Forum

Thread tagged as: Runway

Runway: partial numeric slug matches multiple items when using 'match'=>'eq'

I have several list/detail pages which pull from collections by matching the item slug, like this:

  $result = perch_collection('Product: '.$cat_title, [
    'template' =>'product/_detail_incl/_detail_'.$lang.'.html',
    'filter'=>'slug',
    'match'=>'eq',
    'value'=>perch_get('slug'),
    'skip-template' => true,
    'return-html' => true,
  ]);

I get the slug using a route. For example, the route for one page is [lang]/products/axles/[slug:slug]

I have two collection items with these slugs:

  • 4000-series-rigid
  • 4000-series-rigid-tandem

When I visit /en/products/axles/4000-series-rigid I correctly get the first item, and /en/products/axles/4000-series-rigid-tandem correctly shows the second item.

However, I just noticed that if I visit the URL /en/products/axles/4000, BOTH collection items are matched and shown. There is no collection item with a "4000" slug. The strange thing is that these URLs correctly match nothing:

  • /en/products/axles/400
  • /en/products/axles/4000-
  • /en/products/axles/4000-series

...etc. So it seems that for some reason, only giving the first, complete numeric part of the slug can somehow match multiple collection items. Might be a bug?

Diagnostics:

HEALTH CHECK

Perch Runway is up to date
PHP 5.6.14-1+deb.sury.org~trusty+1 is up to date
MySQL 5.5.46-0ubuntu0.14.04.2 is up to date
Image processing available
SUMMARY INFORMATION

Perch Runway: 2.8.31, PHP: 5.6.14-1+deb.sury.org~trusty+1, MySQL: mysqlnd 5.0.11-dev - 20120503 - $Id: 3c688b6bbc30d36af3ac34fdd4b7b5b787fe5555 $, with PDO
Server OS: Linux, apache2handler
Installed apps: content (2.8.31), assets (2.8.31), categories (2.8.31), perch_blog (5.0), perch_events (1.9.3), perch_forms (1.8.3)
App runtimes: <?php $apps_list = array( 'content', 'categories', 'perch_blog', 'perch_events', 'perch_forms', );
PERCH_LOGINPATH: /at-admin
PERCH_PATH: /var/www/public/axletech.dev/at-admin
PERCH_CORE: /var/www/public/axletech.dev/at-admin/core
PERCH_RESFILEPATH: /var/www/public/axletech.dev/at-admin/resources
Image manipulation: GD Imagick
PHP limits: Max upload 100M, Max POST 100M, Memory: 128M, Total max file upload: 100M
F1: 2edba60ed1f613d6dd804feb202456a2
Resource folder writeable: Yes
HTTP_HOST: axletech.dev
DOCUMENT_ROOT: /var/www/public/axletech.dev
REQUEST_URI: /at-admin/core/settings/diagnostics/
SCRIPT_NAME: /at-admin/core/settings/diagnostics/index.php
Shane Lenzen

Shane Lenzen 18 points

  • 5 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

Can you turn on debug and show me the output?

Holy design change! I like the full width. Anyway, here's the debug:

