View source
<?php
require_once 'SolrPhpClient/Apache/Solr/Service.php';
class Drupal_Apache_Solr_Service extends Apache_Solr_Service {
protected $luke;
protected $luke_cid;
protected $stats;
const LUKE_SERVLET = 'admin/luke';
const STATS_SERVLET = 'admin/stats.jsp';
protected $_createDocuments = FALSE;
protected $_collapseSingleValueArrays = FALSE;
public function ping($timeout = 2) {
$start = microtime(TRUE);
if ($timeout <= 0.0) {
$timeout = -1;
}
list($data, $headers) = $this
->_makeHttpRequest($this->_pingUrl, 'HEAD', array(), NULL, $timeout);
$response = new Apache_Solr_Response($data, $headers);
if ($response
->getHttpStatus() == 200) {
return microtime(TRUE) - $start + 0.0001;
}
else {
return FALSE;
}
}
protected function setLuke($num_terms = 0) {
if (empty($this->luke[$num_terms])) {
$url = $this
->_constructUrl(self::LUKE_SERVLET, array(
'numTerms' => "{$num_terms}",
'wt' => self::SOLR_WRITER,
));
$this->luke[$num_terms] = $this
->_sendRawGet($url);
cache_set($this->luke_cid, $this->luke, 'cache_apachesolr');
}
}
public function getFields($num_terms = 0) {
return $this
->getLuke($num_terms)->fields;
}
public function getLuke($num_terms = 0) {
if (!isset($this->luke[$num_terms])) {
$this
->setLuke($num_terms);
}
return $this->luke[$num_terms];
}
protected function setStats() {
$data = $this
->getLuke();
if (empty($this->stats) && isset($data->index->numDocs)) {
$url = $this
->_constructUrl(self::STATS_SERVLET);
$this->stats_cid = "apachesolr:stats:" . md5($url);
$cache = cache_get($this->stats_cid, 'cache_apachesolr');
if (isset($cache->data)) {
$this->stats = simplexml_load_string($cache->data);
}
else {
$response = $this
->_sendRawGet($url);
$this->stats = simplexml_load_string($response
->getRawResponse());
cache_set($this->stats_cid, $response
->getRawResponse(), 'cache_apachesolr');
}
}
}
public function getStats() {
if (!isset($this->stats)) {
$this
->setStats();
}
return $this->stats;
}
public function getStatsSummary() {
$stats = $this
->getStats();
$summary = array(
'@pending_docs' => '',
'@autocommit_time_seconds' => '',
'@autocommit_time' => '',
'@deletes_by_id' => '',
'@deletes_by_query' => '',
'@deletes_total' => '',
'@schema_version' => '',
'@core_name' => '',
);
if (!empty($stats)) {
$docs_pending_xpath = $stats
->xpath('//stat[@name="docsPending"]');
$summary['@pending_docs'] = (int) trim($docs_pending_xpath[0]);
$max_time_xpath = $stats
->xpath('//stat[@name="autocommit maxTime"]');
$max_time = (int) trim(current($max_time_xpath));
$summary['@autocommit_time_seconds'] = $max_time / 1000;
$summary['@autocommit_time'] = format_interval($max_time / 1000);
$deletes_id_xpath = $stats
->xpath('//stat[@name="deletesById"]');
$summary['@deletes_by_id'] = (int) trim($deletes_id_xpath[0]);
$deletes_query_xpath = $stats
->xpath('//stat[@name="deletesByQuery"]');
$summary['@deletes_by_query'] = (int) trim($deletes_query_xpath[0]);
$summary['@deletes_total'] = $summary['@deletes_by_id'] + $summary['@deletes_by_query'];
$schema = $stats
->xpath('/solr/schema[1]');
$summary['@schema_version'] = trim($schema[0]);
$core = $stats
->xpath('/solr/core[1]');
$summary['@core_name'] = trim($core[0]);
}
return $summary;
}
public function clearCache() {
if (@$this
->ping()) {
$this
->_clearCache();
}
else {
throw new Exception('No Solr instance available when trying to clear the cache.');
}
}
protected function _clearCache() {
cache_clear_all("apachesolr:luke:", 'cache_apachesolr', TRUE);
cache_clear_all("apachesolr:stats:", 'cache_apachesolr', TRUE);
$this->luke = array();
$this->stats = NULL;
}
public function commit($optimize = TRUE, $waitFlush = TRUE, $waitSearcher = TRUE, $timeout = 3600) {
parent::commit($optimize, $waitFlush, $waitSearcher, $timeout);
$this
->_clearCache();
}
protected function _initUrls() {
parent::_initUrls();
$this->_lukeUrl = $this
->_constructUrl(self::LUKE_SERVLET, array(
'numTerms' => '0',
'wt' => self::SOLR_WRITER,
));
}
public function makeServletRequest($servlet, $params = array(), $method = 'GET', $request_headers = array(), $rawPost = '', $timeout = FALSE) {
if ($method == 'GET' || $method == 'HEAD') {
$rawPost = '';
}
$params += array(
'wt' => self::SOLR_WRITER,
);
$url = $this
->_constructUrl($servlet, $params);
list($data, $headers) = $this
->_makeHttpRequest($url, $method, $request_headers, $rawPost, $timeout);
$response = new Apache_Solr_Response($data, $headers, $this->_createDocuments, $this->_collapseSingleValueArrays);
$code = (int) $response
->getHttpStatus();
if ($code != 200) {
$message = $response
->getHttpStatusMessage();
if ($code >= 400 && $code != 403 && $code != 404) {
$message .= $response
->getRawResponse();
}
throw new Exception('"' . $code . '" Status: ' . $message);
}
return $response;
}
public function __construct($host = 'localhost', $port = 8180, $path = '/solr/') {
parent::__construct($host, $port, $path);
$this->luke_cid = "apachesolr:luke:" . md5($this->_lukeUrl);
$cache = cache_get($this->luke_cid, 'cache_apachesolr');
if (isset($cache->data)) {
$this->luke = $cache->data;
}
}
public function search($query, $offset = 0, $limit = 10, $params = array(), $method = self::METHOD_GET) {
if (!is_array($params)) {
$params = array();
}
$params['wt'] = self::SOLR_WRITER;
$params['json.nl'] = $this->_namedListTreatment;
$params['q'] = $query;
$params['start'] = $offset;
$params['rows'] = $limit;
$queryString = http_build_query($params, null, $this->_queryStringDelimiter);
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', $queryString);
if (strlen($queryString) > variable_get('apachesolr_search_post_threshold', 4000)) {
$method = self::METHOD_POST;
}
if ($method == self::METHOD_GET) {
return $this
->_sendRawGet($this->_searchUrl . $this->_queryDelimiter . $queryString);
}
else {
if ($method == self::METHOD_POST) {
return $this
->_sendRawPost($this->_searchUrl, $queryString, FALSE, 'application/x-www-form-urlencoded; charset=UTF-8');
}
else {
throw new Exception("Unsupported method '{$method}', please use the Apache_Solr_Service::METHOD_* constants");
}
}
}
protected function _sendRawGet($url, $timeout = FALSE) {
list($data, $headers) = $this
->_makeHttpRequest($url, 'GET', array(), '', $timeout);
$response = new Apache_Solr_Response($data, $headers, $this->_createDocuments, $this->_collapseSingleValueArrays);
$code = (int) $response
->getHttpStatus();
if ($code != 200) {
$message = $response
->getHttpStatusMessage();
if ($code >= 400 && $code != 403 && $code != 404) {
$message .= $response
->getRawResponse();
}
throw new Exception('"' . $code . '" Status: ' . $message);
}
return $response;
}
protected function _sendRawPost($url, $rawPost, $timeout = FALSE, $contentType = 'text/xml; charset=UTF-8') {
$request_headers = array(
'Content-Type' => $contentType,
);
list($data, $headers) = $this
->_makeHttpRequest($url, 'POST', $request_headers, $rawPost, $timeout);
$response = new Apache_Solr_Response($data, $headers, $this->_createDocuments, $this->_collapseSingleValueArrays);
$code = (int) $response
->getHttpStatus();
if ($code != 200) {
$message = $response
->getHttpStatusMessage();
if ($code >= 400 && $code != 403 && $code != 404) {
$message .= $response
->getRawResponse();
}
throw new Exception('"' . $code . '" Status: ' . $message);
}
return $response;
}
protected function _makeHttpRequest($url, $method = 'GET', $headers = array(), $content = '', $timeout = FALSE) {
if ($timeout) {
$default_socket_timeout = ini_set('default_socket_timeout', $timeout);
}
$result = drupal_http_request($url, $headers, $method, $content);
if ($timeout) {
ini_set('default_socket_timeout', $default_socket_timeout);
}
if (!isset($result->code) || $result->code < 0) {
$result->code = 0;
$result->status_message = 'Request failed';
}
if (isset($result->error)) {
$result->status_message .= ': ' . check_plain($result->error);
}
if (!isset($result->data)) {
$result->data = '';
}
$headers[] = "{$result->protocol} {$result->code} {$result->status_message}";
if (isset($result->headers)) {
foreach ($result->headers as $name => $value) {
$headers[] = "{$name}: {$value}";
}
}
return array(
$result->data,
$headers,
);
}
}