_params; } /** * Remove a Solr param. * * @param string $key * Param name to remove * @param string $value * (optional) Solr param value to be removed. If null given, remove all * params matching $key. */ public function removeParam($key, $value = NULL) { if (! $value) { unset($this->_param[$key]); } else { if (is_array($this->_params[$key])) { foreach ($this->_params[$key] as $_key => $_value) { if ($_value == $value) { unset($this->_params[$_key]); } } } else if($this->_params[$key] == $value) { unset($this->_param[$key]); } } } /** * Add a Solr param to our query * * @param string $key * Solr param name * @param array|string $value * Solr param value, likely more a string any other type. If an array is * given, this will add a set of values for the given param name. */ public function addParam($key, $value) { if (isset($this->_params[$key])) { if (is_array($value)) { // array_values() will ensure we have numeric keys and ensure the // array_merge() expected behavior. if (is_array($this->_params[$key])) { $this->_params = array_merge($this->_params[$key], array_values($value)); } else { $this->_params = array_merge(array($this->_params[$key]), array_values($value)); } } else { if (is_array($this->_params[$key])) { $this->_params[$key][] = $value; } else { $this->_params[$key] = array($this->_params[$key], $value); } } } else { // Whatever is a single value or an array, this will do the right thing. $this->_params[$key] = $value; } } /** * Merge params array with existing one. * * @param array $params = array() * New params to add * @param boolean $override = FALSE * If set to TRUE, incomming params key will override existing ones */ public function addParams($params = array(), $override = FALSE) { foreach ($params as $key => &$value) { if ($override) { $this->removeParam($key); } $this->addParam($key, $value); } } /** * Construct the object * * @param array $params = array() * Apache Solr module formated array of params */ public function __construct($params = array()) { $this->_params = $params; } } /** * Abstract implementation of complex query tree. */ abstract class AbstractAssistantSolrQueryString { /** * Sub queries storage. * * @var array */ protected $_subQueries = array(); /** * Default operator. Can be 'AND' or 'OR'. * * @var string */ protected $_operator = 'OR'; /** * Set default operator. * * @param string $operator * Can be 'AND' or 'OR'. */ public function setOperator($operator) { if ($operator == 'AND' || $operator == 'OR') { $this->_operator = $operator; } } /** * Add subquery to query * * @param AbstractAssistantSolrQueryString $subQuery * AbstractAssistantSolrQueryString instance */ public function addSubQuery(AbstractAssistantSolrQueryString $query) { $this->_subQueries[] = $query; } /** * Build RAW output (speciliazed method). * * @return string */ protected abstract function _renderRawOutput(); /** * Build RAW query string * * @return string */ public final function __toString() { $output = trim($this->_renderRawOutput()); if (! empty($this->_subQueries)) { $subOutput = implode(' ' . $this->_operator . ' ', $this->_subQueries); if (! empty($output)) { $output .= ' ' . $this->_operator . ' (' . $subOutput . ')'; } else { $output .= $subOutput; } } return $output; } } /** * Query string implementation. */ class AssistantSolrQueryString extends AbstractAssistantSolrQueryString { /** * Key/value pairs, keys are field string on which to apply the search token * values are the search token. * Key can be a numeric value, in this case it will be ignored and the value * will be apply as a default search pattern. * This will be used to construct the Solr Query string. */ protected $_q = NULL; /** * Add query keyword to given query array. * * @param string $value * Keywords * @param string $field = NULL * (optional) Field name where to append the query string * Note that if this field already exists, string will be concatenated to * existing one. */ public function addQuery($value, $field) { if (empty($field)) { $this->_q[] = $value; } else if (isset($destination[$field])) { $this->_q[$field] .= " " . $value; } else { $this->_q[$field] = $value; } } /** * Add '"' chars if necessary to a token value. * @return unknown_type */ protected static function _escapeToken($token) { if (preg_match("/[\., -:]/", $token)) { return '"' . $token . '"'; } else { return $token; } } /** * @override _renderRawOutput() * @see AbstractAssistantSolrQueryString#_renderRawOutput() */ protected function _renderRawOutput() { $queryString = array(); if (! empty($this->_q)) { foreach ($this->_q as $field => &$token) { // Skip numeric keys, and append the value as default search keyword if (is_numeric($field)) { $queryString[] = self::_escapeToken($token); } else { $queryString[] = $field . ':' . self::_escapeToken($token); } } return implode(" ", $queryString); } return ""; } } /** * Because Solr_Base_Query does not allows us to do full Solr queries, we done * our own simple implementation that fits to our needs. * * TODO: The AssistantSolrParams extends is ugly * * TODO: Cache the computed query strings until modifications are done. */ class AssistantSolrQuery extends AssistantSolrParams { /** * Solr Query string builder * * @var AssistantSolrQueryString */ protected $_q; /** * Get Solr Filter Query string builder * * @return AssistantSolrQueryString */ public function getQueryString() { return $this->_q; } /** * Solr Filter Query string builder * * @var AssistantSolrQueryString */ protected $_fq; /** * Get Solr Filter Query string builder * * @return AssistantSolrQueryString */ public function getFilterQueryString() { return $this->_fq; } /** * @see AssistantSolrQueryString#addQuery() */ public function addQuery($value, $field = NULL) { $this->_q->addQuery($value, $field); } /** * @see AssistantSolrQueryString#addQuery() */ public function addFilterQuery($value, $field = NULL) { $this->_fq->addQuery($value, $field); } /** * Construct the object * * @param array $params = array() * Apache Solr module formated array of params * @param AssistantSolrQueryString $q = NULL * A AssistantSolrQueryString instance for Solr Query string construction * @param AssistantSolrQueryString $fq = NULL * A AssistantSolrQueryString instance for Solr FilterQuery string construction */ public function __construct($params = array(), AssistantSolrQueryString $q = NULL, AssistantSolrQueryString $fq = NULL) { parent::__construct($params); if ($q) { $this->_q = $q; } else { $this->_q = new AssistantSolrQueryString(); } if ($fq) { $this->_fq = $fq; } else { $this->_fq = new AssistantSolrQueryString(); } } /** * Get raw query string * * @return string * Raw query string */ public function getRawQueryString() { return (string) $this->_q; } /** * Get raw filter query string * * @return string * Raw filter query string */ public function getRawFilterQueryString() { return (string) $this->_fq; } }