Jump to content

Sorting products on category page does not work


romank

Recommended Posts

Hi,

I have noticed today that I cant sort the products using the select on the category page, as I am getting this error:

Security Warning: Illegal array key "sort[price]" was detected and was removed. in /home/xxx/public_html/classes/sanitize.class.php on line 88

I have done loads of custom changes to my cubecart installation, but I am not aware of touching this part at all - shouldnt the sort array be somehow exempted or something?

Link to comment
Share on other sites

Hi keat,

when I go to any category page on the front end and try to change the order of the products (by price, by name, ..) it still stays default and I get the message above.

I have downloaded the latest CC 5 and compared the sanitize.class.php files, apart from some new items in the $exempt array, there is absolutely no difference.

The sort[price] variable is simply getting sanitized and removed, even though its valid.

Link to comment
Share on other sites

I enabled debugging on mine and performed the sort thing, and can't see any red errors in the debug log.

There are references to stuff being chached, so I guess it wouldn't hurt to clear the cache.

Next I'd suggest maybe posting a dozen lines either side of the debug error on here, someone will know the answer i'm sure.

Link to comment
Share on other sites

Looking at CC5210 (because that version has the appropriate statement on line 88, not that this should make a difference), the Sanitize->_clean() function will take an array of data to process. This function is called by Sanitize->cleanGlobals(), and sends, in turn, $_GET, $_POST, $_COOKIE, and $_REQUEST. The $_REQUEST global supposedly has copies of $_GET and $_POST.

The Sorters in the View Category page sends data using the POST method. So, what gets delivered to PHP is:

$_POST['sort']="price|DESC"

The _clean() function works through $_POST using each key => value: that is, for example, 'sort' => "price|DESC". However, that is not what the error message says the data looks like. The error says the key is sort[price].

We need to have a look at the skin template content.category.php. Briefly, the code should look like:

<form action="{$VAL_SELF}" method="post">
	<select name="sort" class="auto_submit">
	  <option value="">{$LANG.form.please_select}</option>
	  {foreach from=$SORTING item=sort}
	  <option value="{$sort.field}|{$sort.order}" {$sort.selected}>{$sort.name} ({$sort.direction})</option>
	  {/foreach}
	</select>
	<input type="submit" value="{$LANG.form.sort}" />
</form>

Note the <option value> being a combination of $sort.field (price, stock, name, etc) and a sort order (ASC, DESC) separated by a vertical bar (aka 'pipe').

Please let us know what skin you are using. I think there is malformed code in the template.

Link to comment
Share on other sites

Hi bsmither,

was hoping you would come to help!

I have figured out the process where it makes the pipe separated value into an array key and value, just like you explained, but couldnt figure out why is it failing the preg in the _clean() method anyway.

 

This is my template file:

	<div class="select_list align_right margintop30">
	<form action="{$VAL_SELF}" method="post">
          <select name="sort" class="listSelect auto_submit dropDown textbox">
            <option value="">{$LANG.form.please_select}</option>
			{foreach from=$SORTING item=sort}
			<option value="{$sort.field}|{$sort.order}" {$sort.selected}>{$sort.name} ({$sort.direction})</option>
			{/foreach}
          </select>
	</form>
    </div>			

 

This is the piece of code from the Cubecart::_category() method which splits the pipe and makes it an array:

<?php
		$query = array();
		if (isset($_POST['sort'])) {
			list($field, $order) = explode('|', $_POST['sort']);
			$query['sort'][$field] = $order;
			if (isset($_GET['search'])) {
				foreach ($_GET['search'] as $key => $value) {
					$query['search'][$key] = $value;
				}
			}
		}
?>

 

I have noticed more things in the error log:

[11-Mar-2016 16:19:51 UTC] PHP Warning:  Security Warning: Illegal array key "$" was detected and was removed. in /home/xxx/public_html/classes/sanitize.class.php on line 89

[11-Mar-2016 16:20:07 UTC] PHP Warning:  Security Warning: Illegal array key "search[keywords]" was detected and was removed. in /home/xxx/public_html/classes/sanitize.class.php on line 89

 

I downloaded the latest CC 5 and looked into the files (sanitize class, cubecart class, category template) but the code really seems identical. I simply dont understand what has happened that makes legit variables like sort and search fail the sanitize process.

Link to comment
Share on other sites

At the bottom of your (custom?) template file content.category.php, add this:

{debug}

Make sure your browser allows for popups. Because a template was edited, you may need to have CubeCart clear the cache.

When you ask for a Category page, the browser will pop up a Smarty diagnostic window. Scan through the left column looking for $SORTING. Examine closely the values for 'field' and 'order' in the various elements of that array.

Link to comment
Share on other sites

I dont have cache enabled, but I have cleared it anyway, to no avail.

This is the html of the sort select:

<form action="xxx" method="post">
	<select name="sort" class="listSelect auto_submit dropDown textbox">
		<option value="">-- Please Select --</option>
		<option value="name|DESC" >Name (Z-A)</option>
		<option value="name|ASC" >Name (A-Z)</option>
		<option value="date_added|DESC" >Date Added (Newest First)</option>
		<option value="date_added|ASC" >Date Added (Oldest First)</option>
		<option value="price|DESC" >Price (High-Low)</option>
		<option value="price|ASC" >Price (Low-High)</option>
	</select>
</form>

and this is the $SORTING variable from the smarty debug window:

