protected function searchPrepare($query, $auto_title = true) { $query = urldecode($query); $i = $offset = 0; $query_parts = array(); while (($j = strpos($query, '&', $offset)) !== false) { // escaped & if ($query[$j - 1] != '\\') { $query_parts[] = str_replace('\\&', '&', substr($query, $i, $j - $i)); $i = $j + 1; } $offset = $j + 1; } $query_parts[] = str_replace('\\&', '&', substr($query, $i)); $model = $this->getModel(); $title = array(); foreach ($query_parts as $part) { if (!($part = trim($part))) { continue; } $parts = preg_split("/(\\\$=|\\^=|\\*=|==|!=|>=|<=|=|>|<)/uis", $part, 2, PREG_SPLIT_DELIM_CAPTURE); if ($parts) { if ($parts[0] == 'category_id') { if ($parts[1] == '==' && $parts[2] == 'null') { $this->where[] = 'p.category_id IS NULL'; $title[] = 'without category'; } else { $this->addJoin('shop_category_products', null, ':table.category_id' . $this->getExpression($parts[1], $parts[2])); $title[] = "category_id " . $parts[1] . $parts[2]; } } elseif ($parts[0] == 'query') { $search = new shopIndexSearch(); $word_ids = $search->getWordIds($parts[2], true); if ($word_ids) { $this->joins[] = array('table' => 'shop_search_index', 'alias' => 'si'); $this->where[] = 'si.word_id IN (' . implode(",", $word_ids) . ')'; if (count($word_ids) > 1) { $this->fields[] = "SUM(si.weight) AS weight"; $this->order_by = 'weight DESC'; $this->group_by = 'p.id'; } else { $this->fields[] = "si.weight"; $this->order_by = 'si.weight DESC'; } } elseif ($parts[2]) { $this->where[] = '0'; } $this->prepared = true; // if not found try find by name if (!$this->count()) { $this->count = null; $this->joins = $this->where = $this->having = $this->fields = array(); if ($this->is_frontend) { if ($this->filtered) { $this->filtered = false; } $this->frontendConditions(); } $this->order_by = 'p.create_datetime DESC'; $this->group_by = null; $q = $model->escape($parts[2], 'like'); $this->addJoin('shop_product_skus', null, "(p.name LIKE '%" . $q . "%' OR :table.name LIKE '%" . $q . "%' OR :table.sku LIKE '%" . $q . "%')"); $this->group_by = 'p.id'; return; } elseif ($word_ids) { $result = $this->getProducts('*', 0, 1); $p = array_shift($result); $w = str_replace(',', '.', 0.3 * $p['weight']); if (count($word_ids) > 1) { $this->having[] = 'SUM(si.weight) >= ' . $w; } else { $this->where[] = 'weight >= ' . $w; } $this->count = null; } $title[] = $parts[0] . $parts[1] . $parts[2]; } elseif ($parts[0] == 'tag') { $tag_model = $this->getModel('tag'); if (strpos($parts[2], '||') !== false) { $tags = explode('||', $parts[2]); $tag_ids = $tag_model->getIds($tags); } else { $sql = "SELECT id FROM " . $tag_model->getTableName() . " WHERE name" . $this->getExpression($parts[1], $parts[2]); $tag_ids = $tag_model->query($sql)->fetchAll(null, true); } if ($tag_ids) { $this->addJoin('shop_product_tags', null, ":table.tag_id IN ('" . implode("', '", $tag_ids) . "')"); } else { $this->where[] = "0"; } } elseif ($model->fieldExists($parts[0])) { $title[] = $parts[0] . $parts[1] . $parts[2]; $this->where[] = 'p.' . $parts[0] . $this->getExpression($parts[1], $parts[2]); } elseif ($parts[1] == '=') { $code = $parts[0]; $is_value_id = false; if (substr($code, -9) == '.value_id') { $code = substr($code, 0, -9); $is_value_id = true; } $feature_model = $this->getModel('feature'); $f = $feature_model->getByCode($code); if ($f) { if ($is_value_id) { $value_id = $parts[2]; } else { $values_model = $feature_model->getValuesModel($f['type']); $value_id = $values_model->getValueId($f['id'], $parts[2]); } $this->addJoin('shop_product_features', null, ':table.feature_id = ' . $f['id'] . ' AND :table.feature_value_id = ' . (int) $value_id); $this->group_by = 'p.id'; } } } } if ($title) { $title = implode(', ', $title); // Strip slashes from search title. $bs = '\\\\'; $title = preg_replace("~{$bs}(_|%|&|{$bs})~", '\\1', $title); } if ($auto_title) { $this->addTitle($title, ' '); } }