Octopoos / SEBLOD

Build high-end websites with SEBLOD®, a CCK for Joomla!
https://www.seblod.com
GNU General Public License v2.0
129 stars 54 forks source link

Subquery in Search List breaks list ordering #751

Open Giuse69 opened 1 year ago

Giuse69 commented 1 year ago

In plugins/search/cck/cck.php, function _buildQueryOrdering, line 613 there is $str = explode( 'FROM', $str ); to split the part of the query before the FROM and the part after it and this is used later to set the "ORDER BY" through $query->order. The issue is that splitting the query by just using "FROM" can be wrong if there is a subquery, so "FROM" appear more than once. In these cases, the explode truncates the query before the real FROM that can be considered, and then following code is not able to find the appearance of the ordering fields in the query (since it is truncated) and ORDER BY is not set (actually t1.title is used as default). This happens for example when the ordering fields are expressed "AS s_field".

A possibile fix is the following to be added after line 616

$pos = $i = 0; while(($pos = strpos($str, "FROM ", $pos)) !== false) $str = substr_replace($str, "FROM" . $i++ . " ", $pos, 5); // create a new query where all parentheses are removed so that only the main FROM remains (not the ones in the subqueries) $cleanStr = preg_replace('/\((?:[^)(]+|(?R))*+\)/','', $str); // find the main FROM<n> preg_match('/FROM\d+/', $cleanStr, $correctFrom); // extract part of the query before the main FROM from the original $str = substr($str, 0, strpos($str, $correctFrom[0]));

and delete the following two lines from original code

$str = explode( 'FROM', $str ); $str = $str[0];

The final $str might be cleaned so that "FROM" are replaced with "FROM" with a very simple preg_replace, but it's not needed since the following code actually does not read the correctness of the query.