/** * {@inheritDoc} */ public function scope(Query $query, TokenInterface $token) { $column = $this->config('field'); $value = $token->value(); if (!$column || empty($value)) { return $query; } $tableAlias = $this->_table->alias(); $range = $this->_parseRange($token->value()); if ($range['lower'] !== $range['upper']) { $conjunction = $token->negated() ? 'AND NOT' : 'AND'; $conditions = ["{$conjunction}" => ["{$tableAlias}.{$column} >=" => $range['lower'], "{$tableAlias}.{$column} <=" => $range['upper']]]; } else { $cmp = $token->negated() ? '<=' : '>='; $conditions = ["{$tableAlias}.{$column} {$cmp}" => $range['lower']]; } if ($token->where() === 'or') { $query->orWhere($conditions); } elseif ($token->where() === 'and') { $query->andWhere($conditions); } else { $query->where($conditions); } return $query; }
/** * {@inheritDoc} */ public function scope(Query $query, TokenInterface $token) { if ($token->negated()) { return $query; } $value = intval($token->value()); if ($value > 0) { $query->limit($value); } return $query; }
/** * {@inheritDoc} */ public function scope(Query $query, TokenInterface $token) { $value = $token->value(); if (empty($value)) { return $query; } return $query->matching('Tags', function ($q) use($value) { $value = explode(',', $value); $names = array_map('trim', (array) $value); return $q->where(['Tags.name IN' => empty($names) ? ['---'] : $names]); }); }
/** * {@inheritDoc} */ public function scope(Query $query, TokenInterface $token) { $fields = $this->config('fields'); if ($token->negated() || empty($fields)) { return $query; } $tableAlias = $this->_table->alias(); $fields = $this->config('fields'); $value = strtolower($token->value()); if (is_string($fields)) { $fields = [$fields]; } foreach (explode(';', $value) as $segment) { $parts = explode(',', $segment); if (in_array($parts[0], $fields)) { $dir = empty($parts[1]) || !in_array($parts[1], ['asc', 'desc']) ? 'asc' : $parts[1]; $query->order(["{$tableAlias}.{$parts[0]}" => $dir]); } } return $query; }
/** * Calculates the conjunction to use and the value to use with such conjunction * based on the given token. * * @param \Search\Parser\TokenInterface $token Token for which calculating the * conjunction * @return array Numeric index array, where the first key (0) is the * conjunction, and the second (1) is the value. */ protected function _prepareConjunction(TokenInterface $token) { $value = $token->value(); $conjunction = strtolower($this->config('conjunction')); if ($conjunction == 'auto') { $conjunction = strpos($value, ',') !== false ? 'in' : 'like'; } if ($conjunction == 'in') { $value = array_slice(explode(',', $value), 0, $this->config('inSlice')); $conjunction = $token->negated() ? 'NOT IN' : 'IN'; } elseif ($conjunction == 'like') { $value = str_replace(['*', '!'], ['%', '_'], $value); $conjunction = $token->negated() ? 'NOT LIKE' : 'LIKE'; } elseif ($conjunction == '=') { $conjunction = $token->negated() ? '<>' : ''; } elseif ($conjunction == '<>') { $conjunction = $token->negated() ? '' : '<>'; } return [$conjunction, $value]; }
/** * Handles "term" search operator. * * term:term1-slug,term2-slug,... * * @param \Cake\ORM\Query $query The query object * @param \Search\Parser\TokenInterface $token Operator token * @return \Cake\ORM\Query */ public function operatorterm(Query $query, TokenInterface $token) { $terms = explode(',', strtolower($token->value())); $conjunction = $token->negated() ? 'NOT IN' : 'IN'; if (empty($terms)) { return $query; } $conditions = ["Contents.id {$conjunction}" => TableRegistry::get('Taxonomy.EntitiesTerms')->find()->select(['EntitiesTerms.entity_id'])->where(['EntitiesTerms.table_alias' => $this->alias()])->matching('Terms', function ($q) use($terms) { return $q->where(['Terms.slug IN' => $terms]); })]; if (!empty($conditions)) { if ($token->where() === 'or') { $query->orWhere($conditions); } elseif ($token->where() === 'and') { $query->andWhere($conditions); } else { $query->where($conditions); } } return $query; }
/** * Similar to "_scopeWords" but using MySQL's fulltext indexes. * * @param \Cake\ORM\Query $query The query to scope * @param \Search\TokenInterface $token Token describing a words sequence. e.g `this is a phrase` * @return \Cake\ORM\Query Scoped query */ protected function _scopeWordsInFulltext(Query $query, TokenInterface $token) { $value = str_replace(['*', '!'], ['*', '*'], $token->value()); $value = mb_strpos($value, '+') === 0 ? mb_substr($value, 1) : $value; if (empty($value) || in_array($value, $this->_stopWords())) { return $query; } $not = $token->negated() ? 'NOT' : ''; $value = str_replace("'", '"', $value); $conditions = ["{$not} MATCH(SearchDatasets.words) AGAINST('{$value}' IN BOOLEAN MODE) > 0"]; if ($token->where() === 'or') { $query->orWhere($conditions); } elseif ($token->where() === 'and') { $query->andWhere($conditions); } else { $query->where($conditions); } return $query; }