<?php
/* --------------------------------------------------------------
xtc_parse_search_string.inc.php 2022-05-02 gm
Gambio GmbH
http://www.gambio.de
Copyright (c) 2022 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
based on:
(c) 2000-2001 The Exchange Project (earlier name of osCommerce)
(c) 2002-2003 osCommerce(general.php,v 1.225 2003/05/29); www.oscommerce.com
(c) 2003 nextcommerce (xtc_parse_search_string.inc.php,v 1.3 2003/08/13); www.nextcommerce.org
(c) 2003 XT-Commerce - community made shopping http://www.xt-commerce.com ($Id: xtc_parse_search_string.inc.php 899 2005-04-29 02:40:57Z hhgag $)
Released under the GNU General Public License
---------------------------------------------------------------------------------------*/
function xtc_parse_search_string($search_str = '', &$objects = [])
{
// only numbers, comma separated
if (is_numeric(str_replace(' ', '', $search_str))) {
$objects = [];
$objects[] = $search_str;
return true;
}
$search_str = trim(strtolower_wrapper($search_str));
// Break up $search_str on whitespace; quoted string will be reconstructed later
$pieces = preg_split('/[[:space:]]+/', $search_str);
$objects = array();
$tmpstring = '';
$flag = '';
for($k = 0; $k < count($pieces); $k++)
{
while(substr_wrapper($pieces[$k], 0, 1) == '(')
{
$objects[] = '(';
if(strlen_wrapper($pieces[$k]) > 1)
{
$pieces[$k] = substr_wrapper($pieces[$k], 1);
}
else
{
$pieces[$k] = '';
}
}
$post_objects = array();
while(substr_wrapper($pieces[$k], -1) == ')')
{
$post_objects[] = ')';
if(strlen_wrapper($pieces[$k]) > 1)
{
$pieces[$k] = substr_wrapper($pieces[$k], 0, -1);
}
else
{
$pieces[$k] = '';
}
}
// Check individual words
if(substr_wrapper($pieces[$k], -1) != '"' && substr_wrapper($pieces[$k], 0, 1) != '"')
{
$objects[] = trim($pieces[$k]);
for($j = 0; $j < count($post_objects); $j++)
{
$objects[] = $post_objects[$j];
}
}
else
{
/* This means that the $piece is either the beginning or the end of a string.
So, we'll slurp up the $pieces and stick them together until we get to the
end of the string or run out of pieces.
*/
// Add this word to the $tmpstring, starting the $tmpstring
$tmpstring = trim(str_replace('"', ' ', $pieces[$k]));
// Check for one possible exception to the rule. That there is a single quoted word.
if(substr_wrapper($pieces[$k], -1) == '"')
{
// Turn the flag off for future iterations
$flag = 'off';
$objects[] = trim($pieces[$k]);
for($j = 0; $j < count($post_objects); $j++)
{
$objects[] = $post_objects[$j];
}
unset($tmpstring);
// Stop looking for the end of the string and move onto the next word.
continue;
}
// Otherwise, turn on the flag to indicate no quotes have been found attached to this word in the string.
$flag = 'on';
// Move on to the next word
$k++;
// Keep reading until the end of the string as long as the $flag is on
while($flag == 'on' && $k < count($pieces))
{
while(substr_wrapper($pieces[$k], -1) == ')')
{
$post_objects[] = ')';
if(strlen_wrapper($pieces[$k]) > 1)
{
$pieces[$k] = substr_wrapper($pieces[$k], 0, -1);
}
else
{
$pieces[$k] = '';
}
}
// If the word doesn't end in double quotes, append it to the $tmpstring.
if(substr_wrapper($pieces[$k], -1) != '"')
{
// Tack this word onto the current string entity
$tmpstring .= ' ' . $pieces[$k];
// Move on to the next word
$k++;
continue;
}
else
{
/* If the $piece ends in double quotes, strip the double quotes, tack the
$piece onto the tail of the string, push the $tmpstring onto the $haves,
kill the $tmpstring, turn the $flag "off", and return.
*/
$tmpstring .= ' ' . trim(str_replace('"', ' ', $pieces[$k]));
// Push the $tmpstring onto the array of stuff to search for
$objects[] = trim($tmpstring);
for($j = 0; $j < count($post_objects); $j++)
{
$objects[] = $post_objects[$j];
}
unset($tmpstring);
// Turn off the flag to exit the loop
$flag = 'off';
}
}
}
}
// add default logical operators if needed
$temp = array();
for($i = 0; $i < (count($objects) - 1); $i++)
{
$temp[] = $objects[$i];
if($objects[$i] != 'and' &&
$objects[$i] != 'or' &&
$objects[$i] != '(' &&
$objects[$i + 1] != 'and' &&
$objects[$i + 1] != 'or' &&
$objects[$i + 1] != ')')
{
$temp[] = ADVANCED_SEARCH_DEFAULT_OPERATOR;
}
}
$temp[] = $objects[$i];
$objects = $temp;
$keyword_count = 0;
$operator_count = 0;
$balance = 0;
for($i = 0; $i < count($objects); $i++)
{
if($objects[$i] == '(')
{
$balance --;
}
if($objects[$i] == ')')
{
$balance ++;
}
if($objects[$i] == 'and' || $objects[$i] == 'or')
{
$operator_count ++;
}
elseif($objects[$i] && $objects[$i] != '(' && $objects[$i] != ')')
{
$keyword_count ++;
}
}
if(($operator_count < $keyword_count) && ($balance == 0))
{
return true;
}
else
{
return false;
}
}