Debug Message
[54] SELECT p.pagePath, pr.routePattern, pr.routeRegExp, p.pageTemplate FROM perch2_pages p LEFT JOIN perch2_page_routes pr ON p.pageID=pr.pageID ORDER BY pr.routeOrder ASC, p.pagePath ASC
Matched route: [lang]/products/axles/[slug:slug]
Using master page: /templates/pages/products.php
Page arguments:
Array
(
    [0] => /en/products/axles/4000
    [1] => en
    [slug] => 4000
    [2] => 4000
)
[1] SELECT * FROM perch2_pages WHERE pagePath='/products/axles' LIMIT 1
Using template: /templates/pages/attributes/_title-nav-text.html
[0] SELECT setID FROM perch2_category_sets WHERE setSlug='' LIMIT 1
[1] SELECT main.* FROM perch2_categories main WHERE 1=1 AND (catPath='products/axles/') ORDER BY catTreePosition ASC
[1] Using template: /templates/categories/_cat_title.html
[1] SELECT collectionID, collectionTemplate FROM perch2_collections WHERE collectionKey='Product: Axles'
[2] SELECT * FROM ( SELECT idx.itemID, ci.collectionID, ci.itemJSON, idx2.indexValue as sortval FROM perch2_collection_index idx JOIN perch2_collection_items ci ON idx.itemID=ci.itemID AND idx.itemRev=ci.itemRev AND idx.collectionID=ci.collectionID JOIN perch2_collection_revisions cr ON idx.itemID=cr.itemID AND idx.itemRev=cr.itemRev AND idx.collectionID=ci.collectionID JOIN perch2_collection_index idx2 ON idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev AND idx2.indexKey='_order' WHERE (idx.collectionID=4) AND ((idx.indexKey='slug' AND idx.indexValue=4000)) AND idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev ) as tbl GROUP BY itemID, itemJSON, sortval ORDER BY sortval ASC
[4] Using template: /templates/content/product/_detail_incl/_detail_en.html
[2] SELECT * FROM ( SELECT idx.itemID, ci.collectionID, ci.itemJSON, idx2.indexValue as sortval FROM perch2_collection_index idx JOIN perch2_collection_items ci ON idx.itemID=ci.itemID AND idx.itemRev=ci.itemRev AND idx.collectionID=ci.collectionID JOIN perch2_collection_revisions cr ON idx.itemID=cr.itemID AND idx.itemRev=cr.itemRev AND idx.collectionID=ci.collectionID JOIN perch2_collection_index idx2 ON idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev AND idx2.indexKey='_order' WHERE (idx.collectionID=4) AND ((idx.indexKey='slug' AND idx.indexValue=4000)) AND idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev ) as tbl GROUP BY itemID, itemJSON, sortval ORDER BY sortval ASC
[2] Using template: /templates/content/product/_title/_title_en.html
Using template: /templates/pages/attributes/default.html
[1] SELECT pageTreePosition FROM perch2_pages WHERE pagePath='/products/axles' OR pageSortPath='/products/axles' LIMIT 1
[2] SELECT * FROM perch2_pages WHERE pageHidden=0 AND pageNew=0 AND pageTreePosition IN ('000-003-001', '000-003', '000') ORDER BY pageTreePosition
[2] Using template: /templates/navigation/breadcrumbs.html
[1] SELECT regionID, regionTemplate, regionPage, regionRev AS rev FROM perch2_content_regions WHERE regionKey='Footer Links' AND (regionPage='/products/axles' OR regionPage='*')
[2] SELECT * FROM ( SELECT idx.itemID, c.regionID, idx.pageID, c.itemJSON, idx2.indexValue as sortval FROM perch2_content_index idx JOIN perch2_content_items c ON idx.itemID=c.itemID AND idx.itemRev=c.itemRev AND idx.regionID=c.regionID JOIN perch2_content_index idx2 ON idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev AND idx2.indexKey='_order' WHERE ((idx.regionID=15 AND idx.itemRev=9)) AND idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev ) as tbl GROUP BY itemID, pageID, itemJSON, sortval ORDER BY sortval ASC
[2] Using template: /templates/content/shared/footer_links.html
[1] SELECT regionID, regionTemplate, regionPage, regionRev AS rev FROM perch2_content_regions WHERE regionKey='Social' AND (regionPage='/products/axles' OR regionPage='*')
[1] SELECT * FROM ( SELECT idx.itemID, c.regionID, idx.pageID, c.itemJSON, idx2.indexValue as sortval FROM perch2_content_index idx JOIN perch2_content_items c ON idx.itemID=c.itemID AND idx.itemRev=c.itemRev AND idx.regionID=c.regionID JOIN perch2_content_index idx2 ON idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev AND idx2.indexKey='_order' WHERE ((idx.regionID=16 AND idx.itemRev=2)) AND idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev ) as tbl GROUP BY itemID, pageID, itemJSON, sortval ORDER BY sortval ASC
[1] Using template: /templates/content/shared/social.html
[41] SELECT * FROM perch2_pages WHERE pageNew=0 AND pageHidden=0 ORDER BY pageTreePosition ASC
[1] SELECT pageTreePosition FROM perch2_pages WHERE pagePath='/products/axles' LIMIT 1
[2] SELECT pageID FROM perch2_pages WHERE pageTreePosition IN ('000-003-001', '000-003', '000') ORDER BY pageTreePosition DESC
[6] Using template: /templates/navigation/item.html
Drew McLellan

Drew McLellan 2638 points
Perch Support

The 4000 is being treated numerically. When we then make the comparison of the number against the slug strings, type coercion truncates the value at the first non-numerical character. Hence the match.

Is there something I should do differently to prevent the match for the partial slug?

Drew McLellan

Drew McLellan 2638 points
Perch Support

I think if you pass in a purely numerical slug, this will always happen. You can set count to 1 to limit the impact.

Is it causing a problem, or is this only theoretical?

To make sure Google doesn't index pages that don't exist, I like to send a 404 header if the given slug doesn't match an item. That's the only problem I can imagine really, other than people just trying random slugs trying to break things (like I did). Not a big deal. Thanks for the help!