View source
<?php
class Solr_Base_Query {
static function get_fields_in_index() {
static $fields;
if (empty($fields)) {
$response = drupal_http_request(apachesolr_base_url() . "/admin/luke?numTerms=0&wt=json");
if ($response->code == '200') {
$data = json_decode($response->data);
}
}
return $data->fields;
}
static function query_extract($keys, $option) {
$pattern = '/(^| )' . $option . ':(\\"([^\\"]*)\\")/i';
preg_match_all($pattern, $keys, $matches);
if (!empty($matches[2])) {
return preg_replace('/^"|"$/', '', $matches[2]);
}
$pattern = '/(^| )' . $option . ':([^ ]*)/i';
if (preg_match_all($pattern, $keys, $matches)) {
if (!empty($matches[2])) {
return $matches[2];
}
}
}
static function query_replace($keys, $option) {
$matches = Solr_Base_Query::query_extract($keys, $option);
if (count($matches) > 0) {
foreach ($matches as $match) {
$found = Solr_Base_Query::make_field(array(
'#name' => $option,
'#value' => $match,
));
$keys = str_replace($found, '', $keys);
}
}
return $keys;
}
static function make_field(array $values) {
if (empty($values['#name'])) {
return implode(' ', array_filter(explode(' ', $values['#value']), 'trim'));
}
else {
if (count(explode(' ', $values['#value'])) > 1) {
$values['#value'] = '"' . $values['#value'] . '"';
}
return $values['#name'] . ':' . $values['#value'];
}
}
private $_fields;
private $_subqueries = array();
private $_query;
private $_field_operator;
function __construct($querystring, $field_operator = "AND") {
$this->_field_operator = $field_operator;
$this->_query = trim($querystring);
$this
->parse_query();
}
function add_field($field, $value) {
$this->_fields[microtime()] = array(
'#name' => $field,
'#value' => trim($value),
);
$this
->rebuild_query();
}
function get_fields() {
return $this->_fields;
}
function remove_field($name, $value = NULL) {
if (empty($name)) {
return;
}
if (empty($value)) {
foreach ($this->_fields as $pos => $values) {
if ($values['#name'] == $name) {
unset($this->_fields[$pos]);
}
}
}
else {
foreach ($this->_fields as $pos => $values) {
if ($values['#name'] == $name && $values['#value'] == $value) {
unset($this->_fields[$pos]);
}
}
}
$this
->rebuild_query();
}
function has_field($name, $value) {
foreach ($this->_fields as $pos => $values) {
if (!empty($values['#name']) && !empty($values['#value']) && $values['#name'] == $name && $values['#value'] == $value) {
return TRUE;
}
}
return FALSE;
}
function add_subquery(Solr_Base_Query $query, $operator = 'AND') {
$this->_subqueries[$query
->get_query_basic()] = array(
'#query' => $query,
'#operator' => $operator,
);
}
function remove_subquery(Solr_Base_Query $query) {
unset($this->_subqueries[$query
->get_query_basic()]);
}
function remove_subqueries() {
$this->_subqueries = array();
}
function get_query() {
$this
->rebuild_query();
return $this->_query;
}
function get_query_basic() {
$nonames = array_filter($this->_fields, create_function('$a', 'return empty($a[\'#name\']);'));
$result = array();
foreach ($nonames as $pos => $field) {
$result[] = $field['#value'];
}
return implode(' ', $result);
}
function get_breadcrumb() {
$breadcrumb = menu_get_active_breadcrumb();
ksort($this->_fields);
$progressive_crumb = array();
$base = 'search/' . arg(1) . '/';
foreach ($this->_fields as $field) {
$progressive_crumb[] = Solr_Base_Query::make_field($field);
if (empty($field['#name'])) {
$breadcrumb[] = l($field['#value'], $base . implode(' ', $progressive_crumb));
}
else {
if ($themed = theme("apachesolr_breadcrumb_{$field['#name']}", $field['#value'])) {
$breadcrumb[] = l($themed, $base . implode(' ', $progressive_crumb));
}
else {
$breadcrumb[] = l($field['#value'], $base . implode(' ', $progressive_crumb));
}
}
}
$last = count($breadcrumb) - 1;
$breadcrumb[$last] = strip_tags($breadcrumb[$last]);
drupal_set_breadcrumb($breadcrumb);
return $breadcrumb;
}
private function parse_query() {
$this->_fields = array();
$_keys = $this->_query;
$index_fields = Solr_Base_Query::get_fields_in_index();
$rows = array();
foreach ((array) $index_fields as $name => $field) {
do {
$a = (int) strlen($_keys);
$values = Solr_Base_Query::query_extract($_keys, $name);
if (count($values) > 0) {
foreach ($values as $value) {
$found = Solr_Base_Query::make_field(array(
'#name' => $name,
'#value' => $value,
));
$pos = strpos($this->_query, $found);
$this->_fields[$pos] = array(
'#name' => $name,
'#value' => trim($value),
);
}
$_keys = trim(Solr_Base_Query::query_replace($_keys, $name));
}
$b = (int) strlen($_keys);
} while ($a !== $b);
if (!empty($_keys)) {
$pos = strpos($this->_query, $_keys);
$this->_fields[$pos] = array(
'#name' => '',
'#value' => trim($_keys),
);
}
}
ksort($this->_fields);
}
private function rebuild_query() {
$fields = array();
foreach ($this->_fields as $pos => $values) {
$fields[] = Solr_Base_Query::make_field($values);
}
$join_delim = $this->_field_operator == 'AND' ? ' ' : ' OR ';
$this->_query = trim(implode($join_delim, array_filter($fields, 'trim')));
foreach ($this->_subqueries as $id => $data) {
$operator = $data['#operator'];
$subquery = $data['#query']
->get_query();
$this->_query .= " {$operator} ({$subquery})";
}
}
}