![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/mirasvit/module-search-ultimate/src/SearchSphinx/SphinxQL/ |
<?php /** * Mirasvit * * This source file is subject to the Mirasvit Software License, which is available at https://mirasvit.com/license/. * Do not edit or add to this file if you wish to upgrade the to newer versions in the future. * If you wish to customize this module for your needs. * Please refer to http://www.magentocommerce.com for more information. * * @category Mirasvit * @package mirasvit/module-search-ultimate * @version 2.2.35 * @copyright Copyright (C) 2024 Mirasvit (https://mirasvit.com/) */ namespace Mirasvit\SearchSphinx\SphinxQL; use Mirasvit\SearchSphinx\SphinxQL\Drivers\ConnectionInterface; use Mirasvit\SearchSphinx\SphinxQL\Exception\SphinxQLException; use Mirasvit\SearchSphinx\SphinxQL\Drivers\MultiResultSetInterface; use Mirasvit\SearchSphinx\SphinxQL\Drivers\ResultSetInterface; /** * Query Builder class for SphinxQL statements. * @SuppressWarnings(PHPMD) * @codingStandardsIgnoreFile */ class SphinxQL { /** * A non-static connection for the current SphinxQL object * * @var ConnectionInterface */ protected $connection; /** * The last result object. * * @var array */ protected $last_result; /** * The last compiled query. * * @var string */ protected $last_compiled; /** * The last chosen method (select, insert, replace, update, delete). * * @var string */ protected $type; /** * An SQL query that is not yet executed or "compiled" * * @var string */ protected $query; /** * Array of select elements that will be comma separated. * * @var array */ protected $select = []; /** * From in SphinxQL is the list of indexes that will be used * * @var array */ protected $from = []; /** * The list of where and parenthesis, must be inserted in order * * @var array */ protected $where = []; /** * The list of matches for the MATCH function in SphinxQL * * @var array */ protected $match = []; /** * GROUP BY array to be comma separated * * @var array */ protected $group_by = []; /** * When not null changes 'GROUP BY' to 'GROUP N BY' * * @var null|int */ protected $group_n_by; /** * ORDER BY array * * @var array */ protected $within_group_order_by = []; /** * The list of where and parenthesis, must be inserted in order * * @var array */ protected $having = []; /** * ORDER BY array * * @var array */ protected $order_by = []; /** * When not null it adds an offset * * @var null|int */ protected $offset; /** * When not null it adds a limit * * @var null|int */ protected $limit; /** * Value of INTO query for INSERT or REPLACE * * @var null|string */ protected $into; /** * Array of columns for INSERT or REPLACE * * @var array */ protected $columns = []; /** * Array OF ARRAYS of values for INSERT or REPLACE * * @var array */ protected $values = []; /** * Array arrays containing column and value for SET in UPDATE * * @var array */ protected $set = []; /** * Array of OPTION specific to SphinxQL * * @var array */ protected $options = []; /** * Array of FACETs * * @var Facet[] */ protected $facets = []; /** * The reference to the object that queued itself and created this object * * @var null|SphinxQL */ protected $queue_prev; /** * An array of escaped characters for escapeMatch() * @var array */ protected $escape_full_chars = [ '\\' => '\\\\', '(' => '\(', ')' => '\)', '|' => '\|', '-' => '\-', '!' => '\!', '@' => '\@', '~' => '\~', '"' => '\"', '&' => '\&', '/' => '\/', '^' => '\^', '$' => '\$', '=' => '\=', '<' => '\<', ]; /** * An array of escaped characters for fullEscapeMatch() * @var array */ protected $escape_half_chars = [ '\\' => '\\\\', '(' => '\(', ')' => '\)', '!' => '\!', '@' => '\@', '~' => '\~', '&' => '\&', '/' => '\/', '^' => '\^', '$' => '\$', '=' => '\=', '<' => '\<', ]; /** * @param ConnectionInterface|null $connection */ public function __construct(ConnectionInterface $connection = null) { $this->connection = $connection; } /** * Returns the currently attached connection * * @returns ConnectionInterface * @return ConnectionInterface|null */ public function getConnection() { return $this->connection; } /** * Avoids having the expressions escaped * * Examples: * $query->where('time', '>', SphinxQL::expr('CURRENT_TIMESTAMP')); * // WHERE time > CURRENT_TIMESTAMP * * @param string $string The string to keep unaltered * * @return Expression The new Expression * @todo make non static */ public static function expr($string = '') { return new Expression($string); } /** * Runs the query built * * @return ResultSetInterface The result of the query */ public function execute() { // pass the object so execute compiles it by itself return $this->last_result = $this->getConnection()->query($this->compile()->getCompiled()); } /** * Executes a batch of queued queries * * @return MultiResultSetInterface The array of results * @throws SphinxQLException In case no query is in queue */ public function executeBatch() { if (count($this->getQueue()) == 0) { throw new SphinxQLException('There is no Queue present to execute.'); } $queue = []; foreach ($this->getQueue() as $query) { $queue[] = $query->compile()->getCompiled(); } return $this->last_result = $this->getConnection()->multiQuery($queue); } /** * Enqueues the current object and returns a new one or the supplied one * * @param SphinxQL|null $next * * @return SphinxQL A new SphinxQL object with the current object referenced */ public function enqueue(SphinxQL $next = null) { if ($next === null) { $next = new static($this->getConnection()); } $next->setQueuePrev($this); return $next; } /** * Returns the ordered array of enqueued objects * * @return SphinxQL[] The ordered array of enqueued objects */ public function getQueue() { $queue = []; $curr = $this; do { if ($curr->type != null) { $queue[] = $curr; } } while ($curr = $curr->getQueuePrev()); return array_reverse($queue); } /** * Gets the enqueued object * * @return SphinxQL|null */ public function getQueuePrev() { return $this->queue_prev; } /** * Sets the reference to the enqueued object * * @param SphinxQL $query The object to set as previous * * @return $this */ public function setQueuePrev($query) { $this->queue_prev = $query; return $this; } /** * Returns the result of the last query * * @return array The result of the last query */ public function getResult() { return $this->last_result; } /** * Returns the latest compiled query * * @return string The last compiled query */ public function getCompiled() { return $this->last_compiled; } /** * Begins transaction */ public function transactionBegin() { $this->getConnection()->query('BEGIN'); } /** * Commits transaction */ public function transactionCommit() { $this->getConnection()->query('COMMIT'); } /** * Rollbacks transaction */ public function transactionRollback() { $this->getConnection()->query('ROLLBACK'); } /** * Runs the compile function * * @return $this */ public function compile() { switch ($this->type) { case 'select': $this->compileSelect(); break; case 'insert': case 'replace': $this->compileInsert(); break; case 'update': $this->compileUpdate(); break; case 'delete': $this->compileDelete(); break; case 'query': $this->compileQuery(); break; } return $this; } /** * @return $this */ public function compileQuery() { $this->last_compiled = $this->query; return $this; } /** * Compiles the MATCH part of the queries * Used by: SELECT, DELETE, UPDATE * * @return string The compiled MATCH */ public function compileMatch() { $query = ''; if (!empty($this->match)) { $query .= 'WHERE MATCH('; $matched = []; foreach ($this->match as $match) { $pre = ''; if ($match['column'] instanceof \Closure) { $sub = new MatchQuery($this); call_user_func($match['column'], $sub); $pre .= $sub->compile()->getCompiled(); } elseif ($match['column'] instanceof MatchQuery) { $pre .= $match['column']->compile()->getCompiled(); } elseif (empty($match['column'])) { $pre .= ''; } elseif (is_array($match['column'])) { $pre .= '@(' . implode(',', $match['column']) . ') '; } else { $pre .= '@' . $match['column'] . ' '; } if ($match['half']) { $pre .= $this->halfEscapeMatch($match['value']); } else { $pre .= $this->escapeMatch($match['value']); } if ($pre !== '') { $matched[] = '(' . $pre . ')'; } } $matched = implode(' ', $matched); $query .= $this->getConnection()->escape(trim($matched)) . ') '; } return $query; } /** * Compiles the WHERE part of the queries * It interacts with the MATCH() and of course isn't usable stand-alone * Used by: SELECT, DELETE, UPDATE * * @return string The compiled WHERE */ public function compileWhere() { $query = ''; if (empty($this->match) && !empty($this->where)) { $query .= 'WHERE '; } if (!empty($this->where)) { foreach ($this->where as $key => $where) { if ($key > 0 || !empty($this->match)) { $query .= 'AND '; } $query .= $this->compileFilterCondition($where); } } return $query; } /** * @param array $filter * * @return string */ public function compileFilterCondition($filter) { $query = ''; if (!empty($filter)) { if (strtoupper($filter['operator']) === 'BETWEEN') { $query .= $filter['column']; $query .= ' BETWEEN '; $query .= $this->getConnection()->quote($filter['value'][0]) . ' AND ' . $this->getConnection()->quote($filter['value'][1]) . ' '; } else { // id can't be quoted! if ($filter['column'] === 'id') { $query .= 'id '; } else { $query .= $filter['column'] . ' '; } if (in_array(strtoupper($filter['operator']), ['IN', 'NOT IN'], true)) { $query .= strtoupper($filter['operator']) . ' (' . implode(', ', $this->getConnection()->quoteArr($filter['value'])) . ') '; } else { $query .= $filter['operator'] . ' ' . $this->getConnection()->quote($filter['value']) . ' '; } } } return $query; } /** * Compiles the statements for SELECT * * @return $this */ public function compileSelect() { $query = ''; if ($this->type == 'select') { $query .= 'SELECT '; if (!empty($this->select)) { $query .= implode(', ', $this->select) . ' '; } else { $query .= '* '; } } if (!empty($this->from)) { if ($this->from instanceof \Closure) { $sub = new static($this->getConnection()); call_user_func($this->from, $sub); $query .= 'FROM (' . $sub->compile()->getCompiled() . ') '; } elseif ($this->from instanceof SphinxQL) { $query .= 'FROM (' . $this->from->compile()->getCompiled() . ') '; } else { $query .= 'FROM ' . implode(', ', $this->from) . ' '; } } $query .= $this->compileMatch() . $this->compileWhere(); if (!empty($this->group_by)) { $query .= 'GROUP '; if ($this->group_n_by !== null) { $query .= $this->group_n_by . ' '; } $query .= 'BY ' . implode(', ', $this->group_by) . ' '; } if (!empty($this->within_group_order_by)) { $query .= 'WITHIN GROUP ORDER BY '; $order_arr = []; foreach ($this->within_group_order_by as $order) { $order_sub = $order['column'] . ' '; if ($order['direction'] !== null) { $order_sub .= ((strtolower($order['direction']) === 'desc') ? 'DESC' : 'ASC'); } $order_arr[] = $order_sub; } $query .= implode(', ', $order_arr) . ' '; } if (!empty($this->having)) { $query .= 'HAVING ' . $this->compileFilterCondition($this->having); } if (!empty($this->order_by)) { $query .= 'ORDER BY '; $order_arr = []; foreach ($this->order_by as $order) { $order_sub = $order['column'] . ' '; if ($order['direction'] !== null) { $order_sub .= ((strtolower($order['direction']) === 'desc') ? 'DESC' : 'ASC'); } $order_arr[] = $order_sub; } $query .= implode(', ', $order_arr) . ' '; } if ($this->limit !== null || $this->offset !== null) { if ($this->offset === null) { $this->offset = 0; } if ($this->limit === null) { $this->limit = 9999999999999; } $query .= 'LIMIT ' . ((int)$this->offset) . ', ' . ((int)$this->limit) . ' '; } if (!empty($this->options)) { $options = []; foreach ($this->options as $option) { if ($option['value'] instanceof Expression) { $option['value'] = $option['value']->value(); } elseif (is_array($option['value'])) { array_walk( $option['value'], function (&$val, $key) { $val = $key . '=' . $val; } ); $option['value'] = '(' . implode(', ', $option['value']) . ')'; } else { $option['value'] = $this->getConnection()->quote($option['value']); } $options[] = $option['name'] . ' = ' . $option['value']; } $query .= 'OPTION ' . implode(', ', $options) . ' '; } if (!empty($this->facets)) { $facets = []; foreach ($this->facets as $facet) { // dynamically set the own SphinxQL connection if the Facet doesn't own one if ($facet->getConnection() === null) { $facet->setConnection($this->getConnection()); $facets[] = $facet->getFacet(); // go back to the status quo for reuse $facet->setConnection(); } else { $facets[] = $facet->getFacet(); } } $query .= implode(' ', $facets); } $query = trim($query); $this->last_compiled = $query; return $this; } /** * Compiles the statements for INSERT or REPLACE * * @return $this */ public function compileInsert() { if ($this->type == 'insert') { $query = 'INSERT '; } else { $query = 'REPLACE '; } if ($this->into !== null) { $query .= 'INTO ' . $this->into . ' '; } if (!empty($this->columns)) { $query .= '(' . implode(', ', $this->columns) . ') '; } if (!empty($this->values)) { $query .= 'VALUES '; $query_sub = []; foreach ($this->values as $value) { $query_sub[] = '(' . implode(', ', $this->getConnection()->quoteArr($value)) . ')'; } $query .= implode(', ', $query_sub); } $query = trim($query); $this->last_compiled = $query; return $this; } /** * Compiles the statements for UPDATE * * @return $this */ public function compileUpdate() { $query = 'UPDATE '; if ($this->into !== null) { $query .= $this->into . ' '; } if (!empty($this->set)) { $query .= 'SET '; $query_sub = []; foreach ($this->set as $column => $value) { // MVA support if (is_array($value)) { $query_sub[] = $column . ' = (' . implode(', ', $this->getConnection()->quoteArr($value)) . ')'; } else { $query_sub[] = $column . ' = ' . $this->getConnection()->quote($value); } } $query .= implode(', ', $query_sub) . ' '; } $query .= $this->compileMatch() . $this->compileWhere(); $query = trim($query); $this->last_compiled = $query; return $this; } /** * Compiles the statements for DELETE * * @return $this */ public function compileDelete() { $query = 'DELETE '; if (!empty($this->from)) { $query .= 'FROM ' . $this->from[0] . ' '; } if (!empty($this->where)) { $query .= $this->compileWhere(); } $query = trim($query); $this->last_compiled = $query; return $this; } /** * Sets a query to be executed * * @param string $sql A SphinxQL query to execute * * @return $this */ public function query($sql) { $this->type = 'query'; $this->query = $sql; return $this; } /** * Select the columns * * Gets the arguments passed as $sphinxql->select('one', 'two') * Using it without arguments equals to having '*' as argument * Using it with array maps values as column names * * Examples: * $query->select('title'); * // SELECT title * * $query->select('title', 'author', 'date'); * // SELECT title, author, date * * $query->select(['id', 'title']); * // SELECT id, title * * @param array|string $columns Array or multiple string arguments containing column names * * @return $this */ public function select($columns = null) { $this->reset(); $this->type = 'select'; if (is_array($columns)) { $this->select = $columns; } else { $this->select = \func_get_args(); } return $this; } /** * Alters which arguments to select * * Query is assumed to be in SELECT mode * See select() for usage * * @param array|string $columns Array or multiple string arguments containing column names * * @return $this */ public function setSelect($columns = null) { if (is_array($columns)) { $this->select = $columns; } else { $this->select = \func_get_args(); } return $this; } /** * Get the columns staged to select * * @return array */ public function getSelect() { return $this->select; } /** * Activates the INSERT mode * * @return $this */ public function insert() { $this->reset(); $this->type = 'insert'; return $this; } /** * Activates the REPLACE mode * * @return $this */ public function replace() { $this->reset(); $this->type = 'replace'; return $this; } /** * Activates the UPDATE mode * * @param string $index The index to update into * * @return $this */ public function update($index) { $this->reset(); $this->type = 'update'; $this->into($index); return $this; } /** * Activates the DELETE mode * * @return $this */ public function delete() { $this->reset(); $this->type = 'delete'; return $this; } /** * FROM clause (Sphinx-specific since it works with multiple indexes) * func_get_args()-enabled * * @param array $array An array of indexes to use * * @return $this */ public function from($array = null) { if (is_string($array)) { $this->from = \func_get_args(); } if (is_array($array) || $array instanceof \Closure || $array instanceof SphinxQL) { $this->from = $array; } return $this; } /** * MATCH clause (Sphinx-specific) * * @param mixed $column The column name (can be array, string, Closure, or Match) * @param string $value The value * @param bool $half Exclude ", |, - control characters from being escaped * * @return $this */ public function match($column, $value = null, $half = false) { if ($column === '*' || (is_array($column) && in_array('*', $column))) { $column = []; } $this->match[] = ['column' => $column, 'value' => $value, 'half' => $half]; return $this; } /** * WHERE clause * * Examples: * $query->where('column', 'value'); * // WHERE column = 'value' * * $query->where('column', '=', 'value'); * // WHERE column = 'value' * * $query->where('column', '>=', 'value') * // WHERE column >= 'value' * * $query->where('column', 'IN', array('value1', 'value2', 'value3')); * // WHERE column IN ('value1', 'value2', 'value3') * * $query->where('column', 'BETWEEN', array('value1', 'value2')) * // WHERE column BETWEEN 'value1' AND 'value2' * // WHERE example BETWEEN 10 AND 100 * * @param string $column The column name * @param Expression|string|null|bool|array|int|float $operator The operator to use (if value is not null, you can * use only string) * @param Expression|string|null|bool|array|int|float $value The value to check against * * @return $this */ public function where($column, $operator, $value = null) { if ($value === null) { $value = $operator; $operator = '='; } $this->where[] = [ 'column' => $column, 'operator' => $operator, 'value' => $value, ]; return $this; } /** * GROUP BY clause * Adds to the previously added columns * * @param string $column A column to group by * * @return $this */ public function groupBy($column) { $this->group_by[] = $column; return $this; } /** * GROUP N BY clause (SphinxQL-specific) * Changes 'GROUP BY' into 'GROUP N BY' * * @param int $n Number of items per group * * @return $this */ public function groupNBy($n) { $this->group_n_by = (int)$n; return $this; } /** * WITHIN GROUP ORDER BY clause (SphinxQL-specific) * Adds to the previously added columns * Works just like a classic ORDER BY * * @param string $column The column to group by * @param string $direction The group by direction (asc/desc) * * @return $this */ public function withinGroupOrderBy($column, $direction = null) { $this->within_group_order_by[] = ['column' => $column, 'direction' => $direction]; return $this; } /** * HAVING clause * * Examples: * $sq->having('column', 'value'); * // HAVING column = 'value' * * $sq->having('column', '=', 'value'); * // HAVING column = 'value' * * $sq->having('column', '>=', 'value') * // HAVING column >= 'value' * * $sq->having('column', 'IN', array('value1', 'value2', 'value3')); * // HAVING column IN ('value1', 'value2', 'value3') * * $sq->having('column', 'BETWEEN', array('value1', 'value2')) * // HAVING column BETWEEN 'value1' AND 'value2' * // HAVING example BETWEEN 10 AND 100 * * @param string $column The column name * @param string $operator The operator to use * @param string $value The value to check against * * @return $this */ public function having($column, $operator, $value = null) { if ($value === null) { $value = $operator; $operator = '='; } $this->having = [ 'column' => $column, 'operator' => $operator, 'value' => $value, ]; return $this; } /** * ORDER BY clause * Adds to the previously added columns * * @param string $column The column to order on * @param string $direction The ordering direction (asc/desc) * * @return $this */ public function orderBy($column, $direction = null) { $this->order_by[] = ['column' => $column, 'direction' => $direction]; return $this; } /** * LIMIT clause * Supports also LIMIT offset, limit * * @param int $offset Offset if $limit is specified, else limit * @param null|int $limit The limit to set, null for no limit * * @return $this */ public function limit($offset, $limit = null) { if ($limit === null) { $this->limit = (int)$offset; return $this; } $this->offset($offset); $this->limit = (int)$limit; return $this; } /** * OFFSET clause * * @param int $offset The offset * * @return $this */ public function offset($offset) { $this->offset = (int)$offset; return $this; } /** * OPTION clause (SphinxQL-specific) * Used by: SELECT * * @param string $name Option name * @param Expression|array|string|int|bool|float|null $value Option value * * @return $this */ public function option($name, $value) { $this->options[] = ['name' => $name, 'value' => $value]; return $this; } /** * INTO clause * Used by: INSERT, REPLACE * * @param string $index The index to insert/replace into * * @return $this */ public function into($index) { $this->into = $index; return $this; } /** * Set columns * Used in: INSERT, REPLACE * func_get_args()-enabled * * @param array $array The array of columns * * @return $this */ public function columns($array = []) { if (is_array($array)) { $this->columns = $array; } else { $this->columns = \func_get_args(); } return $this; } /** * Set VALUES * Used in: INSERT, REPLACE * func_get_args()-enabled * * @param array $array The array of values matching the columns from $this->columns() * * @return $this */ public function values($array) { if (is_array($array)) { $this->values[] = $array; } else { $this->values[] = \func_get_args(); } return $this; } /** * Set column and relative value * Used in: INSERT, REPLACE * * @param string $column The column name * @param string $value The value * * @return $this */ public function value($column, $value) { if ($this->type === 'insert' || $this->type === 'replace') { $this->columns[] = $column; $this->values[0][] = $value; } else { $this->set[$column] = $value; } return $this; } /** * Allows passing an array with the key as column and value as value * Used in: INSERT, REPLACE, UPDATE * * @param array $array Array of key-values * * @return $this */ public function set($array) { if ($this->columns === array_keys($array)) { $this->values($array); } else { foreach ($array as $key => $item) { $this->value($key, $item); } } return $this; } /** * Allows passing an array with the key as column and value as value * Used in: INSERT, REPLACE, UPDATE * * @param Facet $facet * * @return $this */ public function facet($facet) { $this->facets[] = $facet; return $this; } /** * Sets the characters used for escapeMatch(). * * @param array $array The array of characters to escape * * @return $this */ public function setFullEscapeChars($array = []) { if (!empty($array)) { $this->escape_full_chars = $this->compileEscapeChars($array); } return $this; } /** * Sets the characters used for halfEscapeMatch(). * * @param array $array The array of characters to escape * * @return $this */ public function setHalfEscapeChars($array = []) { if (!empty($array)) { $this->escape_half_chars = $this->compileEscapeChars($array); } return $this; } /** * Compiles an array containing the characters and escaped characters into a key/value configuration. * * @param array $array The array of characters to escape * * @return array An array of the characters and it's escaped counterpart */ public function compileEscapeChars($array = []) { $result = []; foreach ($array as $character) { $result[$character] = '\\' . $character; } return $result; } /** * Escapes the query for the MATCH() function * * @param string $string The string to escape for the MATCH * * @return string The escaped string */ public function escapeMatch($string) { if ($string instanceof Expression) { return $string->value(); } return mb_strtolower(str_replace(array_keys($this->escape_full_chars), array_values($this->escape_full_chars), $string), 'utf8'); } /** * Escapes the query for the MATCH() function * Allows some of the control characters to pass through for use with a search field: -, |, " * It also does some tricks to wrap/unwrap within " the string and prevents errors * * @param string $string The string to escape for the MATCH * * @return string The escaped string */ public function halfEscapeMatch($string) { if ($string instanceof Expression) { return $string->value(); } $string = str_replace(array_keys($this->escape_half_chars), array_values($this->escape_half_chars), $string); // this manages to lower the error rate by a lot if (mb_substr_count($string, '"', 'utf8') % 2 !== 0) { $string .= '"'; } $string = preg_replace('/-[\s-]*-/u', '-', $string); $from_to_preg = [ '/([-|])\s*$/u' => '\\\\\1', '/\|[\s|]*\|/u' => '|', '/(\S+)-(\S+)/u' => '\1\-\2', '/(\S+)\s+-\s+(\S+)/u' => '\1 \- \2', ]; $string = mb_strtolower(preg_replace(array_keys($from_to_preg), array_values($from_to_preg), $string), 'utf8'); return $string; } /** * Clears the existing query build for new query when using the same SphinxQL instance. * * @return $this */ public function reset() { $this->query = null; $this->select = []; $this->from = []; $this->where = []; $this->match = []; $this->group_by = []; $this->group_n_by = null; $this->within_group_order_by = []; $this->having = []; $this->order_by = []; $this->offset = null; $this->limit = null; $this->into = null; $this->columns = []; $this->values = []; $this->set = []; $this->options = []; return $this; } /** * @return $this */ public function resetWhere() { $this->where = []; return $this; } /** * @return $this */ public function resetMatch() { $this->match = []; return $this; } /** * @return $this */ public function resetGroupBy() { $this->group_by = []; $this->group_n_by = null; return $this; } /** * @return $this */ public function resetWithinGroupOrderBy() { $this->within_group_order_by = []; return $this; } /** * @return $this */ public function resetFacets() { $this->facets = []; return $this; } /** * @return $this */ public function resetHaving() { $this->having = []; return $this; } /** * @return $this */ public function resetOrderBy() { $this->order_by = []; return $this; } /** * @return $this */ public function resetOptions() { $this->options = []; return $this; } }