Smarty_Variable Object (3)
->value = Array (6)
  0 => Array (5)
    name => "Name"
    field => "name"
    order => "DESC"
    direction => "Z-A"
    selected => ""
  1 => Array (5)
    name => "Name"
    field => "name"
    order => "ASC"
    direction => "A-Z"
    selected => ""
  2 => Array (5)
    name => "Date Added"
    field => "date_added"
    order => "DESC"
    direction => "Newest First"
    selected => ""
  3 => Array (5)
    name => "Date Added"
    field => "date_added"
    order => "ASC"
    direction => "Oldest First"
    selected => ""
  4 => Array (5)
    name => "Price"
    field => "price"
    order => "DESC"
    direction => "High-Low"
    selected => ""
  5 => Array (5)
    name => "Price"
    field => "price"
    order => "ASC"
    direction => "Low-High"
    selected => ""
->nocache = false
->scope = "file:templates/content.category.php"

When I enable CC debug, there are no errors/warnings apart from the one mentioned above:

 Security Warning: Illegal array key "sort[price]" was detected and was removed.

I am very close to adjusting the regular expression so the sort[price] would pass, because I am running out of ideas and everything seem to be in order apart from the damn sanitize issue :(

Link to comment
Share on other sites

To learn which GLOBAL has the faulting key, we can make these edits:

In the Sanitize class, near line 50, find:

		self::_clean($_GET);
		self::_clean($_POST);
		self::_clean($_COOKIE);
		self::_clean($_REQUEST);

Change to:

		self::_clean($_GET,'GET');
		self::_clean($_POST,'POST');
		self::_clean($_COOKIE,'COOKIE');
		self::_clean($_REQUEST,'REQUEST');


Near line 80, find:

private static function _clean(&$data) {

Change to:

private static function _clean(&$data, $global = "UNK") {


Near line 88, find:

trigger_error('Security Warning: Illegal array key "'.htmlentities($key).'" was detected and was removed.', E_USER_WARNING);

Change to:

trigger_error('Security Warning: The key in '.$global.'['.htmlentities($key).'] is illegal and was removed.', E_USER_WARNING);

 

Link to comment
Share on other sites

This is bringing some strange stuff - I did what you asked and I also print out the entire $data from the _clean() method.

After ONE click on the website, I get two records in the error log:

[11-Mar-2016 22:16:18 UTC] PHP Warning:  Security Warning: Illegal array key GET "sort[price]" was detected and was removed. 
Entire array: Array
(
    [seo_path] => xxx
    [_a] => category
    [sort[price]] => ASC
)
URL: /xxx.html?_a=category&sort[price]=ASC
in /home/tradeloc/public_html/classes/sanitize.class.php on line 89
 
 
[11-Mar-2016 22:16:18 UTC] PHP Warning:  Security Warning: Illegal array key REQUEST "sort[price]" was detected and was removed. 
Entire array: Array
(
    [seo_path] => xxx
    [_a] => category
    [sort] => Array
        (
            [price] => ASC
        )

    [__utma] => 131230282.703056860.1409656154.1457728420.1457732214.320
    [__utmz] => 131230282.1452426433.205.5.utmcsr=3.basecamp.com|utmccn=(referral)|utmcmd=referral|utmcct=/
    [member_id] => 0
    [pass_hash] => 0
    [ipsconnect_e230f3ddfa042ff09c509581fffca84a] => 0
    [_ga] => GA1.3.830321126.1432714418
    [whoson] => 862-1453479549677
    [__atuvc] => 0|6,10|7,0|8,0|9,4|10
    [__utmc] => 131230282
    [__utmb] => 131230282.13.10.1457732214
    [PHPSESSID] => df805f0c08297498cf65f529bccc7a75
    [__utmt] => 1
    [sort[price]] => ASC
)
URL: /xxx.html?_a=category&sort[price]=ASC
in /home/tradeloc/public_html/classes/sanitize.class.php on line 89

So it seems there is a redirect or something? Is this standard behavior?

Link to comment
Share on other sites

What exact version of CC5 are you using?

Yes, there is a redirect. This keeps the chosen sort passed from page to page as the customer continues to choose search keywords.

This happens in Cubecart->_category() near line 737 (line numbers relative to CC5210):
$query['sort'][$field] = $order;

Later, near line 784, CubeCart httpredir (bounces) with having put $query in the querystring. This allows for continuing the sort while continuing searching.

 

Link to comment
Share on other sites

One error is for GET and the second is for REQUEST. It is the same page request.

But note that it is for GET and not POST. So this error is after CubeCart has moved the sort from POST to the querystring and the bounce has happened. Thus, there is nothing wrong with the HTML code in the sorter <select> form.

The URL shows this: ?_a=category&sort[price]=ASC

So now, the question is why is PHP not accepting sort as an array. Unless something is not "url encoding" the brackets (changing [ to %5B, for example).

I will look through my codebase starting at CC521 and see if I made any notes.

 

Link to comment
Share on other sites

Desperate update from me.

When I var_dump my $_GET somewhere in the catalogue.class.php just before the sorting goes to effect, I actually see this:

["sort[price]"]=> string(3) "ASC"

When I dump my $_REQUEST, I see this:

["sort"]=> array(1) { ["price"]=> string(3) "ASC" }

So clearly somewhere around the way, stuff goes very wrong and turns an array and a value into a string!!!

Even when I bypass cleanGlobals(), the result is still the same.

It is absolutely beyond me where and why and how this is happening and in top of it - how come the $_REQUEST array is kept intact.

(Here, shamelessly presenting my disgusting temporary fix:)

        if (isset($_REQUEST['sort'])) {
            $_GET['sort'] = $_REQUEST['sort'];
        }
        if (isset($_REQUEST['search'])) {
            $_GET['search'] = $_REQUEST['search'];
        }

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...