diff options
Diffstat (limited to 'vendor/ruflin/elastica/lib/Elastica')
215 files changed, 25264 insertions, 0 deletions
diff --git a/vendor/ruflin/elastica/lib/Elastica/AbstractUpdateAction.php b/vendor/ruflin/elastica/lib/Elastica/AbstractUpdateAction.php new file mode 100644 index 00000000..468087af --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/AbstractUpdateAction.php @@ -0,0 +1,568 @@ +<?php +namespace Elastica; + +/** + * Base class for things that can be sent to the update api (Document and + * Script). + * + * @author Nik Everett <nik9000@gmail.com> + */ +class AbstractUpdateAction extends Param +{ + /** + * @var \Elastica\Document + */ + protected $_upsert; + + /** + * Sets the id of the document. + * + * @param string $id + * + * @return $this + */ + public function setId($id) + { + return $this->setParam('_id', $id); + } + + /** + * Returns document id. + * + * @return string|int Document id + */ + public function getId() + { + return ($this->hasParam('_id')) ? $this->getParam('_id') : null; + } + + /** + * @return bool + */ + public function hasId() + { + return '' !== (string) $this->getId(); + } + + /** + * Sets lifetime of document. + * + * @param string $ttl + * + * @return $this + */ + public function setTtl($ttl) + { + return $this->setParam('_ttl', $ttl); + } + + /** + * @return string + */ + public function getTtl() + { + return $this->getParam('_ttl'); + } + + /** + * @return bool + */ + public function hasTtl() + { + return $this->hasParam('_ttl'); + } + + /** + * Sets the document type name. + * + * @param string $type Type name + * + * @return $this + */ + public function setType($type) + { + if ($type instanceof Type) { + $this->setIndex($type->getIndex()); + $type = $type->getName(); + } + + return $this->setParam('_type', $type); + } + + /** + * Return document type name. + * + * @throws \Elastica\Exception\InvalidException + * + * @return string Document type name + */ + public function getType() + { + return $this->getParam('_type'); + } + + /** + * Sets the document index name. + * + * @param string $index Index name + * + * @return $this + */ + public function setIndex($index) + { + if ($index instanceof Index) { + $index = $index->getName(); + } + + return $this->setParam('_index', $index); + } + + /** + * Get the document index name. + * + * @throws \Elastica\Exception\InvalidException + * + * @return string Index name + */ + public function getIndex() + { + return $this->getParam('_index'); + } + + /** + * Sets the version of a document for use with optimistic concurrency control. + * + * @param int $version Document version + * + * @return $this + * + * @link https://www.elastic.co/blog/versioning + */ + public function setVersion($version) + { + return $this->setParam('_version', (int) $version); + } + + /** + * Returns document version. + * + * @return string|int Document version + */ + public function getVersion() + { + return $this->getParam('_version'); + } + + /** + * @return bool + */ + public function hasVersion() + { + return $this->hasParam('_version'); + } + + /** + * Sets the version_type of a document + * Default in ES is internal, but you can set to external to use custom versioning. + * + * @param int $versionType Document version type + * + * @return $this + */ + public function setVersionType($versionType) + { + return $this->setParam('_version_type', $versionType); + } + + /** + * Returns document version type. + * + * @return string|int Document version type + */ + public function getVersionType() + { + return $this->getParam('_version_type'); + } + + /** + * @return bool + */ + public function hasVersionType() + { + return $this->hasParam('_version_type'); + } + + /** + * Sets parent document id. + * + * @param string|int $parent Parent document id + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-parent-field.html + */ + public function setParent($parent) + { + return $this->setParam('_parent', $parent); + } + + /** + * Returns the parent document id. + * + * @return string|int Parent document id + */ + public function getParent() + { + return $this->getParam('_parent'); + } + + /** + * @return bool + */ + public function hasParent() + { + return $this->hasParam('_parent'); + } + + /** + * Set operation type. + * + * @param string $opType Only accept create + * + * @return $this + */ + public function setOpType($opType) + { + return $this->setParam('_op_type', $opType); + } + + /** + * Get operation type. + * + * @return string + */ + public function getOpType() + { + return $this->getParam('_op_type'); + } + + /** + * @return bool + */ + public function hasOpType() + { + return $this->hasParam('_op_type'); + } + + /** + * Set percolate query param. + * + * @param string $value percolator filter + * + * @return $this + */ + public function setPercolate($value = '*') + { + return $this->setParam('_percolate', $value); + } + + /** + * Get percolate parameter. + * + * @return string + */ + public function getPercolate() + { + return $this->getParam('_percolate'); + } + + /** + * @return bool + */ + public function hasPercolate() + { + return $this->hasParam('_percolate'); + } + + /** + * Set routing query param. + * + * @param string $value routing + * + * @return $this + */ + public function setRouting($value) + { + return $this->setParam('_routing', $value); + } + + /** + * Get routing parameter. + * + * @return string + */ + public function getRouting() + { + return $this->getParam('_routing'); + } + + /** + * @return bool + */ + public function hasRouting() + { + return $this->hasParam('_routing'); + } + + /** + * @param array|string $fields + * + * @return $this + */ + public function setFields($fields) + { + if (is_array($fields)) { + $fields = implode(',', $fields); + } + + return $this->setParam('_fields', (string) $fields); + } + + /** + * @return $this + */ + public function setFieldsSource() + { + return $this->setFields('_source'); + } + + /** + * @return string + */ + public function getFields() + { + return $this->getParam('_fields'); + } + + /** + * @return bool + */ + public function hasFields() + { + return $this->hasParam('_fields'); + } + + /** + * @param int $num + * + * @return $this + */ + public function setRetryOnConflict($num) + { + return $this->setParam('_retry_on_conflict', (int) $num); + } + + /** + * @return int + */ + public function getRetryOnConflict() + { + return $this->getParam('_retry_on_conflict'); + } + + /** + * @return bool + */ + public function hasRetryOnConflict() + { + return $this->hasParam('_retry_on_conflict'); + } + + /** + * @param string $timestamp + * + * @return $this + */ + public function setTimestamp($timestamp) + { + return $this->setParam('_timestamp', $timestamp); + } + + /** + * @return int + */ + public function getTimestamp() + { + return $this->getParam('_timestamp'); + } + + /** + * @return bool + */ + public function hasTimestamp() + { + return $this->hasParam('_timestamp'); + } + + /** + * @param bool $refresh + * + * @return $this + */ + public function setRefresh($refresh = true) + { + return $this->setParam('_refresh', (bool) $refresh); + } + + /** + * @return bool + */ + public function getRefresh() + { + return $this->getParam('_refresh'); + } + + /** + * @return bool + */ + public function hasRefresh() + { + return $this->hasParam('_refresh'); + } + + /** + * @param string $timeout + * + * @return $this + */ + public function setTimeout($timeout) + { + return $this->setParam('_timeout', $timeout); + } + + /** + * @return bool + */ + public function getTimeout() + { + return $this->getParam('_timeout'); + } + + /** + * @return string + */ + public function hasTimeout() + { + return $this->hasParam('_timeout'); + } + + /** + * @param string $timeout + * + * @return $this + */ + public function setConsistency($timeout) + { + return $this->setParam('_consistency', $timeout); + } + + /** + * @return string + */ + public function getConsistency() + { + return $this->getParam('_consistency'); + } + + /** + * @return string + */ + public function hasConsistency() + { + return $this->hasParam('_consistency'); + } + + /** + * @param string $timeout + * + * @return $this + */ + public function setReplication($timeout) + { + return $this->setParam('_replication', $timeout); + } + + /** + * @return string + */ + public function getReplication() + { + return $this->getParam('_replication'); + } + + /** + * @return bool + */ + public function hasReplication() + { + return $this->hasParam('_replication'); + } + + /** + * @param \Elastica\Document|array $data + * + * @return $this + */ + public function setUpsert($data) + { + $document = Document::create($data); + $this->_upsert = $document; + + return $this; + } + + /** + * @return \Elastica\Document + */ + public function getUpsert() + { + return $this->_upsert; + } + + /** + * @return bool + */ + public function hasUpsert() + { + return null !== $this->_upsert; + } + + /** + * @param array $fields if empty array all options will be returned, field names can be either with underscored either without, i.e. _percolate, routing + * @param bool $withUnderscore should option keys contain underscore prefix + * + * @return array + */ + public function getOptions(array $fields = array(), $withUnderscore = false) + { + if (!empty($fields)) { + $data = array(); + foreach ($fields as $field) { + $key = '_'.ltrim($field, '_'); + if ($this->hasParam($key) && '' !== (string) $this->getParam($key)) { + $data[$key] = $this->getParam($key); + } + } + } else { + $data = $this->getParams(); + } + if (!$withUnderscore) { + foreach ($data as $key => $value) { + $data[ltrim($key, '_')] = $value; + unset($data[$key]); + } + } + + return $data; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractAggregation.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractAggregation.php new file mode 100644 index 00000000..4cbb6b74 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractAggregation.php @@ -0,0 +1,97 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Exception\InvalidException; +use Elastica\Param; + +abstract class AbstractAggregation extends Param +{ + /** + * @var string The name of this aggregation + */ + protected $_name; + + /** + * @var array Subaggregations belonging to this aggregation + */ + protected $_aggs = array(); + + /** + * @param string $name the name of this aggregation + */ + public function __construct($name) + { + $this->setName($name); + } + + /** + * Set the name of this aggregation. + * + * @param string $name + * + * @return $this + */ + public function setName($name) + { + $this->_name = $name; + + return $this; + } + + /** + * Retrieve the name of this aggregation. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Retrieve all subaggregations belonging to this aggregation. + * + * @return array + */ + public function getAggs() + { + return $this->_aggs; + } + + /** + * Add a sub-aggregation. + * + * @param AbstractAggregation $aggregation + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addAggregation(AbstractAggregation $aggregation) + { + if ($aggregation instanceof GlobalAggregation) { + throw new InvalidException('Global aggregators can only be placed as top level aggregators'); + } + + $this->_aggs[$aggregation->getName()] = $aggregation->toArray(); + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + $array = parent::toArray(); + if (array_key_exists('global_aggregation', $array)) { + // compensate for class name GlobalAggregation + $array = array('global' => new \stdClass()); + } + if (sizeof($this->_aggs)) { + $array['aggs'] = $this->_aggs; + } + + return $array; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractSimpleAggregation.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractSimpleAggregation.php new file mode 100644 index 00000000..02a0fddb --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractSimpleAggregation.php @@ -0,0 +1,37 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Script; + +abstract class AbstractSimpleAggregation extends AbstractAggregation +{ + /** + * Set the field for this aggregation. + * + * @param string $field the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Set a script for this aggregation. + * + * @param string|Script $script + * + * @return $this + */ + public function setScript($script) + { + if ($script instanceof Script) { + $params = array_merge($this->getParams(), $script->toArray()); + + return $this->setParams($params); + } + + return $this->setParam('script', $script); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractTermsAggregation.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractTermsAggregation.php new file mode 100644 index 00000000..57b56964 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractTermsAggregation.php @@ -0,0 +1,97 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class AbstractTermsAggergation. + */ +abstract class AbstractTermsAggregation extends AbstractSimpleAggregation +{ + /** + * Set the minimum number of documents in which a term must appear in order to be returned in a bucket. + * + * @param int $count + * + * @return $this + */ + public function setMinimumDocumentCount($count) + { + return $this->setParam('min_doc_count', $count); + } + + /** + * Filter documents to include based on a regular expression. + * + * @param string $pattern a regular expression + * @param string $flags Java Pattern flags + * + * @return $this + */ + public function setInclude($pattern, $flags = null) + { + if (is_null($flags)) { + return $this->setParam('include', $pattern); + } + + return $this->setParam('include', array( + 'pattern' => $pattern, + 'flags' => $flags, + )); + } + + /** + * Filter documents to exclude based on a regular expression. + * + * @param string $pattern a regular expression + * @param string $flags Java Pattern flags + * + * @return $this + */ + public function setExclude($pattern, $flags = null) + { + if (is_null($flags)) { + return $this->setParam('exclude', $pattern); + } + + return $this->setParam('exclude', array( + 'pattern' => $pattern, + 'flags' => $flags, + )); + } + + /** + * Sets the amount of terms to be returned. + * + * @param int $size The amount of terms to be returned. + * + * @return $this + */ + public function setSize($size) + { + return $this->setParam('size', $size); + } + + /** + * Sets how many terms the coordinating node will request from each shard. + * + * @param int $shard_size The amount of terms to be returned. + * + * @return $this + */ + public function setShardSize($shard_size) + { + return $this->setParam('shard_size', $shard_size); + } + + /** + * Instruct Elasticsearch to use direct field data or ordinals of the field values to execute this aggregation. + * The execution hint will be ignored if it is not applicable. + * + * @param string $hint map or ordinals + * + * @return $this + */ + public function setExecutionHint($hint) + { + return $this->setParam('execution_hint', $hint); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Avg.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Avg.php new file mode 100644 index 00000000..abc2f7a1 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Avg.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Avg. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-avg-aggregation.html + */ +class Avg extends AbstractSimpleAggregation +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Cardinality.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Cardinality.php new file mode 100644 index 00000000..72b2e3aa --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Cardinality.php @@ -0,0 +1,38 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Cardinality. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html + */ +class Cardinality extends AbstractSimpleAggregation +{ + /** + * @param int $precisionThreshold + * + * @return $this + */ + public function setPrecisionThreshold($precisionThreshold) + { + if (!is_int($precisionThreshold)) { + throw new \InvalidArgumentException('precision_threshold only supports integer values'); + } + + return $this->setParam('precision_threshold', $precisionThreshold); + } + + /** + * @param bool $rehash + * + * @return $this + */ + public function setRehash($rehash) + { + if (!is_bool($rehash)) { + throw new \InvalidArgumentException('rehash only supports boolean values'); + } + + return $this->setParam('rehash', $rehash); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/DateHistogram.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/DateHistogram.php new file mode 100644 index 00000000..8636f34c --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/DateHistogram.php @@ -0,0 +1,130 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class DateHistogram. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html + */ +class DateHistogram extends Histogram +{ + /** + * Set pre-rounding based on interval. + * + * @deprecated Option "pre_zone" is deprecated as of ES 1.5. Use "time_zone" instead + * + * @param string $preZone + * + * @return $this + */ + public function setPreZone($preZone) + { + return $this->setParam('pre_zone', $preZone); + } + + /** + * Set post-rounding based on interval. + * + * @deprecated Option "post_zone" is deprecated as of ES 1.5. Use "time_zone" instead + * + * @param string $postZone + * + * @return $this + */ + public function setPostZone($postZone) + { + return $this->setParam('post_zone', $postZone); + } + + /** + * Set time_zone option. + * + * @param string + * + * @return $this + */ + public function setTimezone($timezone) + { + return $this->setParam('time_zone', $timezone); + } + + /** + * Set pre-zone adjustment for larger time intervals (day and above). + * + * @deprecated Option "pre_zone_adjust_large_interval" is deprecated as of ES 1.5 + * + * @param string $adjust + * + * @return $this + */ + public function setPreZoneAdjustLargeInterval($adjust) + { + return $this->setParam('pre_zone_adjust_large_interval', $adjust); + } + + /** + * Adjust for granularity of date data. + * + * @param int $factor set to 1000 if date is stored in seconds rather than milliseconds + * + * @return $this + */ + public function setFactor($factor) + { + return $this->setParam('factor', $factor); + } + + /** + * Set the offset for pre-rounding. + * + * @deprecated Option "pre_offset" is deprecated as of ES 1.5. Use "offset" instead + * + * @param string $offset "1d", for example + * + * @return $this + */ + public function setPreOffset($offset) + { + return $this->setParam('pre_offset', $offset); + } + + /** + * Set the offset for post-rounding. + * + * @deprecated Option "post_offset" is deprecated as of ES 1.5. Use "offset" instead + * + * @param string $offset "1d", for example + * + * @return $this + */ + public function setPostOffset($offset) + { + return $this->setParam('post_offset', $offset); + } + + /** + * Set offset option. + * + * @param string + * + * @return $this + */ + public function setOffset($offset) + { + return $this->setParam('offset', $offset); + } + + /** + * Set the format for returned bucket key_as_string values. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-bucket-daterange-aggregation.html#date-format-pattern + * + * @param string $format see link for formatting options + * + * @return $this + */ + public function setFormat($format) + { + return $this->setParam('format', $format); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/DateRange.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/DateRange.php new file mode 100644 index 00000000..deb5881d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/DateRange.php @@ -0,0 +1,22 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class DateRange. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-daterange-aggregation.html + */ +class DateRange extends Range +{ + /** + * Set the formatting for the returned date values. + * + * @param string $format see documentation for formatting options + * + * @return $this + */ + public function setFormat($format) + { + return $this->setParam('format', $format); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/ExtendedStats.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ExtendedStats.php new file mode 100644 index 00000000..2b108bd1 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ExtendedStats.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class ExtendedStats. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html + */ +class ExtendedStats extends AbstractSimpleAggregation +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Filter.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Filter.php new file mode 100644 index 00000000..fc83419e --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Filter.php @@ -0,0 +1,53 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Filter\AbstractFilter; + +/** + * Class Filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html + */ +class Filter extends AbstractAggregation +{ + /** + * @param string $name + * @param AbstractFilter $filter + */ + public function __construct($name, AbstractFilter $filter = null) + { + parent::__construct($name); + + if ($filter !== null) { + $this->setFilter($filter); + } + } + + /** + * Set the filter for this aggregation. + * + * @param AbstractFilter $filter + * + * @return $this + */ + public function setFilter(AbstractFilter $filter) + { + return $this->setParam('filter', $filter->toArray()); + } + + /** + * @return array + */ + public function toArray() + { + $array = array( + 'filter' => $this->getParam('filter'), + ); + + if ($this->_aggs) { + $array['aggs'] = $this->_aggs; + } + + return $array; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Filters.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Filters.php new file mode 100644 index 00000000..e0fbf060 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Filters.php @@ -0,0 +1,59 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Filter\AbstractFilter; + +/** + * Class Filters. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html + */ +class Filters extends AbstractAggregation +{ + /** + * Add a filter. + * + * If a name is given, it will be added as a key, otherwise considered as an anonymous filter + * + * @param AbstractFilter $filter + * @param string $name + * + * @return $this + */ + public function addFilter(AbstractFilter $filter, $name = '') + { + if (empty($name)) { + $filterArray[] = $filter->toArray(); + } else { + $filterArray[$name] = $filter->toArray(); + } + + return $this->addParam('filters', $filterArray); + } + + /** + * @return array + */ + public function toArray() + { + $array = array(); + $filters = $this->getParam('filters'); + + foreach ($filters as $filter) { + // Detect between anonymous filters and named ones + $key = key($filter); + + if (is_string($key)) { + $array['filters']['filters'][$key] = current($filter); + } else { + $array['filters']['filters'][] = current($filter); + } + } + + if ($this->_aggs) { + $array['aggs'] = $this->_aggs; + } + + return $array; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/GeoDistance.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/GeoDistance.php new file mode 100644 index 00000000..c50018a0 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/GeoDistance.php @@ -0,0 +1,104 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Exception\InvalidException; + +/** + * Class GeoDistance. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geodistance-aggregation.html + */ +class GeoDistance extends AbstractAggregation +{ + const DISTANCE_TYPE_SLOPPY_ARC = 'sloppy_arc'; + const DISTANCE_TYPE_ARC = 'arc'; + const DISTANCE_TYPE_PLANE = 'plane'; + + /** + * @param string $name the name if this aggregation + * @param string $field the field on which to perform this aggregation + * @param string|array $origin the point from which distances will be calculated + */ + public function __construct($name, $field, $origin) + { + parent::__construct($name); + $this->setField($field)->setOrigin($origin); + } + + /** + * Set the field for this aggregation. + * + * @param string $field the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Set the origin point from which distances will be calculated. + * + * @param string|array $origin valid formats are array("lat" => 52.3760, "lon" => 4.894), "52.3760, 4.894", and array(4.894, 52.3760) + * + * @return $this + */ + public function setOrigin($origin) + { + return $this->setParam('origin', $origin); + } + + /** + * Add a distance range to this aggregation. + * + * @param int $fromValue a distance + * @param int $toValue a distance + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addRange($fromValue = null, $toValue = null) + { + if (is_null($fromValue) && is_null($toValue)) { + throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.'); + } + + $range = array(); + + if (!is_null($fromValue)) { + $range['from'] = $fromValue; + } + + if (!is_null($toValue)) { + $range['to'] = $toValue; + } + + return $this->addParam('ranges', $range); + } + + /** + * Set the unit of distance measure for this aggregation. + * + * @param string $unit defaults to km + * + * @return $this + */ + public function setUnit($unit) + { + return $this->setParam('unit', $unit); + } + + /** + * Set the method by which distances will be calculated. + * + * @param string $distanceType see DISTANCE_TYPE_* constants for options. Defaults to sloppy_arc. + * + * @return $this + */ + public function setDistanceType($distanceType) + { + return $this->setParam('distance_type', $distanceType); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/GeohashGrid.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/GeohashGrid.php new file mode 100644 index 00000000..e7a40471 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/GeohashGrid.php @@ -0,0 +1,68 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class GeohashGrid. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html + */ +class GeohashGrid extends AbstractAggregation +{ + /** + * @param string $name the name of this aggregation + * @param string $field the field on which to perform this aggregation + */ + public function __construct($name, $field) + { + parent::__construct($name); + $this->setField($field); + } + + /** + * Set the field for this aggregation. + * + * @param string $field the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Set the precision for this aggregation. + * + * @param int $precision an integer between 1 and 12, inclusive. Defaults to 5. + * + * @return $this + */ + public function setPrecision($precision) + { + return $this->setParam('precision', $precision); + } + + /** + * Set the maximum number of buckets to return. + * + * @param int $size defaults to 10,000 + * + * @return $this + */ + public function setSize($size) + { + return $this->setParam('size', $size); + } + + /** + * Set the number of results returned from each shard. + * + * @param int $shardSize + * + * @return $this + */ + public function setShardSize($shardSize) + { + return $this->setParam('shard_size', $shardSize); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/GlobalAggregation.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/GlobalAggregation.php new file mode 100644 index 00000000..523844d2 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/GlobalAggregation.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class GlobalAggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-global-aggregation.html + */ +class GlobalAggregation extends AbstractAggregation +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Histogram.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Histogram.php new file mode 100644 index 00000000..79a8e517 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Histogram.php @@ -0,0 +1,59 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Histogram. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html + */ +class Histogram extends AbstractSimpleAggregation +{ + /** + * @param string $name the name of this aggregation + * @param string $field the name of the field on which to perform the aggregation + * @param int $interval the interval by which documents will be bucketed + */ + public function __construct($name, $field, $interval) + { + parent::__construct($name); + $this->setField($field); + $this->setInterval($interval); + } + + /** + * Set the interval by which documents will be bucketed. + * + * @param int $interval + * + * @return $this + */ + public function setInterval($interval) + { + return $this->setParam('interval', $interval); + } + + /** + * Set the bucket sort order. + * + * @param string $order "_count", "_term", or the name of a sub-aggregation or sub-aggregation response field + * @param string $direction "asc" or "desc" + * + * @return $this + */ + public function setOrder($order, $direction) + { + return $this->setParam('order', array($order => $direction)); + } + + /** + * Set the minimum number of documents which must fall into a bucket in order for the bucket to be returned. + * + * @param int $count set to 0 to include empty buckets + * + * @return $this + */ + public function setMinimumDocumentCount($count) + { + return $this->setParam('min_doc_count', $count); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/IpRange.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/IpRange.php new file mode 100644 index 00000000..7a4ef7c8 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/IpRange.php @@ -0,0 +1,72 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Exception\InvalidException; + +/** + * Class IpRange. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-iprange-aggregation.html + */ +class IpRange extends AbstractAggregation +{ + /** + * @param string $name the name of this aggregation + * @param string $field the field on which to perform this aggregation + */ + public function __construct($name, $field) + { + parent::__construct($name); + $this->setField($field); + } + + /** + * Set the field for this aggregation. + * + * @param string $field the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Add an ip range to this aggregation. + * + * @param string $fromValue a valid ipv4 address. Low end of this range, exclusive (greater than) + * @param string $toValue a valid ipv4 address. High end of this range, exclusive (less than) + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addRange($fromValue = null, $toValue = null) + { + if (is_null($fromValue) && is_null($toValue)) { + throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.'); + } + $range = array(); + if (!is_null($fromValue)) { + $range['from'] = $fromValue; + } + if (!is_null($toValue)) { + $range['to'] = $toValue; + } + + return $this->addParam('ranges', $range); + } + + /** + * Add an ip range in the form of a CIDR mask. + * + * @param string $mask a valid CIDR mask + * + * @return $this + */ + public function addMaskRange($mask) + { + return $this->addParam('ranges', array('mask' => $mask)); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Max.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Max.php new file mode 100644 index 00000000..fc0294ca --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Max.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Max. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html + */ +class Max extends AbstractSimpleAggregation +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Min.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Min.php new file mode 100644 index 00000000..d5c5c31b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Min.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Min. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-min-aggregation.html + */ +class Min extends AbstractSimpleAggregation +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Missing.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Missing.php new file mode 100644 index 00000000..11a6bdf9 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Missing.php @@ -0,0 +1,32 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Missing. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-missing-aggregation.html + */ +class Missing extends AbstractAggregation +{ + /** + * @param string $name the name of this aggregation + * @param string $field the field on which to perform this aggregation + */ + public function __construct($name, $field) + { + parent::__construct($name); + $this->setField($field); + } + + /** + * Set the field for this aggregation. + * + * @param string $field the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Nested.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Nested.php new file mode 100644 index 00000000..76407bc8 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Nested.php @@ -0,0 +1,32 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Nested. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html + */ +class Nested extends AbstractAggregation +{ + /** + * @param string $name the name of this aggregation + * @param string $path the nested path for this aggregation + */ + public function __construct($name, $path) + { + parent::__construct($name); + $this->setPath($path); + } + + /** + * Set the nested path for this aggregation. + * + * @param string $path + * + * @return $this + */ + public function setPath($path) + { + return $this->setParam('path', $path); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Percentiles.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Percentiles.php new file mode 100644 index 00000000..22079634 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Percentiles.php @@ -0,0 +1,59 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Percentiles. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html + */ +class Percentiles extends AbstractSimpleAggregation +{ + /** + * @param string $name the name of this aggregation + * @param string $field the field on which to perform this aggregation + */ + public function __construct($name, $field = null) + { + parent::__construct($name); + + if (!is_null($field)) { + $this->setField($field); + } + } + + /** + * Set compression parameter. + * + * @param float $value + * + * @return $this + */ + public function setCompression($value) + { + return $this->setParam('compression', (float) $value); + } + + /** + * Set which percents must be returned. + * + * @param float[] $percents + * + * @return $this + */ + public function setPercents(array $percents) + { + return $this->setParam('percents', $percents); + } + + /** + * Add yet another percent to result. + * + * @param float $percent + * + * @return $this + */ + public function addPercent($percent) + { + return $this->addParam('percents', (float) $percent); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Range.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Range.php new file mode 100644 index 00000000..becafb28 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Range.php @@ -0,0 +1,58 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Exception\InvalidException; + +/** + * Class Range. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-range-aggregation.html + */ +class Range extends AbstractSimpleAggregation +{ + /** + * Add a range to this aggregation. + * + * @param int|float $fromValue low end of this range, exclusive (greater than or equal to) + * @param int|float $toValue high end of this range, exclusive (less than) + * @param string $key customized key value + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addRange($fromValue = null, $toValue = null, $key = null) + { + if (is_null($fromValue) && is_null($toValue)) { + throw new InvalidException('Either fromValue or toValue must be set. Both cannot be null.'); + } + + $range = array(); + + if (!is_null($fromValue)) { + $range['from'] = $fromValue; + } + + if (!is_null($toValue)) { + $range['to'] = $toValue; + } + + if (!is_null($key)) { + $range['key'] = $key; + } + + return $this->addParam('ranges', $range); + } + + /** + * If set to true, a unique string key will be associated with each bucket, and ranges will be returned as an associative array. + * + * @param bool $keyed + * + * @return $this + */ + public function setKeyedResponse($keyed = true) + { + return $this->setParam('keyed', (bool) $keyed); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/ReverseNested.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ReverseNested.php new file mode 100644 index 00000000..5216ae85 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ReverseNested.php @@ -0,0 +1,49 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Reversed Nested Aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-reverse-nested-aggregation.html + */ +class ReverseNested extends AbstractAggregation +{ + /** + * @param string $name The name of this aggregation + * @param string $path Optional path to the nested object for this aggregation. Defaults to the root of the main document. + */ + public function __construct($name, $path = null) + { + parent::__construct($name); + + if ($path !== null) { + $this->setPath($path); + } + } + + /** + * Set the nested path for this aggregation. + * + * @param string $path + * + * @return $this + */ + public function setPath($path) + { + return $this->setParam('path', $path); + } + + /** + * {@inheritDoc} + */ + public function toArray() + { + $array = parent::toArray(); + + // ensure we have an object for the reverse_nested key. + // if we don't have a path, then this would otherwise get encoded as an empty array, which is invalid. + $array['reverse_nested'] = (object) $array['reverse_nested']; + + return $array; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/ScriptedMetric.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ScriptedMetric.php new file mode 100644 index 00000000..3e51f056 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ScriptedMetric.php @@ -0,0 +1,82 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class ScriptedMetric. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-scripted-metric-aggregation.html + */ +class ScriptedMetric extends AbstractAggregation +{ + /** + * @param string $name the name if this aggregation + * @param string|null $initScript Executed prior to any collection of documents + * @param string|null $mapScript Executed once per document collected + * @param string|null $combineScript Executed once on each shard after document collection is complete + * @param string|null $reduceScript Executed once on the coordinating node after all shards have returned their results + */ + public function __construct($name, $initScript = null, $mapScript = null, $combineScript = null, $reduceScript = null) + { + parent::__construct($name); + if ($initScript) { + $this->setInitScript($initScript); + } + if ($mapScript) { + $this->setMapScript($mapScript); + } + if ($combineScript) { + $this->setCombineScript($combineScript); + } + if ($reduceScript) { + $this->setReduceScript($reduceScript); + } + } + + /** + * Set the field for this aggregation. + * + * @param string $script the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setCombineScript($script) + { + return $this->setParam('combine_script', $script); + } + + /** + * Set the field for this aggregation. + * + * @param string $script the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setInitScript($script) + { + return $this->setParam('init_script', $script); + } + + /** + * Set the field for this aggregation. + * + * @param string $script the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setMapScript($script) + { + return $this->setParam('map_script', $script); + } + + /** + * Set the field for this aggregation. + * + * @param string $script the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setReduceScript($script) + { + return $this->setParam('reduce_script', $script); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/SignificantTerms.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/SignificantTerms.php new file mode 100644 index 00000000..fa394791 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/SignificantTerms.php @@ -0,0 +1,27 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Filter\AbstractFilter; + +/** + * Class SignificantTerms. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html + */ +class SignificantTerms extends AbstractTermsAggregation +{ + /** + * The default source of statistical information for background term frequencies is the entire index and this scope can + * be narrowed through the use of a background_filter to focus in on significant terms within a narrower context. + * + * @param AbstractFilter $filter + * + * @return $this + * + * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html#_custom_background_context + */ + public function setBackgroundFilter(AbstractFilter $filter) + { + return $this->setParam('background_filter', $filter->toArray()); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Stats.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Stats.php new file mode 100644 index 00000000..f512628c --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Stats.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Stats. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html + */ +class Stats extends AbstractSimpleAggregation +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Sum.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Sum.php new file mode 100644 index 00000000..5172a684 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Sum.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Sum. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html + */ +class Sum extends AbstractSimpleAggregation +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/Terms.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Terms.php new file mode 100644 index 00000000..8d0d6bef --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/Terms.php @@ -0,0 +1,23 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class Terms. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html + */ +class Terms extends AbstractTermsAggregation +{ + /** + * Set the bucket sort order. + * + * @param string $order "_count", "_term", or the name of a sub-aggregation or sub-aggregation response field + * @param string $direction "asc" or "desc" + * + * @return $this + */ + public function setOrder($order, $direction) + { + return $this->setParam('order', array($order => $direction)); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/TopHits.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/TopHits.php new file mode 100644 index 00000000..91a48a48 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/TopHits.php @@ -0,0 +1,156 @@ +<?php +namespace Elastica\Aggregation; + +use Elastica\Script; +use Elastica\ScriptFields; + +/** + * Class TopHits. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html + */ +class TopHits extends AbstractAggregation +{ + /** + * @return array + */ + public function toArray() + { + $array = parent::toArray(); + + // if there are no params, it's ok, but ES will throw exception if json + // will be like {"top_hits":[]} instead of {"top_hits":{}} + if (empty($array['top_hits'])) { + $array['top_hits'] = new \stdClass(); + } + + return $array; + } + + /** + * The maximum number of top matching hits to return per bucket. By default the top three matching hits are returned. + * + * @param int $size + * + * @return $this + */ + public function setSize($size) + { + return $this->setParam('size', (int) $size); + } + + /** + * The offset from the first result you want to fetch. + * + * @param int $from + * + * @return $this + */ + public function setFrom($from) + { + return $this->setParam('from', (int) $from); + } + + /** + * How the top matching hits should be sorted. By default the hits are sorted by the score of the main query. + * + * @param array $sortArgs + * + * @return $this + */ + public function setSort(array $sortArgs) + { + return $this->setParam('sort', $sortArgs); + } + + /** + * Allows to control how the _source field is returned with every hit. + * + * @param array $fields + * + * @return $this + */ + public function setSource(array $fields) + { + return $this->setParam('_source', $fields); + } + + /** + * Returns a version for each search hit. + * + * @param bool $version + * + * @return $this + */ + public function setVersion($version) + { + return $this->setParam('version', (bool) $version); + } + + /** + * Enables explanation for each hit on how its score was computed. + * + * @param bool $explain + * + * @return $this + */ + public function setExplain($explain) + { + return $this->setParam('explain', (bool) $explain); + } + + /** + * Set script fields. + * + * @param array|\Elastica\ScriptFields $scriptFields + * + * @return $this + */ + public function setScriptFields($scriptFields) + { + if (is_array($scriptFields)) { + $scriptFields = new ScriptFields($scriptFields); + } + + return $this->setParam('script_fields', $scriptFields->toArray()); + } + + /** + * Adds a Script to the aggregation. + * + * @param string $name + * @param \Elastica\Script $script + * + * @return $this + */ + public function addScriptField($name, Script $script) + { + $this->_params['script_fields'][$name] = $script->toArray(); + + return $this; + } + + /** + * Sets highlight arguments for the results. + * + * @param array $highlightArgs + * + * @return $this + */ + public function setHighlight(array $highlightArgs) + { + return $this->setParam('highlight', $highlightArgs); + } + + /** + * Allows to return the field data representation of a field for each hit. + * + * @param array $fields + * + * @return $this + */ + public function setFieldDataFields(array $fields) + { + return $this->setParam('fielddata_fields', $fields); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Aggregation/ValueCount.php b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ValueCount.php new file mode 100644 index 00000000..8706a1be --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Aggregation/ValueCount.php @@ -0,0 +1,32 @@ +<?php +namespace Elastica\Aggregation; + +/** + * Class ValueCount. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html + */ +class ValueCount extends AbstractAggregation +{ + /** + * @param string $name the name of this aggregation + * @param string $field the field on which to perform this aggregation + */ + public function __construct($name, $field) + { + parent::__construct($name); + $this->setField($field); + } + + /** + * Set the field for this aggregation. + * + * @param string $field the name of the document field on which to perform this aggregation + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk.php b/vendor/ruflin/elastica/lib/Elastica/Bulk.php new file mode 100644 index 00000000..e7693dce --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk.php @@ -0,0 +1,442 @@ +<?php +namespace Elastica; + +use Elastica\Bulk\Action; +use Elastica\Bulk\Action\AbstractDocument as AbstractDocumentAction; +use Elastica\Bulk\Response as BulkResponse; +use Elastica\Bulk\ResponseSet; +use Elastica\Exception\Bulk\ResponseException as BulkResponseException; +use Elastica\Exception\Bulk\UdpException; +use Elastica\Exception\InvalidException; + +class Bulk +{ + const DELIMITER = "\n"; + + const UDP_DEFAULT_HOST = 'localhost'; + const UDP_DEFAULT_PORT = 9700; + + /** + * @var \Elastica\Client + */ + protected $_client; + + /** + * @var \Elastica\Bulk\Action[] + */ + protected $_actions = array(); + + /** + * @var string + */ + protected $_index = ''; + + /** + * @var string + */ + protected $_type = ''; + + /** + * @var array request parameters to the bulk api + */ + protected $_requestParams = array(); + + /** + * @param \Elastica\Client $client + */ + public function __construct(Client $client) + { + $this->_client = $client; + } + + /** + * @param string|\Elastica\Index $index + * + * @return $this + */ + public function setIndex($index) + { + if ($index instanceof Index) { + $index = $index->getName(); + } + + $this->_index = (string) $index; + + return $this; + } + + /** + * @return string + */ + public function getIndex() + { + return $this->_index; + } + + /** + * @return bool + */ + public function hasIndex() + { + return '' !== $this->getIndex(); + } + + /** + * @param string|\Elastica\Type $type + * + * @return $this + */ + public function setType($type) + { + if ($type instanceof Type) { + $this->setIndex($type->getIndex()->getName()); + $type = $type->getName(); + } + + $this->_type = (string) $type; + + return $this; + } + + /** + * @return string + */ + public function getType() + { + return $this->_type; + } + + /** + * @return bool + */ + public function hasType() + { + return '' !== $this->_type; + } + + /** + * @return string + */ + public function getPath() + { + $path = ''; + if ($this->hasIndex()) { + $path .= $this->getIndex().'/'; + if ($this->hasType()) { + $path .= $this->getType().'/'; + } + } + $path .= '_bulk'; + + return $path; + } + + /** + * @param \Elastica\Bulk\Action $action + * + * @return $this + */ + public function addAction(Action $action) + { + $this->_actions[] = $action; + + return $this; + } + + /** + * @param \Elastica\Bulk\Action[] $actions + * + * @return $this + */ + public function addActions(array $actions) + { + foreach ($actions as $action) { + $this->addAction($action); + } + + return $this; + } + + /** + * @return \Elastica\Bulk\Action[] + */ + public function getActions() + { + return $this->_actions; + } + + /** + * @param \Elastica\Document $document + * @param string $opType + * + * @return $this + */ + public function addDocument(Document $document, $opType = null) + { + $action = AbstractDocumentAction::create($document, $opType); + + return $this->addAction($action); + } + + /** + * @param \Elastica\Document[] $documents + * @param string $opType + * + * @return $this + */ + public function addDocuments(array $documents, $opType = null) + { + foreach ($documents as $document) { + $this->addDocument($document, $opType); + } + + return $this; + } + + /** + * @param \Elastica\Script $data + * @param string $opType + * + * @return $this + */ + public function addScript(Script $script, $opType = null) + { + $action = AbstractDocumentAction::create($script, $opType); + + return $this->addAction($action); + } + + /** + * @param \Elastica\Document[] $scripts + * @param string $opType + * + * @return $this + */ + public function addScripts(array $scripts, $opType = null) + { + foreach ($scripts as $document) { + $this->addScript($document, $opType); + } + + return $this; + } + + /** + * @param \Elastica\Script|\Elastica\Document\array $data + * @param string $opType + * + * @return $this + */ + public function addData($data, $opType = null) + { + if (!is_array($data)) { + $data = array($data); + } + + foreach ($data as $actionData) { + if ($actionData instanceof Script) { + $this->addScript($actionData, $opType); + } elseif ($actionData instanceof Document) { + $this->addDocument($actionData, $opType); + } else { + throw new \InvalidArgumentException('Data should be a Document, a Script or an array containing Documents and/or Scripts'); + } + } + + return $this; + } + + /** + * @param array $data + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addRawData(array $data) + { + foreach ($data as $row) { + if (is_array($row)) { + $opType = key($row); + $metadata = reset($row); + if (Action::isValidOpType($opType)) { + // add previous action + if (isset($action)) { + $this->addAction($action); + } + $action = new Action($opType, $metadata); + } elseif (isset($action)) { + $action->setSource($row); + $this->addAction($action); + $action = null; + } else { + throw new InvalidException('Invalid bulk data, source must follow action metadata'); + } + } else { + throw new InvalidException('Invalid bulk data, should be array of array, Document or Bulk/Action'); + } + } + + // add last action if available + if (isset($action)) { + $this->addAction($action); + } + + return $this; + } + + /** + * Set a url parameter on the request bulk request. + * + * @param string $name name of the parameter + * @param string $value value of the parameter + * + * @return $this + */ + public function setRequestParam($name, $value) + { + $this->_requestParams[$name] = $value; + + return $this; + } + + /** + * Set the amount of time that the request will wait the shards to come on line. + * Requires Elasticsearch version >= 0.90.8. + * + * @param string $time timeout in Elasticsearch time format + * + * @return $this + */ + public function setShardTimeout($time) + { + return $this->setRequestParam('timeout', $time); + } + + /** + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * @return string + */ + public function toString() + { + $data = ''; + foreach ($this->getActions() as $action) { + $data .= $action->toString(); + } + + return $data; + } + + /** + * @return array + */ + public function toArray() + { + $data = array(); + foreach ($this->getActions() as $action) { + foreach ($action->toArray() as $row) { + $data[] = $row; + } + } + + return $data; + } + + /** + * @return \Elastica\Bulk\ResponseSet + */ + public function send() + { + $path = $this->getPath(); + $data = $this->toString(); + + $response = $this->_client->request($path, Request::PUT, $data, $this->_requestParams); + + return $this->_processResponse($response); + } + + /** + * @param \Elastica\Response $response + * + * @throws \Elastica\Exception\Bulk\ResponseException + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\Bulk\ResponseSet + */ + protected function _processResponse(Response $response) + { + $responseData = $response->getData(); + + $actions = $this->getActions(); + + $bulkResponses = array(); + + if (isset($responseData['items']) && is_array($responseData['items'])) { + foreach ($responseData['items'] as $key => $item) { + if (!isset($actions[$key])) { + throw new InvalidException('No response found for action #'.$key); + } + + $action = $actions[$key]; + + $opType = key($item); + $bulkResponseData = reset($item); + + if ($action instanceof AbstractDocumentAction) { + $data = $action->getData(); + if ($data instanceof Document && $data->isAutoPopulate() + || $this->_client->getConfigValue(array('document', 'autoPopulate'), false) + ) { + if (!$data->hasId() && isset($bulkResponseData['_id'])) { + $data->setId($bulkResponseData['_id']); + } + if (isset($bulkResponseData['_version'])) { + $data->setVersion($bulkResponseData['_version']); + } + } + } + + $bulkResponses[] = new BulkResponse($bulkResponseData, $action, $opType); + } + } + + $bulkResponseSet = new ResponseSet($response, $bulkResponses); + + if ($bulkResponseSet->hasError()) { + throw new BulkResponseException($bulkResponseSet); + } + + return $bulkResponseSet; + } + + /** + * @param string $host + * @param int $port + * + * @throws \Elastica\Exception\Bulk\UdpException + */ + public function sendUdp($host = null, $port = null) + { + if (null === $host) { + $host = $this->_client->getConfigValue(array('udp', 'host'), self::UDP_DEFAULT_HOST); + } + if (null === $port) { + $port = $this->_client->getConfigValue(array('udp', 'port'), self::UDP_DEFAULT_PORT); + } + + $message = $this->toString(); + $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + $result = socket_sendto($socket, $message, strlen($message), 0, $host, $port); + socket_close($socket); + if (false === $result) { + throw new UdpException('UDP request failed'); + } + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/Action.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action.php new file mode 100644 index 00000000..25d02adc --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action.php @@ -0,0 +1,228 @@ +<?php +namespace Elastica\Bulk; + +use Elastica\Bulk; +use Elastica\Index; +use Elastica\JSON; +use Elastica\Type; + +class Action +{ + const OP_TYPE_CREATE = 'create'; + const OP_TYPE_INDEX = 'index'; + const OP_TYPE_DELETE = 'delete'; + const OP_TYPE_UPDATE = 'update'; + + /** + * @var array + */ + public static $opTypes = array( + self::OP_TYPE_CREATE, + self::OP_TYPE_INDEX, + self::OP_TYPE_DELETE, + self::OP_TYPE_UPDATE, + ); + + /** + * @var string + */ + protected $_opType; + + /** + * @var array + */ + protected $_metadata = array(); + + /** + * @var array + */ + protected $_source = array(); + + /** + * @param string $opType + * @param array $metadata + * @param array $source + */ + public function __construct($opType = self::OP_TYPE_INDEX, array $metadata = array(), array $source = array()) + { + $this->setOpType($opType); + $this->setMetadata($metadata); + $this->setSource($source); + } + + /** + * @param string $type + * + * @return $this + */ + public function setOpType($type) + { + $this->_opType = $type; + + return $this; + } + + /** + * @return string + */ + public function getOpType() + { + return $this->_opType; + } + + /** + * @param array $metadata + * + * @return $this + */ + public function setMetadata(array $metadata) + { + $this->_metadata = $metadata; + + return $this; + } + + /** + * @return array + */ + public function getMetadata() + { + return $this->_metadata; + } + + /** + * @return array + */ + public function getActionMetadata() + { + return array($this->_opType => $this->getMetadata()); + } + + /** + * @param array $source + * + * @return $this + */ + public function setSource($source) + { + $this->_source = $source; + + return $this; + } + + /** + * @return array + */ + public function getSource() + { + return $this->_source; + } + + /** + * @return bool + */ + public function hasSource() + { + return !empty($this->_source); + } + + /** + * @param string|\Elastica\Index $index + * + * @return $this + */ + public function setIndex($index) + { + if ($index instanceof Index) { + $index = $index->getName(); + } + $this->_metadata['_index'] = $index; + + return $this; + } + + /** + * @param string|\Elastica\Type $type + * + * @return $this + */ + public function setType($type) + { + if ($type instanceof Type) { + $this->setIndex($type->getIndex()->getName()); + $type = $type->getName(); + } + $this->_metadata['_type'] = $type; + + return $this; + } + + /** + * @param string $id + * + * @return $this + */ + public function setId($id) + { + $this->_metadata['_id'] = $id; + + return $this; + } + + /** + * @param string $routing + * + * @return $this + */ + public function setRouting($routing) + { + $this->_metadata['_routing'] = $routing; + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + $data[] = $this->getActionMetadata(); + if ($this->hasSource()) { + $data[] = $this->getSource(); + } + + return $data; + } + + /** + * @return string + */ + public function toString() + { + $string = JSON::stringify($this->getActionMetadata(), JSON_FORCE_OBJECT).Bulk::DELIMITER; + if ($this->hasSource()) { + $source = $this->getSource(); + if (is_string($source)) { + $string .= $source; + } elseif (is_array($source) && array_key_exists('doc', $source) && is_string($source['doc'])) { + $docAsUpsert = (isset($source['doc_as_upsert'])) ? ', "doc_as_upsert": '.$source['doc_as_upsert'] : ''; + $string .= '{"doc": '.$source['doc'].$docAsUpsert.'}'; + } else { + $string .= JSON::stringify($source, 'JSON_ELASTICSEARCH'); + } + $string .= Bulk::DELIMITER; + } + + return $string; + } + + /** + * @param string $opType + * + * @return bool + */ + public static function isValidOpType($opType) + { + return in_array($opType, self::$opTypes); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/AbstractDocument.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/AbstractDocument.php new file mode 100644 index 00000000..3127ff9c --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/AbstractDocument.php @@ -0,0 +1,166 @@ +<?php +namespace Elastica\Bulk\Action; + +use Elastica\AbstractUpdateAction; +use Elastica\Bulk\Action; +use Elastica\Document; +use Elastica\Script; + +abstract class AbstractDocument extends Action +{ + /** + * @var \Elastica\Document|\Elastica\Script + */ + protected $_data; + + /** + * @param \Elastica\Document|\Elastica\Script $document + */ + public function __construct($document) + { + $this->setData($document); + } + + /** + * @param \Elastica\Document $document + * + * @return $this + */ + public function setDocument(Document $document) + { + $this->_data = $document; + + $metadata = $this->_getMetadata($document); + + $this->setMetadata($metadata); + + return $this; + } + + /** + * @param \Elastica\Script $script + * + * @return $this + */ + public function setScript(Script $script) + { + if (!($this instanceof UpdateDocument)) { + throw new \BadMethodCallException('setScript() can only be used for UpdateDocument'); + } + + $this->_data = $script; + + $metadata = $this->_getMetadata($script); + $this->setMetadata($metadata); + + return $this; + } + + /** + * @param \Elastica\Script|\Elastica\Document $data + * + * @throws \InvalidArgumentException + * + * @return $this + */ + public function setData($data) + { + if ($data instanceof Script) { + $this->setScript($data); + } elseif ($data instanceof Document) { + $this->setDocument($data); + } else { + throw new \InvalidArgumentException('Data should be a Document or a Script.'); + } + + return $this; + } + + /** + * Note: This is for backwards compatibility. + * + * @return \Elastica\Document|null + */ + public function getDocument() + { + if ($this->_data instanceof Document) { + return $this->_data; + } + + return; + } + + /** + * Note: This is for backwards compatibility. + * + * @return \Elastica\Script|null + */ + public function getScript() + { + if ($this->_data instanceof Script) { + return $this->_data; + } + + return; + } + + /** + * @return \Elastica\Document|\Elastica\Script + */ + public function getData() + { + return $this->_data; + } + + /** + * @param \Elastica\AbstractUpdateAction $source + * + * @return array + */ + abstract protected function _getMetadata(AbstractUpdateAction $source); + + /** + * @param \Elastica\Document|\Elastica\Script $data + * @param string $opType + * + * @return static + */ + public static function create($data, $opType = null) + { + //Check type + if (!($data instanceof Document) && !($data instanceof Script)) { + throw new \InvalidArgumentException('The data needs to be a Document or a Script.'); + } + + if (null === $opType && $data->hasOpType()) { + $opType = $data->getOpType(); + } + + //Check that scripts can only be used for updates + if ($data instanceof Script) { + if ($opType === null) { + $opType = self::OP_TYPE_UPDATE; + } elseif ($opType != self::OP_TYPE_UPDATE) { + throw new \InvalidArgumentException('Scripts can only be used with the update operation type.'); + } + } + + switch ($opType) { + case self::OP_TYPE_DELETE: + $action = new DeleteDocument($data); + break; + case self::OP_TYPE_CREATE: + $action = new CreateDocument($data); + break; + case self::OP_TYPE_UPDATE: + $action = new UpdateDocument($data); + break; + case self::OP_TYPE_INDEX: + default: + $action = new IndexDocument($data); + break; + } + + return $action; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/CreateDocument.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/CreateDocument.php new file mode 100644 index 00000000..82581856 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/CreateDocument.php @@ -0,0 +1,10 @@ +<?php +namespace Elastica\Bulk\Action; + +class CreateDocument extends IndexDocument +{ + /** + * @var string + */ + protected $_opType = self::OP_TYPE_CREATE; +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/DeleteDocument.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/DeleteDocument.php new file mode 100644 index 00000000..5a243870 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/DeleteDocument.php @@ -0,0 +1,33 @@ +<?php +namespace Elastica\Bulk\Action; + +use Elastica\AbstractUpdateAction; + +class DeleteDocument extends AbstractDocument +{ + /** + * @var string + */ + protected $_opType = self::OP_TYPE_DELETE; + + /** + * @param \Elastica\AbstractUpdateAction $action + * + * @return array + */ + protected function _getMetadata(AbstractUpdateAction $action) + { + $params = array( + 'index', + 'type', + 'id', + 'version', + 'version_type', + 'routing', + 'parent', + ); + $metadata = $action->getOptions($params, true); + + return $metadata; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/IndexDocument.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/IndexDocument.php new file mode 100644 index 00000000..0cf30e61 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/IndexDocument.php @@ -0,0 +1,53 @@ +<?php +namespace Elastica\Bulk\Action; + +use Elastica\AbstractUpdateAction; +use Elastica\Document; + +class IndexDocument extends AbstractDocument +{ + /** + * @var string + */ + protected $_opType = self::OP_TYPE_INDEX; + + /** + * @param \Elastica\Document $document + * + * @return $this + */ + public function setDocument(Document $document) + { + parent::setDocument($document); + + $this->setSource($document->getData()); + + return $this; + } + + /** + * @param \Elastica\AbstractUpdateAction $source + * + * @return array + */ + protected function _getMetadata(AbstractUpdateAction $action) + { + $params = array( + 'index', + 'type', + 'id', + 'version', + 'version_type', + 'routing', + 'percolate', + 'parent', + 'ttl', + 'timestamp', + 'retry_on_conflict', + ); + + $metadata = $action->getOptions($params, true); + + return $metadata; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/UpdateDocument.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/UpdateDocument.php new file mode 100644 index 00000000..2b133acb --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/Action/UpdateDocument.php @@ -0,0 +1,65 @@ +<?php +namespace Elastica\Bulk\Action; + +use Elastica\Document; +use Elastica\Script; + +class UpdateDocument extends IndexDocument +{ + /** + * @var string + */ + protected $_opType = self::OP_TYPE_UPDATE; + + /** + * Set the document for this bulk update action. + * + * @param \Elastica\Document $document + * + * @return $this + */ + public function setDocument(Document $document) + { + parent::setDocument($document); + + $source = array('doc' => $document->getData()); + + if ($document->getDocAsUpsert()) { + $source['doc_as_upsert'] = true; + } elseif ($document->hasUpsert()) { + $upsert = $document->getUpsert()->getData(); + + if (!empty($upsert)) { + $source['upsert'] = $upsert; + } + } + + $this->setSource($source); + + return $this; + } + + /** + * @param \Elastica\Script $script + * + * @return $this + */ + public function setScript(Script $script) + { + parent::setScript($script); + + $source = $script->toArray(); + + if ($script->hasUpsert()) { + $upsert = $script->getUpsert()->getData(); + + if (!empty($upsert)) { + $source['upsert'] = $upsert; + } + } + + $this->setSource($source); + + return $this; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/Response.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/Response.php new file mode 100644 index 00000000..855a72c5 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/Response.php @@ -0,0 +1,46 @@ +<?php +namespace Elastica\Bulk; + +use Elastica\Response as BaseResponse; + +class Response extends BaseResponse +{ + /** + * @var \Elastica\Bulk\Action + */ + protected $_action; + + /** + * @var string + */ + protected $_opType; + + /** + * @param array|string $responseData + * @param \Elastica\Bulk\Action $action + * @param string $opType + */ + public function __construct($responseData, Action $action, $opType) + { + parent::__construct($responseData); + + $this->_action = $action; + $this->_opType = $opType; + } + + /** + * @return \Elastica\Bulk\Action + */ + public function getAction() + { + return $this->_action; + } + + /** + * @return string + */ + public function getOpType() + { + return $this->_opType; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Bulk/ResponseSet.php b/vendor/ruflin/elastica/lib/Elastica/Bulk/ResponseSet.php new file mode 100644 index 00000000..1837203f --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Bulk/ResponseSet.php @@ -0,0 +1,141 @@ +<?php +namespace Elastica\Bulk; + +use Elastica\Response as BaseResponse; + +class ResponseSet extends BaseResponse implements \Iterator, \Countable +{ + /** + * @var \Elastica\Bulk\Response[] + */ + protected $_bulkResponses = array(); + + /** + * @var int + */ + protected $_position = 0; + + /** + * @param \Elastica\Response $response + * @param \Elastica\Bulk\Response[] $bulkResponses + */ + public function __construct(BaseResponse $response, array $bulkResponses) + { + parent::__construct($response->getData()); + + $this->_bulkResponses = $bulkResponses; + } + + /** + * @return \Elastica\Bulk\Response[] + */ + public function getBulkResponses() + { + return $this->_bulkResponses; + } + + /** + * Returns first found error. + * + * @return string + */ + public function getError() + { + $error = ''; + + foreach ($this->getBulkResponses() as $bulkResponse) { + if ($bulkResponse->hasError()) { + $error = $bulkResponse->getError(); + break; + } + } + + return $error; + } + + /** + * @return bool + */ + public function isOk() + { + $return = true; + + foreach ($this->getBulkResponses() as $bulkResponse) { + if (!$bulkResponse->isOk()) { + $return = false; + break; + } + } + + return $return; + } + + /** + * @return bool + */ + public function hasError() + { + $return = false; + + foreach ($this->getBulkResponses() as $bulkResponse) { + if ($bulkResponse->hasError()) { + $return = true; + break; + } + } + + return $return; + } + + /** + * @return bool|\Elastica\Bulk\Response + */ + public function current() + { + if ($this->valid()) { + return $this->_bulkResponses[$this->key()]; + } else { + return false; + } + } + + /** + * + */ + public function next() + { + $this->_position++; + } + + /** + * @return int + */ + public function key() + { + return $this->_position; + } + + /** + * @return bool + */ + public function valid() + { + return isset($this->_bulkResponses[$this->key()]); + } + + /** + * + */ + public function rewind() + { + $this->_position = 0; + } + + /** + * @return int + */ + public function count() + { + return count($this->_bulkResponses); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Client.php b/vendor/ruflin/elastica/lib/Elastica/Client.php new file mode 100644 index 00000000..b30bdb43 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Client.php @@ -0,0 +1,719 @@ +<?php +namespace Elastica; + +use Elastica\Bulk\Action; +use Elastica\Exception\ConnectionException; +use Elastica\Exception\InvalidException; +use Elastica\Exception\RuntimeException; +use Psr\Log\LoggerInterface; + +/** + * Client to connect the the elasticsearch server. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Client +{ + /** + * Config with defaults. + * + * log: Set to true, to enable logging, set a string to log to a specific file + * retryOnConflict: Use in \Elastica\Client::updateDocument + * + * @var array + */ + protected $_config = array( + 'host' => null, + 'port' => null, + 'path' => null, + 'url' => null, + 'proxy' => null, + 'transport' => null, + 'persistent' => true, + 'timeout' => null, + 'connections' => array(), // host, port, path, timeout, transport, persistent, timeout, config -> (curl, headers, url) + 'roundRobin' => false, + 'log' => false, + 'retryOnConflict' => 0, + ); + + /** + * @var callback + */ + protected $_callback = null; + + /** + * @var \Elastica\Request + */ + protected $_lastRequest; + + /** + * @var \Elastica\Response + */ + protected $_lastResponse; + + /** + * @var LoggerInterface + */ + protected $_logger = null; + /** + * @var Connection\ConnectionPool + */ + protected $_connectionPool = null; + + /** + * Creates a new Elastica client. + * + * @param array $config OPTIONAL Additional config options + * @param callback $callback OPTIONAL Callback function which can be used to be notified about errors (for example connection down) + */ + public function __construct(array $config = array(), $callback = null) + { + $this->setConfig($config); + $this->_callback = $callback; + $this->_initConnections(); + } + + /** + * Inits the client connections. + */ + protected function _initConnections() + { + $connections = array(); + + foreach ($this->getConfig('connections') as $connection) { + $connections[] = Connection::create($this->_prepareConnectionParams($connection)); + } + + if (isset($this->_config['servers'])) { + foreach ($this->getConfig('servers') as $server) { + $connections[] = Connection::create($this->_prepareConnectionParams($server)); + } + } + + // If no connections set, create default connection + if (empty($connections)) { + $connections[] = Connection::create($this->_prepareConnectionParams($this->getConfig())); + } + + if (!isset($this->_config['connectionStrategy'])) { + if ($this->getConfig('roundRobin') === true) { + $this->setConfigValue('connectionStrategy', 'RoundRobin'); + } else { + $this->setConfigValue('connectionStrategy', 'Simple'); + } + } + + $strategy = Connection\Strategy\StrategyFactory::create($this->getConfig('connectionStrategy')); + + $this->_connectionPool = new Connection\ConnectionPool($connections, $strategy, $this->_callback); + } + + /** + * Creates a Connection params array from a Client or server config array. + * + * @param array $config + * + * @return array + */ + protected function _prepareConnectionParams(array $config) + { + $params = array(); + $params['config'] = array(); + foreach ($config as $key => $value) { + if (in_array($key, array('curl', 'headers', 'url'))) { + $params['config'][$key] = $value; + } else { + $params[$key] = $value; + } + } + + return $params; + } + + /** + * Sets specific config values (updates and keeps default values). + * + * @param array $config Params + * + * @return $this + */ + public function setConfig(array $config) + { + foreach ($config as $key => $value) { + $this->_config[$key] = $value; + } + + return $this; + } + + /** + * Returns a specific config key or the whole + * config array if not set. + * + * @param string $key Config key + * + * @throws \Elastica\Exception\InvalidException + * + * @return array|string Config value + */ + public function getConfig($key = '') + { + if (empty($key)) { + return $this->_config; + } + + if (!array_key_exists($key, $this->_config)) { + throw new InvalidException('Config key is not set: '.$key); + } + + return $this->_config[$key]; + } + + /** + * Sets / overwrites a specific config value. + * + * @param string $key Key to set + * @param mixed $value Value + * + * @return $this + */ + public function setConfigValue($key, $value) + { + return $this->setConfig(array($key => $value)); + } + + /** + * @param array|string $keys config key or path of config keys + * @param mixed $default default value will be returned if key was not found + * + * @return mixed + */ + public function getConfigValue($keys, $default = null) + { + $value = $this->_config; + foreach ((array) $keys as $key) { + if (isset($value[$key])) { + $value = $value[$key]; + } else { + return $default; + } + } + + return $value; + } + + /** + * Returns the index for the given connection. + * + * @param string $name Index name to create connection to + * + * @return \Elastica\Index Index for the given name + */ + public function getIndex($name) + { + return new Index($this, $name); + } + + /** + * Adds a HTTP Header. + * + * @param string $header The HTTP Header + * @param string $headerValue The HTTP Header Value + * + * @throws \Elastica\Exception\InvalidException If $header or $headerValue is not a string + * + * @return $this + */ + public function addHeader($header, $headerValue) + { + if (is_string($header) && is_string($headerValue)) { + $this->_config['headers'][$header] = $headerValue; + } else { + throw new InvalidException('Header must be a string'); + } + + return $this; + } + + /** + * Remove a HTTP Header. + * + * @param string $header The HTTP Header to remove + * + * @throws \Elastica\Exception\InvalidException If $header is not a string + * + * @return $this + */ + public function removeHeader($header) + { + if (is_string($header)) { + if (array_key_exists($header, $this->_config['headers'])) { + unset($this->_config['headers'][$header]); + } + } else { + throw new InvalidException('Header must be a string'); + } + + return $this; + } + + /** + * Uses _bulk to send documents to the server. + * + * Array of \Elastica\Document as input. Index and type has to be + * set inside the document, because for bulk settings documents, + * documents can belong to any type and index + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @throws \Elastica\Exception\InvalidException If docs is empty + * + * @return \Elastica\Bulk\ResponseSet Response object + */ + public function updateDocuments(array $docs) + { + if (empty($docs)) { + throw new InvalidException('Array has to consist of at least one element'); + } + + $bulk = new Bulk($this); + + $bulk->addDocuments($docs, \Elastica\Bulk\Action::OP_TYPE_UPDATE); + + return $bulk->send(); + } + + /** + * Uses _bulk to send documents to the server. + * + * Array of \Elastica\Document as input. Index and type has to be + * set inside the document, because for bulk settings documents, + * documents can belong to any type and index + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @throws \Elastica\Exception\InvalidException If docs is empty + * + * @return \Elastica\Bulk\ResponseSet Response object + */ + public function addDocuments(array $docs) + { + if (empty($docs)) { + throw new InvalidException('Array has to consist of at least one element'); + } + + $bulk = new Bulk($this); + + $bulk->addDocuments($docs); + + return $bulk->send(); + } + + /** + * Update document, using update script. Requires elasticsearch >= 0.19.0. + * + * @param int $id document id + * @param array|\Elastica\Script|\Elastica\Document $data raw data for request body + * @param string $index index to update + * @param string $type type of index to update + * @param array $options array of query params to use for query. For possible options check es api + * + * @return \Elastica\Response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html + */ + public function updateDocument($id, $data, $index, $type, array $options = array()) + { + $path = $index.'/'.$type.'/'.$id.'/_update'; + + if ($data instanceof Script) { + $requestData = $data->toArray(); + } elseif ($data instanceof Document) { + $requestData = array('doc' => $data->getData()); + + if ($data->getDocAsUpsert()) { + $requestData['doc_as_upsert'] = true; + } + + $docOptions = $data->getOptions( + array( + 'version', + 'version_type', + 'routing', + 'percolate', + 'parent', + 'fields', + 'retry_on_conflict', + 'consistency', + 'replication', + 'refresh', + 'timeout', + ) + ); + $options += $docOptions; + // set fields param to source only if options was not set before + if ($data instanceof Document && ($data->isAutoPopulate() + || $this->getConfigValue(array('document', 'autoPopulate'), false)) + && !isset($options['fields']) + ) { + $options['fields'] = '_source'; + } + } else { + $requestData = $data; + } + + //If an upsert document exists + if ($data instanceof Script || $data instanceof Document) { + if ($data->hasUpsert()) { + $requestData['upsert'] = $data->getUpsert()->getData(); + } + } + + if (!isset($options['retry_on_conflict'])) { + $retryOnConflict = $this->getConfig('retryOnConflict'); + $options['retry_on_conflict'] = $retryOnConflict; + } + + $response = $this->request($path, Request::POST, $requestData, $options); + + if ($response->isOk() + && $data instanceof Document + && ($data->isAutoPopulate() || $this->getConfigValue(array('document', 'autoPopulate'), false)) + ) { + $responseData = $response->getData(); + if (isset($responseData['_version'])) { + $data->setVersion($responseData['_version']); + } + if (isset($options['fields'])) { + $this->_populateDocumentFieldsFromResponse($response, $data, $options['fields']); + } + } + + return $response; + } + + /** + * @param \Elastica\Response $response + * @param \Elastica\Document $document + * @param string $fields Array of field names to be populated or '_source' if whole document data should be updated + */ + protected function _populateDocumentFieldsFromResponse(Response $response, Document $document, $fields) + { + $responseData = $response->getData(); + if ('_source' == $fields) { + if (isset($responseData['get']['_source']) && is_array($responseData['get']['_source'])) { + $document->setData($responseData['get']['_source']); + } + } else { + $keys = explode(',', $fields); + $data = $document->getData(); + foreach ($keys as $key) { + if (isset($responseData['get']['fields'][$key])) { + $data[$key] = $responseData['get']['fields'][$key]; + } elseif (isset($data[$key])) { + unset($data[$key]); + } + } + $document->setData($data); + } + } + + /** + * Bulk deletes documents. + * + * @param array|\Elastica\Document[] $docs + * + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\Bulk\ResponseSet + */ + public function deleteDocuments(array $docs) + { + if (empty($docs)) { + throw new InvalidException('Array has to consist of at least one element'); + } + + $bulk = new Bulk($this); + $bulk->addDocuments($docs, Action::OP_TYPE_DELETE); + + return $bulk->send(); + } + + /** + * Returns the status object for all indices. + * + * @return \Elastica\Status Status object + */ + public function getStatus() + { + return new Status($this); + } + + /** + * Returns the current cluster. + * + * @return \Elastica\Cluster Cluster object + */ + public function getCluster() + { + return new Cluster($this); + } + + /** + * @param \Elastica\Connection $connection + * + * @return $this + */ + public function addConnection(Connection $connection) + { + $this->_connectionPool->addConnection($connection); + + return $this; + } + + /** + * Determines whether a valid connection is available for use. + * + * @return bool + */ + public function hasConnection() + { + return $this->_connectionPool->hasConnection(); + } + + /** + * @throws \Elastica\Exception\ClientException + * + * @return \Elastica\Connection + */ + public function getConnection() + { + return $this->_connectionPool->getConnection(); + } + + /** + * @return \Elastica\Connection[] + */ + public function getConnections() + { + return $this->_connectionPool->getConnections(); + } + + /** + * @return \Elastica\Connection\Strategy\StrategyInterface + */ + public function getConnectionStrategy() + { + return $this->_connectionPool->getStrategy(); + } + + /** + * @param array|\Elastica\Connection[] $connections + * + * @return $this + */ + public function setConnections(array $connections) + { + $this->_connectionPool->setConnections($connections); + + return $this; + } + + /** + * Deletes documents with the given ids, index, type from the index. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + * + * @param array $ids Document ids + * @param string|\Elastica\Index $index Index name + * @param string|\Elastica\Type $type Type of documents + * @param string|false $routing Optional routing key for all ids + * + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\Bulk\ResponseSet Response object + */ + public function deleteIds(array $ids, $index, $type, $routing = false) + { + if (empty($ids)) { + throw new InvalidException('Array has to consist of at least one id'); + } + + $bulk = new Bulk($this); + $bulk->setIndex($index); + $bulk->setType($type); + + foreach ($ids as $id) { + $action = new Action(Action::OP_TYPE_DELETE); + $action->setId($id); + + if (!empty($routing)) { + $action->setRouting($routing); + } + + $bulk->addAction($action); + } + + return $bulk->send(); + } + + /** + * Bulk operation. + * + * Every entry in the params array has to exactly on array + * of the bulk operation. An example param array would be: + * + * array( + * array('index' => array('_index' => 'test', '_type' => 'user', '_id' => '1')), + * array('user' => array('name' => 'hans')), + * array('delete' => array('_index' => 'test', '_type' => 'user', '_id' => '2')) + * ); + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + * + * @param array $params Parameter array + * + * @throws \Elastica\Exception\ResponseException + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\Bulk\ResponseSet Response object + */ + public function bulk(array $params) + { + if (empty($params)) { + throw new InvalidException('Array has to consist of at least one param'); + } + + $bulk = new Bulk($this); + + $bulk->addRawData($params); + + return $bulk->send(); + } + + /** + * Makes calls to the elasticsearch server based on this index. + * + * It's possible to make any REST query directly over this method + * + * @param string $path Path to call + * @param string $method Rest method to use (GET, POST, DELETE, PUT) + * @param array $data OPTIONAL Arguments as array + * @param array $query OPTIONAL Query params + * + * @throws Exception\ConnectionException|\Exception + * + * @return \Elastica\Response Response object + */ + public function request($path, $method = Request::GET, $data = array(), array $query = array()) + { + $connection = $this->getConnection(); + try { + $request = new Request($path, $method, $data, $query, $connection); + + $this->_log($request); + + $response = $request->send(); + + $this->_lastRequest = $request; + $this->_lastResponse = $response; + + return $response; + } catch (ConnectionException $e) { + $this->_connectionPool->onFail($connection, $e, $this); + + // In case there is no valid connection left, throw exception which caused the disabling of the connection. + if (!$this->hasConnection()) { + throw $e; + } + + return $this->request($path, $method, $data, $query); + } + } + + /** + * Optimizes all search indices. + * + * @param array $args OPTIONAL Optional arguments + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-optimize.html + */ + public function optimizeAll($args = array()) + { + return $this->request('_optimize', Request::POST, array(), $args); + } + + /** + * Refreshes all search indices. + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html + */ + public function refreshAll() + { + return $this->request('_refresh', Request::POST); + } + + /** + * logging. + * + * @param string|\Elastica\Request $context + * + * @throws Exception\RuntimeException + */ + protected function _log($context) + { + $log = $this->getConfig('log'); + if ($log && !class_exists('Psr\Log\AbstractLogger')) { + throw new RuntimeException('Class Psr\Log\AbstractLogger not found'); + } elseif (!$this->_logger && $log) { + $this->setLogger(new Log($this->getConfig('log'))); + } + if ($this->_logger) { + if ($context instanceof Request) { + $data = $context->toArray(); + } else { + $data = array('message' => $context); + } + $this->_logger->debug('logging Request', $data); + } + } + + /** + * @return \Elastica\Request + */ + public function getLastRequest() + { + return $this->_lastRequest; + } + + /** + * @return \Elastica\Response + */ + public function getLastResponse() + { + return $this->_lastResponse; + } + + /** + * set Logger. + * + * @param LoggerInterface $logger + * + * @return $this + */ + public function setLogger(LoggerInterface $logger) + { + $this->_logger = $logger; + + return $this; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Cluster.php b/vendor/ruflin/elastica/lib/Elastica/Cluster.php new file mode 100644 index 00000000..990aeeb2 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Cluster.php @@ -0,0 +1,192 @@ +<?php +namespace Elastica; + +use Elastica\Cluster\Health; +use Elastica\Cluster\Settings; +use Elastica\Exception\NotImplementedException; + +/** + * Cluster informations for elasticsearch. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html + */ +class Cluster +{ + /** + * Client. + * + * @var \Elastica\Client Client object + */ + protected $_client = null; + + /** + * Cluster state response. + * + * @var \Elastica\Response + */ + protected $_response; + + /** + * Cluster state data. + * + * @var array + */ + protected $_data; + + /** + * Creates a cluster object. + * + * @param \Elastica\Client $client Connection client object + */ + public function __construct(Client $client) + { + $this->_client = $client; + $this->refresh(); + } + + /** + * Refreshes all cluster information (state). + */ + public function refresh() + { + $path = '_cluster/state'; + $this->_response = $this->_client->request($path, Request::GET); + $this->_data = $this->getResponse()->getData(); + } + + /** + * Returns the response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Return list of index names. + * + * @return array List of index names + */ + public function getIndexNames() + { + $metaData = $this->_data['metadata']['indices']; + + $indices = array(); + foreach ($metaData as $key => $value) { + $indices[] = $key; + } + + return $indices; + } + + /** + * Returns the full state of the cluster. + * + * @return array State array + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-state.html + */ + public function getState() + { + return $this->_data; + } + + /** + * Returns a list of existing node names. + * + * @return array List of node names + */ + public function getNodeNames() + { + $data = $this->getState(); + $nodeNames = array(); + foreach ($data['nodes'] as $node) { + $nodeNames[] = $node['name']; + } + + return $nodeNames; + } + + /** + * Returns all nodes of the cluster. + * + * @return \Elastica\Node[] + */ + public function getNodes() + { + $nodes = array(); + $data = $this->getState(); + + foreach ($data['nodes'] as $id => $name) { + $nodes[] = new Node($id, $this->getClient()); + } + + return $nodes; + } + + /** + * Returns the client object. + * + * @return \Elastica\Client Client object + */ + public function getClient() + { + return $this->_client; + } + + /** + * Returns the cluster information (not implemented yet). + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-info.html + * + * @param array $args Additional arguments + * + * @throws \Elastica\Exception\NotImplementedException + */ + public function getInfo(array $args) + { + throw new NotImplementedException('not implemented yet'); + } + + /** + * Return Cluster health. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html + * + * @return \Elastica\Cluster\Health + */ + public function getHealth() + { + return new Health($this->getClient()); + } + + /** + * Return Cluster settings. + * + * @return \Elastica\Cluster\Settings + */ + public function getSettings() + { + return new Settings($this->getClient()); + } + + /** + * Shuts down the complete cluster. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-shutdown.html + * + * @param string $delay OPTIONAL Seconds to shutdown cluster after (default = 1s) + * + * @return \Elastica\Response + */ + public function shutdown($delay = '1s') + { + $path = '_shutdown?delay='.$delay; + + return $this->_client->request($path, Request::POST); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Cluster/Health.php b/vendor/ruflin/elastica/lib/Elastica/Cluster/Health.php new file mode 100644 index 00000000..d5d25ff1 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Cluster/Health.php @@ -0,0 +1,185 @@ +<?php +namespace Elastica\Cluster; + +use Elastica\Client; +use Elastica\Cluster\Health\Index; +use Elastica\Request; + +/** + * Elastic cluster health. + * + * @author Ray Ward <ray.ward@bigcommerce.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html + */ +class Health +{ + /** + * @var \Elastica\Client Client object. + */ + protected $_client = null; + + /** + * @var array The cluster health data. + */ + protected $_data = null; + + /** + * @param \Elastica\Client $client The Elastica client. + */ + public function __construct(Client $client) + { + $this->_client = $client; + $this->refresh(); + } + + /** + * Retrieves the health data from the cluster. + * + * @return array + */ + protected function _retrieveHealthData() + { + $path = '_cluster/health?level=shards'; + $response = $this->_client->request($path, Request::GET); + + return $response->getData(); + } + + /** + * Gets the health data. + * + * @return array + */ + public function getData() + { + return $this->_data; + } + + /** + * Refreshes the health data for the cluster. + * + * @return $this + */ + public function refresh() + { + $this->_data = $this->_retrieveHealthData(); + + return $this; + } + + /** + * Gets the name of the cluster. + * + * @return string + */ + public function getClusterName() + { + return $this->_data['cluster_name']; + } + + /** + * Gets the status of the cluster. + * + * @return string green, yellow or red. + */ + public function getStatus() + { + return $this->_data['status']; + } + + /** + * TODO determine the purpose of this. + * + * @return bool + */ + public function getTimedOut() + { + return $this->_data['timed_out']; + } + + /** + * Gets the number of nodes in the cluster. + * + * @return int + */ + public function getNumberOfNodes() + { + return $this->_data['number_of_nodes']; + } + + /** + * Gets the number of data nodes in the cluster. + * + * @return int + */ + public function getNumberOfDataNodes() + { + return $this->_data['number_of_data_nodes']; + } + + /** + * Gets the number of active primary shards. + * + * @return int + */ + public function getActivePrimaryShards() + { + return $this->_data['active_primary_shards']; + } + + /** + * Gets the number of active shards. + * + * @return int + */ + public function getActiveShards() + { + return $this->_data['active_shards']; + } + + /** + * Gets the number of relocating shards. + * + * @return int + */ + public function getRelocatingShards() + { + return $this->_data['relocating_shards']; + } + + /** + * Gets the number of initializing shards. + * + * @return int + */ + public function getInitializingShards() + { + return $this->_data['initializing_shards']; + } + + /** + * Gets the number of unassigned shards. + * + * @return int + */ + public function getUnassignedShards() + { + return $this->_data['unassigned_shards']; + } + + /** + * Gets the status of the indices. + * + * @return \Elastica\Cluster\Health\Index[] + */ + public function getIndices() + { + $indices = array(); + foreach ($this->_data['indices'] as $indexName => $index) { + $indices[] = new Index($indexName, $index); + } + + return $indices; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Index.php b/vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Index.php new file mode 100644 index 00000000..ef55bd00 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Index.php @@ -0,0 +1,137 @@ +<?php +namespace Elastica\Cluster\Health; + +/** + * Wraps status information for an index. + * + * @author Ray Ward <ray.ward@bigcommerce.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html + */ +class Index +{ + /** + * @var string The name of the index. + */ + protected $_name; + + /** + * @var array The index health data. + */ + protected $_data; + + /** + * @param string $name The name of the index. + * @param array $data The index health data. + */ + public function __construct($name, $data) + { + $this->_name = $name; + $this->_data = $data; + } + + /** + * Gets the name of the index. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Gets the status of the index. + * + * @return string green, yellow or red. + */ + public function getStatus() + { + return $this->_data['status']; + } + + /** + * Gets the number of nodes in the index. + * + * @return int + */ + public function getNumberOfShards() + { + return $this->_data['number_of_shards']; + } + + /** + * Gets the number of data nodes in the index. + * + * @return int + */ + public function getNumberOfReplicas() + { + return $this->_data['number_of_replicas']; + } + + /** + * Gets the number of active primary shards. + * + * @return int + */ + public function getActivePrimaryShards() + { + return $this->_data['active_primary_shards']; + } + + /** + * Gets the number of active shards. + * + * @return int + */ + public function getActiveShards() + { + return $this->_data['active_shards']; + } + + /** + * Gets the number of relocating shards. + * + * @return int + */ + public function getRelocatingShards() + { + return $this->_data['relocating_shards']; + } + + /** + * Gets the number of initializing shards. + * + * @return int + */ + public function getInitializingShards() + { + return $this->_data['initializing_shards']; + } + + /** + * Gets the number of unassigned shards. + * + * @return int + */ + public function getUnassignedShards() + { + return $this->_data['unassigned_shards']; + } + + /** + * Gets the health of the shards in this index. + * + * @return \Elastica\Cluster\Health\Shard[] + */ + public function getShards() + { + $shards = array(); + foreach ($this->_data['shards'] as $shardNumber => $shard) { + $shards[] = new Shard($shardNumber, $shard); + } + + return $shards; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Shard.php b/vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Shard.php new file mode 100644 index 00000000..e1d2c8dc --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Shard.php @@ -0,0 +1,102 @@ +<?php +namespace Elastica\Cluster\Health; + +/** + * Wraps status information for a shard. + * + * @author Ray Ward <ray.ward@bigcommerce.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html + */ +class Shard +{ + /** + * @var int The shard index/number. + */ + protected $_shardNumber; + + /** + * @var array The shard health data. + */ + protected $_data; + + /** + * @param int $shardNumber The shard index/number. + * @param array $data The shard health data. + */ + public function __construct($shardNumber, $data) + { + $this->_shardNumber = $shardNumber; + $this->_data = $data; + } + + /** + * Gets the index/number of this shard. + * + * @return int + */ + public function getShardNumber() + { + return $this->_shardNumber; + } + + /** + * Gets the status of this shard. + * + * @return string green, yellow or red. + */ + public function getStatus() + { + return $this->_data['status']; + } + + /** + * Is the primary active? + * + * @return bool + */ + public function isPrimaryActive() + { + return $this->_data['primary_active']; + } + + /** + * Is this shard active? + * + * @return bool + */ + public function isActive() + { + return $this->_data['active_shards'] == 1; + } + + /** + * Is this shard relocating? + * + * @return bool + */ + public function isRelocating() + { + return $this->_data['relocating_shards'] == 1; + } + + /** + * Is this shard initialized? + * + * @return bool + */ + public function isInitialized() + { + return $this->_data['initializing_shards'] == 1; + } + + /** + * Is this shard unassigned? + * + * @return bool + */ + public function isUnassigned() + { + return $this->_data['unassigned_shards'] == 1; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Cluster/Settings.php b/vendor/ruflin/elastica/lib/Elastica/Cluster/Settings.php new file mode 100644 index 00000000..c597417f --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Cluster/Settings.php @@ -0,0 +1,202 @@ +<?php +namespace Elastica\Cluster; + +use Elastica\Client; +use Elastica\Request; + +/** + * Cluster settings. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-update-settings.html + */ +class Settings +{ + /** + * @var \Elastica\Client Client object + */ + protected $_client = null; + + /** + * Creates a cluster object. + * + * @param \Elastica\Client $client Connection client object + */ + public function __construct(Client $client) + { + $this->_client = $client; + } + + /** + * Returns settings data. + * + * @return array Settings data (persistent and transient) + */ + public function get() + { + return $this->request()->getData(); + } + + /** + * Returns the current persistent settings of the cluster. + * + * If param is set, only specified setting is return. + * + * @param string $setting OPTIONAL Setting name to return + * + * @return array|string|null Settings data + */ + public function getPersistent($setting = '') + { + $data = $this->get(); + $settings = $data['persistent']; + + if (!empty($setting)) { + if (isset($settings[$setting])) { + return $settings[$setting]; + } else { + return; + } + } + + return $settings; + } + + /** + * Returns the current transient settings of the cluster. + * + * If param is set, only specified setting is return. + * + * @param string $setting OPTIONAL Setting name to return + * + * @return array|string|null Settings data + */ + public function getTransient($setting = '') + { + $data = $this->get(); + $settings = $data['transient']; + + if (!empty($setting)) { + if (isset($settings[$setting])) { + return $settings[$setting]; + } else { + if (strpos($setting, '.') !== false) { + // convert dot notation to nested arrays + $keys = explode('.', $setting); + foreach ($keys as $key) { + if (isset($settings[$key])) { + $settings = $settings[$key]; + } else { + return; + } + } + + return $settings; + } + + return; + } + } + + return $settings; + } + + /** + * Sets persistent setting. + * + * @param string $key + * @param string $value + * + * @return \Elastica\Response + */ + public function setPersistent($key, $value) + { + return $this->set( + array( + 'persistent' => array( + $key => $value, + ), + ) + ); + } + + /** + * Sets transient settings. + * + * @param string $key + * @param string $value + * + * @return \Elastica\Response + */ + public function setTransient($key, $value) + { + return $this->set( + array( + 'transient' => array( + $key => $value, + ), + ) + ); + } + + /** + * Sets the cluster to read only. + * + * Second param can be used to set it persistent + * + * @param bool $readOnly + * @param bool $persistent + * + * @return \Elastica\Response $response + */ + public function setReadOnly($readOnly = true, $persistent = false) + { + $key = 'cluster.blocks.read_only'; + + if ($persistent) { + $response = $this->setPersistent($key, $readOnly); + } else { + $response = $this->setTransient($key, $readOnly); + } + + return $response; + } + + /** + * Set settings for cluster. + * + * @param array $settings Raw settings (including persistent or transient) + * + * @return \Elastica\Response + */ + public function set(array $settings) + { + return $this->request($settings, Request::PUT); + } + + /** + * Get the client. + * + * @return \Elastica\Client + */ + public function getClient() + { + return $this->_client; + } + + /** + * Sends settings request. + * + * @param array $data OPTIONAL Data array + * @param string $method OPTIONAL Transfer method (default = \Elastica\Request::GET) + * + * @return \Elastica\Response Response object + */ + public function request(array $data = array(), $method = Request::GET) + { + $path = '_cluster/settings'; + + return $this->getClient()->request($path, $method, $data); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Connection.php b/vendor/ruflin/elastica/lib/Elastica/Connection.php new file mode 100644 index 00000000..0084b6ee --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Connection.php @@ -0,0 +1,320 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; +use Elastica\Transport\AbstractTransport; + +/** + * Elastica connection instance to an elasticasearch node. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Connection extends Param +{ + /** + * Default elastic search port. + */ + const DEFAULT_PORT = 9200; + + /** + * Default host. + */ + const DEFAULT_HOST = 'localhost'; + + /** + * Default transport. + * + * @var string + */ + const DEFAULT_TRANSPORT = 'Http'; + + /** + * Number of seconds after a timeout occurs for every request + * If using indexing of file large value necessary. + */ + const TIMEOUT = 300; + + /** + * Number of seconds after a connection timeout occurs for every request during the connection phase. + * + * @see Connection::setConnectTimeout(); + */ + const CONNECT_TIMEOUT = 0; + + /** + * Creates a new connection object. A connection is enabled by default. + * + * @param array $params OPTIONAL Connection params: host, port, transport, timeout. All are optional + */ + public function __construct(array $params = array()) + { + $this->setParams($params); + $this->setEnabled(true); + + // Set empty config param if not exists + if (!$this->hasParam('config')) { + $this->setParam('config', array()); + } + } + + /** + * @return int Server port + */ + public function getPort() + { + return $this->hasParam('port') ? $this->getParam('port') : self::DEFAULT_PORT; + } + + /** + * @param int $port + * + * @return $this + */ + public function setPort($port) + { + return $this->setParam('port', (int) $port); + } + + /** + * @return string Host + */ + public function getHost() + { + return $this->hasParam('host') ? $this->getParam('host') : self::DEFAULT_HOST; + } + + /** + * @param string $host + * + * @return $this + */ + public function setHost($host) + { + return $this->setParam('host', $host); + } + + /** + * @return string|null Host + */ + public function getProxy() + { + return $this->hasParam('proxy') ? $this->getParam('proxy') : null; + } + + /** + * Set proxy for http connections. Null is for environmental proxy, + * empty string to disable proxy and proxy string to set actual http proxy. + * + * @see http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTPROXY + * + * @param string|null $proxy + * + * @return $this + */ + public function setProxy($proxy) + { + return $this->setParam('proxy', $proxy); + } + + /** + * @return string|array + */ + public function getTransport() + { + return $this->hasParam('transport') ? $this->getParam('transport') : self::DEFAULT_TRANSPORT; + } + + /** + * @param string|array $transport + * + * @return $this + */ + public function setTransport($transport) + { + return $this->setParam('transport', $transport); + } + + /** + * @return string + */ + public function getPath() + { + return $this->hasParam('path') ? $this->getParam('path') : ''; + } + + /** + * @param string $path + * + * @return $this + */ + public function setPath($path) + { + return $this->setParam('path', $path); + } + + /** + * @param int $timeout Timeout in seconds + * + * @return $this + */ + public function setTimeout($timeout) + { + return $this->setParam('timeout', $timeout); + } + + /** + * @return int Connection timeout in seconds + */ + public function getTimeout() + { + return (int) $this->hasParam('timeout') ? $this->getParam('timeout') : self::TIMEOUT; + } + + /** + * Number of seconds after a connection timeout occurs for every request during the connection phase. + * Use a small value if you need a fast fail in case of dead, unresponsive or unreachable servers (~5 sec). + * + * Set to zero to switch to the default built-in connection timeout (300 seconds in curl). + * + * @see http://curl.haxx.se/libcurl/c/CURLOPT_CONNECTTIMEOUT.html + * + * @param int $timeout Connect timeout in seconds + * + * @return $this + */ + public function setConnectTimeout($timeout) + { + return $this->setParam('connectTimeout', $timeout); + } + + /** + * @return int Connection timeout in seconds + */ + public function getConnectTimeout() + { + return (int) $this->hasParam('connectTimeout') ? $this->getParam('connectTimeout') : self::CONNECT_TIMEOUT; + } + + /** + * Enables a connection. + * + * @param bool $enabled OPTIONAL (default = true) + * + * @return $this + */ + public function setEnabled($enabled = true) + { + return $this->setParam('enabled', $enabled); + } + + /** + * @return bool True if enabled + */ + public function isEnabled() + { + return (bool) $this->getParam('enabled'); + } + + /** + * Returns an instance of the transport type. + * + * @throws \Elastica\Exception\InvalidException If invalid transport type + * + * @return \Elastica\Transport\AbstractTransport Transport object + */ + public function getTransportObject() + { + $transport = $this->getTransport(); + + return AbstractTransport::create($transport, $this); + } + + /** + * @return bool Returns true if connection is persistent. True by default + */ + public function isPersistent() + { + return (bool) $this->hasParam('persistent') ? $this->getParam('persistent') : true; + } + + /** + * @param array $config + * + * @return $this + */ + public function setConfig(array $config) + { + return $this->setParam('config', $config); + } + + /** + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function addConfig($key, $value) + { + $this->_params['config'][$key] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return bool + */ + public function hasConfig($key) + { + $config = $this->getConfig(); + + return isset($config[$key]); + } + + /** + * Returns a specific config key or the whole + * config array if not set. + * + * @param string $key Config key + * + * @throws \Elastica\Exception\InvalidException + * + * @return array|string Config value + */ + public function getConfig($key = '') + { + $config = $this->getParam('config'); + if (empty($key)) { + return $config; + } + + if (!array_key_exists($key, $config)) { + throw new InvalidException('Config key is not set: '.$key); + } + + return $config[$key]; + } + + /** + * @param \Elastica\Connection|array $params Params to create a connection + * + * @throws Exception\InvalidException + * + * @return self + */ + public static function create($params = array()) + { + $connection = null; + + if ($params instanceof self) { + $connection = $params; + } elseif (is_array($params)) { + $connection = new self($params); + } else { + throw new InvalidException('Invalid data type'); + } + + return $connection; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Connection/ConnectionPool.php b/vendor/ruflin/elastica/lib/Elastica/Connection/ConnectionPool.php new file mode 100644 index 00000000..b5fa681d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Connection/ConnectionPool.php @@ -0,0 +1,122 @@ +<?php +namespace Elastica\Connection; + +use Elastica\Client; +use Elastica\Connection; +use Elastica\Connection\Strategy\StrategyInterface; +use Exception; + +/** + * Description of ConnectionPool. + * + * @author chabior + */ +class ConnectionPool +{ + /** + * @var array|\Elastica\Connection[] Connections array + */ + protected $_connections; + + /** + * @var \Elastica\Connection\Strategy\StrategyInterface Strategy for connection + */ + protected $_strategy; + + /** + * @var callback Function called on connection fail + */ + protected $_callback; + + /** + * @param array $connections + * @param \Elastica\Connection\Strategy\StrategyInterface $strategy + * @param callback $callback + */ + public function __construct(array $connections, StrategyInterface $strategy, $callback = null) + { + $this->_connections = $connections; + + $this->_strategy = $strategy; + + $this->_callback = $callback; + } + + /** + * @param \Elastica\Connection $connection + * + * @return $this + */ + public function addConnection(Connection $connection) + { + $this->_connections[] = $connection; + + return $this; + } + + /** + * @param array|\Elastica\Connection[] $connections + * + * @return $this + */ + public function setConnections(array $connections) + { + $this->_connections = $connections; + + return $this; + } + + /** + * @return bool + */ + public function hasConnection() + { + foreach ($this->_connections as $connection) { + if ($connection->isEnabled()) { + return true; + } + } + + return false; + } + + /** + * @return array + */ + public function getConnections() + { + return $this->_connections; + } + + /** + * @throws \Elastica\Exception\ClientException + * + * @return \Elastica\Connection + */ + public function getConnection() + { + return $this->_strategy->getConnection($this->getConnections()); + } + + /** + * @param \Elastica\Connection $connection + * @param \Exception $e + * @param Client $client + */ + public function onFail(Connection $connection, Exception $e, Client $client) + { + $connection->setEnabled(false); + + if ($this->_callback) { + call_user_func($this->_callback, $connection, $e, $client); + } + } + + /** + * @return \Elastica\Connection\Strategy\StrategyInterface + */ + public function getStrategy() + { + return $this->_strategy; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/CallbackStrategy.php b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/CallbackStrategy.php new file mode 100644 index 00000000..ccaeb6dd --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/CallbackStrategy.php @@ -0,0 +1,51 @@ +<?php +namespace Elastica\Connection\Strategy; + +use Elastica\Exception\InvalidException; + +/** + * Description of CallbackStrategy. + * + * @author chabior + */ +class CallbackStrategy implements StrategyInterface +{ + /** + * @var callable + */ + protected $_callback; + + /** + * @param callable $callback + * + * @throws \Elastica\Exception\InvalidException + */ + public function __construct($callback) + { + if (!self::isValid($callback)) { + throw new InvalidException(sprintf('Callback should be a callable, %s given!', gettype($callback))); + } + + $this->_callback = $callback; + } + + /** + * @param array|\Elastica\Connection[] $connections + * + * @return \Elastica\Connection + */ + public function getConnection($connections) + { + return call_user_func_array($this->_callback, array($connections)); + } + + /** + * @param callable $callback + * + * @return bool + */ + public static function isValid($callback) + { + return is_callable($callback); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/RoundRobin.php b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/RoundRobin.php new file mode 100644 index 00000000..92cd570e --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/RoundRobin.php @@ -0,0 +1,24 @@ +<?php +namespace Elastica\Connection\Strategy; + +/** + * Description of RoundRobin. + * + * @author chabior + */ +class RoundRobin extends Simple +{ + /** + * @param array|\Elastica\Connection[] $connections + * + * @throws \Elastica\Exception\ClientException + * + * @return \Elastica\Connection + */ + public function getConnection($connections) + { + shuffle($connections); + + return parent::getConnection($connections); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/Simple.php b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/Simple.php new file mode 100644 index 00000000..7c42dd3b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/Simple.php @@ -0,0 +1,30 @@ +<?php +namespace Elastica\Connection\Strategy; + +use Elastica\Exception\ClientException; + +/** + * Description of SimpleStrategy. + * + * @author chabior + */ +class Simple implements StrategyInterface +{ + /** + * @param array|\Elastica\Connection[] $connections + * + * @throws \Elastica\Exception\ClientException + * + * @return \Elastica\Connection + */ + public function getConnection($connections) + { + foreach ($connections as $connection) { + if ($connection->isEnabled()) { + return $connection; + } + } + + throw new ClientException('No enabled connection'); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyFactory.php b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyFactory.php new file mode 100644 index 00000000..7590ab11 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyFactory.php @@ -0,0 +1,45 @@ +<?php +namespace Elastica\Connection\Strategy; + +use Elastica\Exception\InvalidException; + +/** + * Description of StrategyFactory. + * + * @author chabior + */ +class StrategyFactory +{ + /** + * @param mixed|callable|string|StrategyInterface $strategyName + * + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\Connection\Strategy\StrategyInterface + */ + public static function create($strategyName) + { + if ($strategyName instanceof StrategyInterface) { + return $strategyName; + } + + if (CallbackStrategy::isValid($strategyName)) { + return new CallbackStrategy($strategyName); + } + + if (is_string($strategyName)) { + $requiredInterface = '\\Elastica\\Connection\\Strategy\\StrategyInterface'; + $predefinedStrategy = '\\Elastica\\Connection\\Strategy\\'.$strategyName; + + if (class_exists($predefinedStrategy) && class_implements($predefinedStrategy, $requiredInterface)) { + return new $predefinedStrategy(); + } + + if (class_exists($strategyName) && class_implements($strategyName, $requiredInterface)) { + return new $strategyName(); + } + } + + throw new InvalidException('Can\'t create strategy instance by given argument'); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyInterface.php b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyInterface.php new file mode 100644 index 00000000..29bf7701 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyInterface.php @@ -0,0 +1,17 @@ +<?php +namespace Elastica\Connection\Strategy; + +/** + * Description of AbstractStrategy. + * + * @author chabior + */ +interface StrategyInterface +{ + /** + * @param array|\Elastica\Connection[] $connections + * + * @return \Elastica\Connection + */ + public function getConnection($connections); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Document.php b/vendor/ruflin/elastica/lib/Elastica/Document.php new file mode 100644 index 00000000..e82afae9 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Document.php @@ -0,0 +1,356 @@ +<?php +namespace Elastica; + +use Elastica\Bulk\Action; +use Elastica\Exception\InvalidException; +use Elastica\Exception\NotImplementedException; + +/** + * Single document stored in elastic search. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Document extends AbstractUpdateAction +{ + const OP_TYPE_CREATE = Action::OP_TYPE_CREATE; + + /** + * Document data. + * + * @var array Document data + */ + protected $_data = array(); + + /** + * Whether to use this document to upsert if the document does not exist. + * + * @var bool + */ + protected $_docAsUpsert = false; + + /** + * @var bool + */ + protected $_autoPopulate = false; + + /** + * Creates a new document. + * + * @param int|string $id OPTIONAL $id Id is create if empty + * @param array|string $data OPTIONAL Data array + * @param string $type OPTIONAL Type name + * @param string $index OPTIONAL Index name + */ + public function __construct($id = '', $data = array(), $type = '', $index = '') + { + $this->setId($id); + $this->setData($data); + $this->setType($type); + $this->setIndex($index); + } + + /** + * @param string $key + * + * @return mixed + */ + public function __get($key) + { + return $this->get($key); + } + + /** + * @param string $key + * @param mixed $value + */ + public function __set($key, $value) + { + $this->set($key, $value); + } + + /** + * @param string $key + * + * @return bool + */ + public function __isset($key) + { + return $this->has($key) && null !== $this->get($key); + } + + /** + * @param string $key + */ + public function __unset($key) + { + $this->remove($key); + } + + /** + * @param string $key + * + * @throws \Elastica\Exception\InvalidException + * + * @return mixed + */ + public function get($key) + { + if (!$this->has($key)) { + throw new InvalidException("Field {$key} does not exist"); + } + + return $this->_data[$key]; + } + + /** + * @param string $key + * @param mixed $value + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function set($key, $value) + { + if (!is_array($this->_data)) { + throw new InvalidException('Document data is serialized data. Data creation is forbidden.'); + } + $this->_data[$key] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return bool + */ + public function has($key) + { + return is_array($this->_data) && array_key_exists($key, $this->_data); + } + + /** + * @param string $key + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function remove($key) + { + if (!$this->has($key)) { + throw new InvalidException("Field {$key} does not exist"); + } + unset($this->_data[$key]); + + return $this; + } + + /** + * Adds the given key/value pair to the document. + * + * @deprecated + * + * @param string $key Document entry key + * @param mixed $value Document entry value + * + * @return $this + */ + public function add($key, $value) + { + return $this->set($key, $value); + } + + /** + * Adds a file to the index. + * + * To use this feature you have to call the following command in the + * elasticsearch directory: + * <code> + * ./bin/plugin -install elasticsearch/elasticsearch-mapper-attachments/1.6.0 + * </code> + * This installs the tika file analysis plugin. More infos about supported formats + * can be found here: {@link http://tika.apache.org/0.7/formats.html} + * + * @param string $key Key to add the file to + * @param string $filepath Path to add the file + * @param string $mimeType OPTIONAL Header mime type + * + * @return $this + */ + public function addFile($key, $filepath, $mimeType = '') + { + $value = base64_encode(file_get_contents($filepath)); + + if (!empty($mimeType)) { + $value = array('_content_type' => $mimeType, '_name' => $filepath, '_content' => $value); + } + + $this->set($key, $value); + + return $this; + } + + /** + * Add file content. + * + * @param string $key Document key + * @param string $content Raw file content + * + * @return $this + */ + public function addFileContent($key, $content) + { + return $this->set($key, base64_encode($content)); + } + + /** + * Adds a geopoint to the document. + * + * Geohashes are not yet supported + * + * @param string $key Field key + * @param float $latitude Latitude value + * @param float $longitude Longitude value + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-geo-point-type.html + * + * @return $this + */ + public function addGeoPoint($key, $latitude, $longitude) + { + $value = array('lat' => $latitude, 'lon' => $longitude); + + $this->set($key, $value); + + return $this; + } + + /** + * Overwrites the current document data with the given data. + * + * @param array|string $data Data array + * + * @return $this + */ + public function setData($data) + { + $this->_data = $data; + + return $this; + } + + /** + * Returns the document data. + * + * @return array|string Document data + */ + public function getData() + { + return $this->_data; + } + + /** + * @deprecated + * + * @param \Elastica\Script $data + * + * @throws NotImplementedException + */ + public function setScript($data) + { + throw new NotImplementedException('setScript() is no longer available as of 0.90.2. See http://elastica.io/migration/0.90.2/upsert.html to migrate'); + } + + /** + * @throws NotImplementedException + * + * @deprecated + */ + public function getScript() + { + throw new NotImplementedException('getScript() is no longer available as of 0.90.2. See http://elastica.io/migration/0.90.2/upsert.html to migrate'); + } + + /** + * @throws NotImplementedException + * + * @deprecated + */ + public function hasScript() + { + throw new NotImplementedException('hasScript() is no longer available as of 0.90.2. See http://elastica.io/migration/0.90.2/upsert.html to migrate'); + } + + /** + * @param bool $value + * + * @return $this + */ + public function setDocAsUpsert($value) + { + $this->_docAsUpsert = (bool) $value; + + return $this; + } + + /** + * @return bool + */ + public function getDocAsUpsert() + { + return $this->_docAsUpsert; + } + + /** + * @param bool $autoPopulate + * + * @return $this + */ + public function setAutoPopulate($autoPopulate = true) + { + $this->_autoPopulate = (bool) $autoPopulate; + + return $this; + } + + /** + * @return bool + */ + public function isAutoPopulate() + { + return $this->_autoPopulate; + } + + /** + * Returns the document as an array. + * + * @return array + */ + public function toArray() + { + $doc = $this->getParams(); + $doc['_source'] = $this->getData(); + + return $doc; + } + + /** + * @param array|\Elastica\Document $data + * + * @throws \Elastica\Exception\InvalidException + * + * @return self + */ + public static function create($data) + { + if ($data instanceof self) { + return $data; + } elseif (is_array($data)) { + return new self('', $data); + } else { + throw new InvalidException('Failed to create document. Invalid data passed.'); + } + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/Response/ActionException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/Response/ActionException.php new file mode 100644 index 00000000..5db0e49f --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/Response/ActionException.php @@ -0,0 +1,65 @@ +<?php +namespace Elastica\Exception\Bulk\Response; + +use Elastica\Bulk\Response; +use Elastica\Exception\BulkException; + +class ActionException extends BulkException +{ + /** + * @var \Elastica\Response + */ + protected $_response; + + /** + * @param \Elastica\Bulk\Response $response + */ + public function __construct(Response $response) + { + $this->_response = $response; + + parent::__construct($this->getErrorMessage($response)); + } + + /** + * @return \Elastica\Bulk\Action + */ + public function getAction() + { + return $this->getResponse()->getAction(); + } + + /** + * @return \Elastica\Bulk\Response + */ + public function getResponse() + { + return $this->_response; + } + + /** + * @param \Elastica\Bulk\Response $response + * + * @return string + */ + public function getErrorMessage(Response $response) + { + $error = $response->getError(); + $opType = $response->getOpType(); + $data = $response->getData(); + + $path = ''; + if (isset($data['_index'])) { + $path .= '/'.$data['_index']; + } + if (isset($data['_type'])) { + $path .= '/'.$data['_type']; + } + if (isset($data['_id'])) { + $path .= '/'.$data['_id']; + } + $message = "$opType: $path caused $error"; + + return $message; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/ResponseException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/ResponseException.php new file mode 100644 index 00000000..54b5702b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/ResponseException.php @@ -0,0 +1,98 @@ +<?php +namespace Elastica\Exception\Bulk; + +use Elastica\Bulk\ResponseSet; +use Elastica\Exception\Bulk\Response\ActionException; +use Elastica\Exception\BulkException; + +/** + * Bulk Response exception. + */ +class ResponseException extends BulkException +{ + /** + * @var \Elastica\Bulk\ResponseSet ResponseSet object + */ + protected $_responseSet; + + /** + * @var \Elastica\Exception\Bulk\Response\ActionException[] + */ + protected $_actionExceptions = array(); + + /** + * Construct Exception. + * + * @param \Elastica\Bulk\ResponseSet $responseSet + */ + public function __construct(ResponseSet $responseSet) + { + $this->_init($responseSet); + + $message = 'Error in one or more bulk request actions:'.PHP_EOL.PHP_EOL; + $message .= $this->getActionExceptionsAsString(); + + parent::__construct($message); + } + + /** + * @param \Elastica\Bulk\ResponseSet $responseSet + */ + protected function _init(ResponseSet $responseSet) + { + $this->_responseSet = $responseSet; + + foreach ($responseSet->getBulkResponses() as $bulkResponse) { + if ($bulkResponse->hasError()) { + $this->_actionExceptions[] = new ActionException($bulkResponse); + } + } + } + + /** + * Returns bulk response set object. + * + * @return \Elastica\Bulk\ResponseSet + */ + public function getResponseSet() + { + return $this->_responseSet; + } + + /** + * Returns array of failed actions. + * + * @return array Array of failed actions + */ + public function getFailures() + { + $errors = array(); + + foreach ($this->getActionExceptions() as $actionException) { + $errors[] = $actionException->getMessage(); + } + + return $errors; + } + + /** + * @return \Elastica\Exception\Bulk\Response\ActionException[] + */ + public function getActionExceptions() + { + return $this->_actionExceptions; + } + + /** + * @return string + */ + public function getActionExceptionsAsString() + { + $message = ''; + foreach ($this->getActionExceptions() as $actionException) { + $message .= $actionException->getMessage().PHP_EOL; + } + + return $message; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/UdpException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/UdpException.php new file mode 100644 index 00000000..e332b92f --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/UdpException.php @@ -0,0 +1,8 @@ +<?php +namespace Elastica\Exception\Bulk; + +use Elastica\Exception\BulkException; + +class UdpException extends BulkException +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/BulkException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/BulkException.php new file mode 100644 index 00000000..121cf557 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/BulkException.php @@ -0,0 +1,6 @@ +<?php +namespace Elastica\Exception; + +class BulkException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/ClientException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/ClientException.php new file mode 100644 index 00000000..66af363d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/ClientException.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Exception; + +/** + * Client exception. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class ClientException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/GuzzleException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/GuzzleException.php new file mode 100644 index 00000000..614ad139 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/GuzzleException.php @@ -0,0 +1,50 @@ +<?php +namespace Elastica\Exception\Connection; + +use Elastica\Exception\ConnectionException; +use Elastica\Request; +use Elastica\Response; +use GuzzleHttp\Exception\TransferException; + +/** + * Transport exception. + * + * @author Milan Magudia <milan@magudia.com> + */ +class GuzzleException extends ConnectionException +{ + /** + * @var TransferException + */ + protected $_guzzleException; + + /** + * @param \GuzzleHttp\Exception\TransferException $guzzleException + * @param \Elastica\Request $request + * @param \Elastica\Response $response + */ + public function __construct(TransferException $guzzleException, Request $request = null, Response $response = null) + { + $this->_guzzleException = $guzzleException; + $message = $this->getErrorMessage($this->getGuzzleException()); + parent::__construct($message, $request, $response); + } + + /** + * @param \GuzzleHttp\Exception\TransferException $guzzleException + * + * @return string + */ + public function getErrorMessage(TransferException $guzzleException) + { + return $guzzleException->getMessage(); + } + + /** + * @return TransferException + */ + public function getGuzzleException() + { + return $this->_guzzleException; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/HttpException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/HttpException.php new file mode 100644 index 00000000..28e78e77 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/HttpException.php @@ -0,0 +1,86 @@ +<?php +namespace Elastica\Exception\Connection; + +use Elastica\Exception\ConnectionException; +use Elastica\Request; +use Elastica\Response; + +/** + * Connection exception. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class HttpException extends ConnectionException +{ + /** + * Error code / message. + * + * @var string Error code / message + */ + protected $_error = 0; + + /** + * Construct Exception. + * + * @param string $error Error + * @param \Elastica\Request $request + * @param \Elastica\Response $response + */ + public function __construct($error, Request $request = null, Response $response = null) + { + $this->_error = $error; + + $message = $this->getErrorMessage($this->getError()); + parent::__construct($message, $request, $response); + } + + /** + * Returns the error message corresponding to the error code + * cUrl error code reference can be found here {@link http://curl.haxx.se/libcurl/c/libcurl-errors.html}. + * + * @param string $error Error code + * + * @return string Error message + */ + public function getErrorMessage($error) + { + switch ($error) { + case CURLE_UNSUPPORTED_PROTOCOL: + $error = 'Unsupported protocol'; + break; + case CURLE_FAILED_INIT: + $error = 'Internal cUrl error?'; + break; + case CURLE_URL_MALFORMAT: + $error = 'Malformed URL'; + break; + case CURLE_COULDNT_RESOLVE_PROXY: + $error = "Couldn't resolve proxy"; + break; + case CURLE_COULDNT_RESOLVE_HOST: + $error = "Couldn't resolve host"; + break; + case CURLE_COULDNT_CONNECT: + $error = "Couldn't connect to host, Elasticsearch down?"; + break; + case 28: + $error = 'Operation timed out'; + break; + default: + $error = 'Unknown error:'.$error; + break; + } + + return $error; + } + + /** + * Return Error code / message. + * + * @return string Error code / message + */ + public function getError() + { + return $this->_error; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/MemcacheException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/MemcacheException.php new file mode 100644 index 00000000..24181379 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/MemcacheException.php @@ -0,0 +1,13 @@ +<?php +namespace Elastica\Exception\Connection; + +use Elastica\Exception\ConnectionException; + +/** + * Transport exception. + * + * @author Igor Denisenko <im.denisenko@yahoo.com> + */ +class MemcacheException extends ConnectionException +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/ThriftException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/ThriftException.php new file mode 100644 index 00000000..499cbd7d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/Connection/ThriftException.php @@ -0,0 +1,49 @@ +<?php +namespace Elastica\Exception\Connection; + +use Elastica\Exception\ConnectionException; +use Elastica\Request; +use Elastica\Response; +use Thrift\Exception\TException; + +/** + * Transport exception. + * + * @author Mikhail Shamin <munk13@gmail.com> + */ +class ThriftException extends ConnectionException +{ + /** + * @var TException + */ + protected $_thriftException; + + /** + * @param \Thrift\Exception\TException $thriftException + * @param \Elastica\Request $request + * @param \Elastica\Response $response + */ + public function __construct(TException $thriftException, Request $request = null, Response $response = null) + { + $this->_thriftException = $thriftException; + $message = $this->getErrorMessage($this->getThriftException()); + parent::__construct($message, $request, $response); + } + + /** + * @param \Thrift\Exception\TException $thriftException + * + * @return string + */ + public function getErrorMessage(TException $thriftException) + { + return $thriftException->getMessage(); + } + /** + * @return TException + */ + public function getThriftException() + { + return $this->_thriftException; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/ConnectionException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/ConnectionException.php new file mode 100644 index 00000000..b2376d2f --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/ConnectionException.php @@ -0,0 +1,58 @@ +<?php +namespace Elastica\Exception; + +use Elastica\Request; +use Elastica\Response; + +/** + * Connection exception. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class ConnectionException extends \RuntimeException implements ExceptionInterface +{ + /** + * @var \Elastica\Request Request object + */ + protected $_request; + + /** + * @var \Elastica\Response Response object + */ + protected $_response; + + /** + * Construct Exception. + * + * @param string $message Message + * @param \Elastica\Request $request + * @param \Elastica\Response $response + */ + public function __construct($message, Request $request = null, Response $response = null) + { + $this->_request = $request; + $this->_response = $response; + + parent::__construct($message); + } + + /** + * Returns request object. + * + * @return \Elastica\Request Request object + */ + public function getRequest() + { + return $this->_request; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/ElasticsearchException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/ElasticsearchException.php new file mode 100644 index 00000000..59cca0c6 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/ElasticsearchException.php @@ -0,0 +1,91 @@ +<?php +namespace Elastica\Exception; + +/** + * Elasticsearch exception. + * + * @author Ian Babrou <ibobrik@gmail.com> + */ +class ElasticsearchException extends \Exception implements ExceptionInterface +{ + const REMOTE_TRANSPORT_EXCEPTION = 'RemoteTransportException'; + + /** + * @var string|null Elasticsearch exception name + */ + private $_exception; + + /** + * @var bool Whether exception was local to server node or remote + */ + private $_isRemote = false; + + /** + * Constructs elasticsearch exception. + * + * @param int $code Error code + * @param string $error Error message from elasticsearch + */ + public function __construct($code, $error) + { + $this->_parseError($error); + parent::__construct($error, $code); + } + + /** + * Parse error message from elasticsearch. + * + * @param string $error Error message + */ + protected function _parseError($error) + { + $errors = explode(']; nested: ', $error); + + if (count($errors) == 1) { + $this->_exception = $this->_extractException($errors[0]); + } else { + if ($this->_extractException($errors[0]) == self::REMOTE_TRANSPORT_EXCEPTION) { + $this->_isRemote = true; + $this->_exception = $this->_extractException($errors[1]); + } else { + $this->_exception = $this->_extractException($errors[0]); + } + } + } + + /** + * Extract exception name from error response. + * + * @param string $error + * + * @return null|string + */ + protected function _extractException($error) + { + if (preg_match('/^(\w+)\[.*\]/', $error, $matches)) { + return $matches[1]; + } else { + return; + } + } + + /** + * Returns elasticsearch exception name. + * + * @return string|null + */ + public function getExceptionName() + { + return $this->_exception; + } + + /** + * Returns whether exception was local to server node or remote. + * + * @return bool + */ + public function isRemoteTransportException() + { + return $this->_isRemote; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/ExceptionInterface.php b/vendor/ruflin/elastica/lib/Elastica/Exception/ExceptionInterface.php new file mode 100644 index 00000000..02f43092 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/ExceptionInterface.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Exception; + +/** + * General Elastica exception interface. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +interface ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/InvalidException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/InvalidException.php new file mode 100644 index 00000000..996a9389 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/InvalidException.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Exception; + +/** + * Invalid exception. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class InvalidException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/JSONParseException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/JSONParseException.php new file mode 100644 index 00000000..010adf45 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/JSONParseException.php @@ -0,0 +1,9 @@ +<?php +namespace Elastica\Exception; + +/** + * JSON Parse exception. + */ +class JSONParseException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/NotFoundException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/NotFoundException.php new file mode 100644 index 00000000..a2897fd7 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/NotFoundException.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Exception; + +/** + * Not found exception. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class NotFoundException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/NotImplementedException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/NotImplementedException.php new file mode 100644 index 00000000..591417b6 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/NotImplementedException.php @@ -0,0 +1,13 @@ +<?php +namespace Elastica\Exception; + +/** + * Not implemented exception. + * + * Is thrown if a function or feature is not implemented yet + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class NotImplementedException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/PartialShardFailureException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/PartialShardFailureException.php new file mode 100644 index 00000000..bb3fa44a --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/PartialShardFailureException.php @@ -0,0 +1,28 @@ +<?php +namespace Elastica\Exception; + +use Elastica\JSON; +use Elastica\Request; +use Elastica\Response; + +/** + * Partial shard failure exception. + * + * @author Ian Babrou <ibobrik@gmail.com> + */ +class PartialShardFailureException extends ResponseException +{ + /** + * Construct Exception. + * + * @param \Elastica\Request $request + * @param \Elastica\Response $response + */ + public function __construct(Request $request, Response $response) + { + parent::__construct($request, $response); + + $shardsStatistics = $response->getShardsStatistics(); + $this->message = JSON::stringify($shardsStatistics['failed']); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/QueryBuilderException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/QueryBuilderException.php new file mode 100644 index 00000000..ae03c831 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/QueryBuilderException.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Exception; + +/** + * QueryBuilder exception. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class QueryBuilderException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/ResponseException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/ResponseException.php new file mode 100644 index 00000000..57502307 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/ResponseException.php @@ -0,0 +1,70 @@ +<?php +namespace Elastica\Exception; + +use Elastica\Request; +use Elastica\Response; + +/** + * Response exception. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class ResponseException extends \RuntimeException implements ExceptionInterface +{ + /** + * @var \Elastica\Request Request object + */ + protected $_request = null; + + /** + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Construct Exception. + * + * @param \Elastica\Request $request + * @param \Elastica\Response $response + */ + public function __construct(Request $request, Response $response) + { + $this->_request = $request; + $this->_response = $response; + parent::__construct($response->getError()); + } + + /** + * Returns request object. + * + * @return \Elastica\Request Request object + */ + public function getRequest() + { + return $this->_request; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Returns elasticsearch exception. + * + * @return ElasticsearchException + */ + public function getElasticsearchException() + { + $response = $this->getResponse(); + $transfer = $response->getTransferInfo(); + $code = array_key_exists('http_code', $transfer) ? $transfer['http_code'] : 0; + + return new ElasticsearchException($code, $response->getError()); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Exception/RuntimeException.php b/vendor/ruflin/elastica/lib/Elastica/Exception/RuntimeException.php new file mode 100644 index 00000000..af18faff --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Exception/RuntimeException.php @@ -0,0 +1,11 @@ +<?php +namespace Elastica\Exception; + +/** + * Client exception. + * + * @author Mikhail Shamin <munk13@gmail.com> + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/AbstractFacet.php b/vendor/ruflin/elastica/lib/Elastica/Facet/AbstractFacet.php new file mode 100644 index 00000000..743cefe1 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/AbstractFacet.php @@ -0,0 +1,145 @@ +<?php +namespace Elastica\Facet; + +use Elastica\Exception\InvalidException; +use Elastica\Filter\AbstractFilter; +use Elastica\Param; + +/** + * Abstract facet object. Should be extended by all facet types. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * @author Jasper van Wanrooy <jasper@vanwanrooy.net> + * + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +abstract class AbstractFacet extends Param +{ + /** + * @var string Holds the name of the facet. + */ + protected $_name = ''; + + /** + * @var array Holds all facet parameters. + */ + protected $_facet = array(); + + /** + * Constructs a Facet object. + * + * @param string $name The name of the facet. + */ + public function __construct($name) + { + $this->setName($name); + } + + /** + * Sets the name of the facet. It is automatically set by + * the constructor. + * + * @param string $name The name of the facet. + * + * @throws \Elastica\Exception\InvalidException If name is empty + * + * @return $this + */ + public function setName($name) + { + if (empty($name)) { + throw new InvalidException('Facet name has to be set'); + } + $this->_name = $name; + + return $this; + } + + /** + * Gets the name of the facet. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets a filter for this facet. + * + * @param \Elastica\Filter\AbstractFilter $filter A filter to apply on the facet. + * + * @return $this + */ + public function setFilter(AbstractFilter $filter) + { + return $this->_setFacetParam('facet_filter', $filter->toArray()); + } + + /** + * Sets the flag to either run the facet globally or bound to the + * current search query. When not set, it defaults to the + * Elasticsearch default value. + * + * @param bool $global Flag to either run the facet globally. + * + * @return $this + */ + public function setGlobal($global = true) + { + return $this->_setFacetParam('global', (bool) $global); + } + + /** + * Sets the path to the nested document. + * + * @param string $nestedPath Nested path + * + * @return $this + */ + public function setNested($nestedPath) + { + return $this->_setFacetParam('nested', $nestedPath); + } + + /** + * Sets the scope. + * + * @param string $scope Scope + * + * @return $this + */ + public function setScope($scope) + { + return $this->_setFacetParam('scope', $scope); + } + + /** + * Basic definition of all specs of the facet. Each implementation + * should override this function in order to set it's specific + * settings. + * + * @return array + */ + public function toArray() + { + return $this->_facet; + } + + /** + * Sets a param for the facet. Each facet implementation needs to take + * care of handling their own params. + * + * @param string $key The key of the param to set. + * @param mixed $value The value of the param. + * + * @return $this + */ + protected function _setFacetParam($key, $value) + { + $this->_facet[$key] = $value; + + return $this; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/DateHistogram.php b/vendor/ruflin/elastica/lib/Elastica/Facet/DateHistogram.php new file mode 100644 index 00000000..c47eddab --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/DateHistogram.php @@ -0,0 +1,58 @@ +<?php +namespace Elastica\Facet; + +/** + * Implements the Date Histogram facet. + * + * @author Raul Martinez Jr <juneym@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-date-histogram-facet.html + * @link https://github.com/elasticsearch/elasticsearch/issues/591 + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class DateHistogram extends Histogram +{ + /** + * Set the time_zone parameter. + * + * @param string $tzOffset + * + * @return $this + */ + public function setTimezone($tzOffset) + { + return $this->setParam('time_zone', $tzOffset); + } + + /** + * Set the factor parameter. + * + * @param int $factor + * + * @return $this + */ + public function setFactor($factor) + { + return $this->setParam('factor', $factor); + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @throws \Elastica\Exception\InvalidException When the right fields haven't been set. + * + * @return array + */ + public function toArray() + { + /* + * Set the range in the abstract as param. + */ + $this->_setFacetParam('date_histogram', $this->_params); + + return $this->_facet; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/Filter.php b/vendor/ruflin/elastica/lib/Elastica/Facet/Filter.php new file mode 100644 index 00000000..26f032b4 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/Filter.php @@ -0,0 +1,27 @@ +<?php +namespace Elastica\Facet; + +use Elastica\Filter\AbstractFilter; + +/** + * Filter facet. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-filter-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class Filter extends AbstractFacet +{ + /** + * Set the filter for the facet. + * + * @param \Elastica\Filter\AbstractFilter $filter + * + * @return $this + */ + public function setFilter(AbstractFilter $filter) + { + return $this->_setFacetParam('filter', $filter->toArray()); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/GeoCluster.php b/vendor/ruflin/elastica/lib/Elastica/Facet/GeoCluster.php new file mode 100644 index 00000000..71fa5094 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/GeoCluster.php @@ -0,0 +1,66 @@ +<?php +namespace Elastica\Facet; + +/** + * Implements the Geo Cluster facet. + * + * @author Konstantin Nikiforov <konstantin.nikiforov@gmail.com> + * + * @link https://github.com/zenobase/geocluster-facet + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class GeoCluster extends AbstractFacet +{ + /** + * @param string $fieldName + * + * @return $this + */ + public function setField($fieldName) + { + $this->setParam('field', $fieldName); + + return $this; + } + + /** + * @param float $factor + * + * @return $this + */ + public function setFactor($factor) + { + $this->setParam('factor', $factor); + + return $this; + } + + /** + * @param bool $showIds + * + * @return $this + */ + public function setShowIds($showIds) + { + $this->setParam('showIds', $showIds); + + return $this; + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @throws \Elastica\Exception\InvalidException When the right fields haven't been set. + * + * @return array + */ + public function toArray() + { + $this->_setFacetParam('geo_cluster', $this->_params); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/GeoDistance.php b/vendor/ruflin/elastica/lib/Elastica/Facet/GeoDistance.php new file mode 100644 index 00000000..664d33a6 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/GeoDistance.php @@ -0,0 +1,69 @@ +<?php +namespace Elastica\Facet; + +/** + * Implements the Geo Distance facet. + * + * @author Gerard A. Matthew <gerard.matthew@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-geo-distance-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class GeoDistance extends AbstractFacet +{ + /** + * Sets the ranges for the facet all at once. + * Sample ranges: + * array ( + * array('to' => 50), + * array('from' => 20, 'to' => 70), + * array('from' => 70, 'to' => 120), + * array('from' => 150) + * ). + * + * @param array $ranges Numerical array with range definitions. + * + * @return $this + */ + public function setRanges(array $ranges) + { + return $this->setParam('ranges', $ranges); + } + + /** + * Set the relative GeoPoint for the facet. + * + * @param string $typeField index type and field e.g foo.bar + * @param float $latitude + * @param float $longitude + * + * @return $this + */ + public function setGeoPoint($typeField, $latitude, $longitude) + { + return $this->setParam($typeField, array( + 'lat' => $latitude, + 'lon' => $longitude, + )); + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @throws \Elastica\Exception\InvalidException When the right fields haven't been set. + * + * @return array + */ + public function toArray() + { + /* + * Set the geo_distance in the abstract as param. + */ + $this->_setFacetParam('geo_distance', $this->_params); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/Histogram.php b/vendor/ruflin/elastica/lib/Elastica/Facet/Histogram.php new file mode 100644 index 00000000..1b76ea89 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/Histogram.php @@ -0,0 +1,96 @@ +<?php +namespace Elastica\Facet; + +/** + * Implements the Histogram facet. + * + * @author Raul Martinez Jr <juneym@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-histogram-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class Histogram extends AbstractFacet +{ + /** + * Sets the field for histogram. + * + * @param string $field The name of the field for the histogram + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Set the value for interval. + * + * @param string $interval + * + * @return $this + */ + public function setInterval($interval) + { + return $this->setParam('interval', $interval); + } + + /** + * Set the fields for key_field and value_field. + * + * @param string $keyField Key field + * @param string $valueField Value field + * + * @return $this + */ + public function setKeyValueFields($keyField, $valueField) + { + return $this->setParam('key_field', $keyField)->setParam('value_field', $valueField); + } + + /** + * Sets the key and value for this facet by script. + * + * @param string $keyScript Script to check whether it falls into the range. + * @param string $valueScript Script to use for statistical calculations. + * + * @return $this + */ + public function setKeyValueScripts($keyScript, $valueScript) + { + return $this->setParam('key_script', $keyScript) + ->setParam('value_script', $valueScript); + } + + /** + * Set the "params" essential to the a script. + * + * @param array $params Associative array (key/value pair) + * + * @return $this + */ + public function setScriptParams(array $params) + { + return $this->setParam('params', $params); + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @throws \Elastica\Exception\InvalidException When the right fields haven't been set. + * + * @return array + */ + public function toArray() + { + /* + * Set the range in the abstract as param. + */ + $this->_setFacetParam('histogram', $this->_params); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/Query.php b/vendor/ruflin/elastica/lib/Elastica/Facet/Query.php new file mode 100644 index 00000000..522090d5 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/Query.php @@ -0,0 +1,27 @@ +<?php +namespace Elastica\Facet; + +use Elastica\Query\AbstractQuery; + +/** + * Query facet. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-query-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class Query extends AbstractFacet +{ + /** + * Set the query for the facet. + * + * @param \Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery(AbstractQuery $query) + { + return $this->_setFacetParam('query', $query->toArray()); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/Range.php b/vendor/ruflin/elastica/lib/Elastica/Facet/Range.php new file mode 100644 index 00000000..f81caf3d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/Range.php @@ -0,0 +1,143 @@ +<?php +namespace Elastica\Facet; + +use Elastica\Exception\InvalidException; + +/** + * Implements the range facet. + * + * @author Jasper van Wanrooy <jasper@vanwanrooy.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-range-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class Range extends AbstractFacet +{ + /** + * Sets the field for the range. + * + * @param string $field The name of the field for range. + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Sets the fields by their separate key and value fields. + * + * @param string $keyField The key_field param for the range. + * @param string $valueField The key_value param for the range. + * + * @return $this + */ + public function setKeyValueFields($keyField, $valueField) + { + return $this->setParam('key_field', $keyField) + ->setParam('value_field', $valueField); + } + + /** + * Sets the key and value for this facet by script. + * + * @param string $keyScript Script to check whether it falls into the range. + * @param string $valueScript Script to use for statistical calculations. + * + * @return $this + */ + public function setKeyValueScripts($keyScript, $valueScript) + { + return $this->setParam('key_script', $keyScript) + ->setParam('value_script', $valueScript); + } + + /** + * Sets the ranges for the facet all at once. Sample ranges: + * array ( + * array('to' => 50), + * array('from' => 20, 'to' 70), + * array('from' => 70, 'to' => 120), + * array('from' => 150) + * ). + * + * @param array $ranges Numerical array with range definitions. + * + * @return $this + */ + public function setRanges(array $ranges) + { + return $this->setParam('ranges', $ranges); + } + + /** + * Adds a range to the range facet. + * + * @param mixed $from The from for the range. + * @param mixed $to The to for the range. + * + * @return $this + */ + public function addRange($from = null, $to = null) + { + if (!isset($this->_params['ranges']) || !is_array($this->_params['ranges'])) { + $this->_params['ranges'] = array(); + } + + $range = array(); + if (isset($from)) { + $range['from'] = $from; + } + if (isset($to)) { + $range['to'] = $to; + } + $this->_params['ranges'][] = $range; + + return $this; + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @throws \Elastica\Exception\InvalidException When the right fields haven't been set. + * + * @return array + */ + public function toArray() + { + /* + * Check the facet for validity. + * There are three ways to set the key and value field for the range: + * - a single field for both key and value; or + * - separate fields for key and value; or + * - separate scripts for key and value. + */ + $fieldTypesSet = 0; + if (isset($this->_params['field'])) { + $fieldTypesSet++; + } + if (isset($this->_params['key_field'])) { + $fieldTypesSet++; + } + if (isset($this->_params['key_script'])) { + $fieldTypesSet++; + } + + if ($fieldTypesSet === 0) { + throw new InvalidException('Neither field, key_field nor key_script is set.'); + } elseif ($fieldTypesSet > 1) { + throw new InvalidException('Either field, key_field and key_value or key_script and value_script should be set.'); + } + + /* + * Set the range in the abstract as param. + */ + $this->_setFacetParam('range', $this->_params); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/Statistical.php b/vendor/ruflin/elastica/lib/Elastica/Facet/Statistical.php new file mode 100644 index 00000000..bb4eef8b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/Statistical.php @@ -0,0 +1,64 @@ +<?php +namespace Elastica\Facet; + +/** + * Implements the statistical facet. + * + * @author Robert Katzki <robert@katzki.de> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-statistical-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class Statistical extends AbstractFacet +{ + /** + * Sets the field for the statistical query. + * + * @param string $field The field name for the statistical query. + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Sets multiple fields for the statistical query. + * + * @param array $fields Numerical array with the fields for the statistical query. + * + * @return $this + */ + public function setFields(array $fields) + { + return $this->setParam('fields', $fields); + } + + /** + * Sets a script to calculate statistical information. + * + * @param string $script The script to do calculations on the statistical values + * + * @return $this + */ + public function setScript($script) + { + return $this->setParam('script', $script); + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @return array + */ + public function toArray() + { + $this->_setFacetParam('statistical', $this->_params); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/Terms.php b/vendor/ruflin/elastica/lib/Elastica/Facet/Terms.php new file mode 100644 index 00000000..6af8867b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/Terms.php @@ -0,0 +1,137 @@ +<?php +namespace Elastica\Facet; + +use Elastica\Exception\InvalidException; +use Elastica\Script; + +/** + * Implements the terms facet. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * @author Jasper van Wanrooy <jasper@vanwanrooy.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-terms-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class Terms extends AbstractFacet +{ + /** + * Holds the types of ordering which are allowed + * by Elasticsearch. + * + * @var array + */ + protected $_orderTypes = array('count', 'term', 'reverse_count', 'reverse_term'); + + /** + * Sets the field for the terms. + * + * @param string $field The field name for the terms. + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Sets the script for the term. + * + * @param string $script The script for the term. + * + * @return $this + */ + public function setScript($script) + { + $script = Script::create($script); + foreach ($script->toArray() as $param => $value) { + $this->setParam($param, $value); + } + + return $this; + } + + /** + * Sets multiple fields for the terms. + * + * @param array $fields Numerical array with the fields for the terms. + * + * @return $this + */ + public function setFields(array $fields) + { + return $this->setParam('fields', $fields); + } + + /** + * Sets the flag to return all available terms. When they + * don't have a hit, they have a count of zero. + * + * @param bool $allTerms Flag to fetch all terms. + * + * @return $this + */ + public function setAllTerms($allTerms) + { + return $this->setParam('all_terms', (bool) $allTerms); + } + + /** + * Sets the ordering type for this facet. Elasticsearch + * internal default is count. + * + * @param string $type The order type to set use for sorting of the terms. + * + * @throws \Elastica\Exception\InvalidException When an invalid order type was set. + * + * @return $this + */ + public function setOrder($type) + { + if (!in_array($type, $this->_orderTypes)) { + throw new InvalidException('Invalid order type: '.$type); + } + + return $this->setParam('order', $type); + } + + /** + * Set an array with terms which are omitted in the search. + * + * @param array $exclude Numerical array which includes all terms which needs to be ignored. + * + * @return $this + */ + public function setExclude(array $exclude) + { + return $this->setParam('exclude', $exclude); + } + + /** + * Sets the amount of terms to be returned. + * + * @param int $size The amount of terms to be returned. + * + * @return $this + */ + public function setSize($size) + { + return $this->setParam('size', (int) $size); + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @return array + */ + public function toArray() + { + $this->_setFacetParam('terms', $this->_params); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Facet/TermsStats.php b/vendor/ruflin/elastica/lib/Elastica/Facet/TermsStats.php new file mode 100644 index 00000000..22d284c5 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Facet/TermsStats.php @@ -0,0 +1,107 @@ +<?php +namespace Elastica\Facet; + +use Elastica\Exception\InvalidException; + +/** + * Implements the statistical facet on a per term basis. + * + * @author Tom Michaelis <tom.michaelis@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets-terms-stats-facet.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ +class TermsStats extends AbstractFacet +{ + /** + * Holds the types of ordering which are allowed + * by Elasticsearch. + * + * @var array + */ + protected $_orderTypes = array('term', 'reverse_term', 'count', 'reverse_count', + 'total', 'reverse_total', 'min', 'reverse_min', 'max', 'reverse_max', 'mean', + 'reverse_mean', ); + + /** + * Sets the key field for the query. + * + * @param string $keyField The key field name for the query. + * + * @return $this + */ + public function setKeyField($keyField) + { + return $this->setParam('key_field', $keyField); + } + + /** + * Sets a script to calculate statistical information on a per term basis. + * + * @param string $valueScript The script to do calculations on the statistical values + * + * @return $this + */ + public function setValueScript($valueScript) + { + return $this->setParam('value_script', $valueScript); + } + + /** + * Sets the ordering type for this facet. Elasticsearch + * internal default is count. + * + * @param string $type The order type to set use for sorting of the terms. + * + * @throws \Elastica\Exception\InvalidException When an invalid order type was set. + * + * @return $this + */ + public function setOrder($type) + { + if (!in_array($type, $this->_orderTypes)) { + throw new InvalidException('Invalid order type: '.$type); + } + + return $this->setParam('order', $type); + } + + /** + * Sets a field to compute basic statistical results on. + * + * @param string $valueField The field to compute statistical values for + * + * @return $this + */ + public function setValueField($valueField) + { + return $this->setParam('value_field', $valueField); + } + + /** + * Sets the amount of terms to be returned. + * + * @param int $size The amount of terms to be returned. + * + * @return $this + */ + public function setSize($size) + { + return $this->setParam('size', (int) $size); + } + + /** + * Creates the full facet definition, which includes the basic + * facet definition of the parent. + * + * @see \Elastica\Facet\AbstractFacet::toArray() + * + * @return array + */ + public function toArray() + { + $this->_setFacetParam('terms_stats', $this->_params); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractFilter.php b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractFilter.php new file mode 100644 index 00000000..7c7dc4f7 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractFilter.php @@ -0,0 +1,59 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Exception\InvalidException; +use Elastica\Param; + +/** + * Abstract filter object. Should be extended by all filter types. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filters.html + */ +abstract class AbstractFilter extends Param +{ + /** + * Sets the filter cache. + * + * @param bool $cached Cached + * + * @return $this + */ + public function setCached($cached = true) + { + return $this->setParam('_cache', (bool) $cached); + } + + /** + * Sets the filter cache key. + * + * @param string $cacheKey Cache key + * + * @throws \Elastica\Exception\InvalidException If given key is empty + * + * @return $this + */ + public function setCacheKey($cacheKey) + { + $cacheKey = (string) $cacheKey; + + if (empty($cacheKey)) { + throw new InvalidException('Invalid parameter. Has to be a non empty string'); + } + + return $this->setParam('_cache_key', (string) $cacheKey); + } + + /** + * Sets the filter name. + * + * @param string $name Name + * + * @return $this + */ + public function setName($name) + { + return $this->setParam('_name', $name); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoDistance.php b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoDistance.php new file mode 100644 index 00000000..b208afb4 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoDistance.php @@ -0,0 +1,198 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Exception\InvalidException; + +/** + * Geo distance filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html + */ +abstract class AbstractGeoDistance extends AbstractFilter +{ + const LOCATION_TYPE_GEOHASH = 'geohash'; + const LOCATION_TYPE_LATLON = 'latlon'; + + /** + * Location type. + * + * Decides if this filter uses latitude/longitude or geohash for the location. + * Values are "latlon" or "geohash". + * + * @var string + */ + protected $_locationType = null; + + /** + * Key. + * + * @var string + */ + protected $_key = null; + + /** + * Latitude. + * + * @var float + */ + protected $_latitude = null; + + /** + * Longitude. + * + * @var float + */ + protected $_longitude = null; + + /** + * Geohash. + * + * @var string + */ + protected $_geohash = null; + + /** + * Create GeoDistance object. + * + * @param string $key Key + * @param array|string $location Location as array or geohash: array('lat' => 48.86, 'lon' => 2.35) OR 'drm3btev3e86' + * + * @internal param string $distance Distance + */ + public function __construct($key, $location) + { + // Key + $this->setKey($key); + $this->setLocation($location); + } + + /** + * @param string $key + * + * @return $this + */ + public function setKey($key) + { + $this->_key = $key; + + return $this; + } + + /** + * @param array|string $location + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function setLocation($location) + { + // Location + if (is_array($location)) { // Latitude/Longitude + // Latitude + if (isset($location['lat'])) { + $this->setLatitude($location['lat']); + } else { + throw new InvalidException('$location[\'lat\'] has to be set'); + } + + // Longitude + if (isset($location['lon'])) { + $this->setLongitude($location['lon']); + } else { + throw new InvalidException('$location[\'lon\'] has to be set'); + } + } elseif (is_string($location)) { // Geohash + $this->setGeohash($location); + } else { // Invalid location + throw new InvalidException('$location has to be an array (latitude/longitude) or a string (geohash)'); + } + + return $this; + } + + /** + * @param float $latitude + * + * @return $this + */ + public function setLatitude($latitude) + { + $this->_latitude = (float) $latitude; + $this->_locationType = self::LOCATION_TYPE_LATLON; + + return $this; + } + + /** + * @param float $longitude + * + * @return $this + */ + public function setLongitude($longitude) + { + $this->_longitude = (float) $longitude; + $this->_locationType = self::LOCATION_TYPE_LATLON; + + return $this; + } + + /** + * @param string $geohash + * + * @return $this + */ + public function setGeohash($geohash) + { + $this->_geohash = $geohash; + $this->_locationType = self::LOCATION_TYPE_GEOHASH; + + return $this; + } + + /** + * @throws \Elastica\Exception\InvalidException + * + * @return array|string + */ + protected function _getLocationData() + { + if ($this->_locationType === self::LOCATION_TYPE_LATLON) { // Latitude/longitude + $location = array(); + + if (isset($this->_latitude)) { // Latitude + $location['lat'] = $this->_latitude; + } else { + throw new InvalidException('Latitude has to be set'); + } + + if (isset($this->_longitude)) { // Geohash + $location['lon'] = $this->_longitude; + } else { + throw new InvalidException('Longitude has to be set'); + } + } elseif ($this->_locationType === self::LOCATION_TYPE_GEOHASH) { // Geohash + $location = $this->_geohash; + } else { // Invalid location type + throw new InvalidException('Invalid location type'); + } + + return $location; + } + + /** + * @see \Elastica\Param::toArray() + * + * @throws \Elastica\Exception\InvalidException + * + * @return array + */ + public function toArray() + { + $this->setParam($this->_key, $this->_getLocationData()); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoShape.php b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoShape.php new file mode 100644 index 00000000..4f5c0f93 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoShape.php @@ -0,0 +1,52 @@ +<?php +namespace Elastica\Filter; + +/** + * geo_shape filter. + * + * Filter pre-indexed shape definitions + * + * @author Bennie Krijger <benniekrijger@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html + */ +abstract class AbstractGeoShape extends AbstractFilter +{ + const RELATION_INTERSECT = 'intersects'; + const RELATION_DISJOINT = 'disjoint'; + const RELATION_CONTAINS = 'within'; + + /** + * @var string + * + * elasticsearch path of the pre-indexed shape + */ + protected $_path; + + /** + * @var string + * + * the relation of the 2 shaped: intersects, disjoint, within + */ + protected $_relation = self::RELATION_INTERSECT; + + /** + * @param string $relation + * + * @return $this + */ + public function setRelation($relation) + { + $this->_relation = $relation; + + return $this; + } + + /** + * @return string + */ + public function getRelation() + { + return $this->_relation; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractMulti.php b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractMulti.php new file mode 100644 index 00000000..06f6daea --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/AbstractMulti.php @@ -0,0 +1,89 @@ +<?php +namespace Elastica\Filter; + +/** + * Multi Abstract filter object. Should be extended by filter types composed of an array of sub filters. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +abstract class AbstractMulti extends AbstractFilter +{ + /** + * Filters. + * + * @var array + */ + protected $_filters = array(); + + /** + * @param \Elastica\Filter\AbstractFilter $filters + */ + public function __construct(array $filters = array()) + { + if (!empty($filters)) { + $this->setFilters($filters); + } + } + + /** + * Add filter. + * + * @param \Elastica\Filter\AbstractFilter $filter + * + * @return $this + */ + public function addFilter(AbstractFilter $filter) + { + $this->_filters[] = $filter->toArray(); + + return $this; + } + + /** + * Set filters. + * + * @param array $filters + * + * @return $this + */ + public function setFilters(array $filters) + { + $this->_filters = array(); + + foreach ($filters as $filter) { + $this->addFilter($filter); + } + + return $this; + } + + /** + * @return array Filters + */ + public function getFilters() + { + return $this->_filters; + } + + /** + * @see \Elastica\Param::toArray() + * + * @return array + */ + public function toArray() + { + $data = parent::toArray(); + $name = $this->_getBaseName(); + $filterData = $data[$name]; + + if (empty($filterData)) { + $filterData = $this->_filters; + } else { + $filterData['filters'] = $this->_filters; + } + + $data[$name] = $filterData; + + return $data; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Bool.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Bool.php new file mode 100644 index 00000000..0d30f83f --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Bool.php @@ -0,0 +1,15 @@ +<?php +namespace Elastica\Filter; + +/** + * Bool Filter. + * + * This class is for backward compatibility reason for all php < 7 versions. For PHP 7 and above use BoolFilter as Bool is reserved. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html + */ +class Bool extends BoolFilter +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/BoolAnd.php b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolAnd.php new file mode 100644 index 00000000..8a08ea9c --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolAnd.php @@ -0,0 +1,20 @@ +<?php +namespace Elastica\Filter; + +/** + * And Filter. + * + * @author Lee Parker, Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-and-filter.html + */ +class BoolAnd extends AbstractMulti +{ + /** + * @return string + */ + protected function _getBaseName() + { + return 'and'; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/BoolFilter.php b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolFilter.php new file mode 100644 index 00000000..5a488b77 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolFilter.php @@ -0,0 +1,133 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Exception\InvalidException; + +/** + * Bool Filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html + */ +class BoolFilter extends AbstractFilter +{ + /** + * Must. + * + * @var array + */ + protected $_must = array(); + + /** + * Should. + * + * @var array + */ + protected $_should = array(); + + /** + * Must not. + * + * @var array + */ + protected $_mustNot = array(); + + /** + * Adds should filter. + * + * @param array|\Elastica\Filter\AbstractFilter $args Filter data + * + * @return $this + */ + public function addShould($args) + { + return $this->_addFilter('should', $args); + } + + /** + * Adds must filter. + * + * @param array|\Elastica\Filter\AbstractFilter $args Filter data + * + * @return $this + */ + public function addMust($args) + { + return $this->_addFilter('must', $args); + } + + /** + * Adds mustNot filter. + * + * @param array|\Elastica\Filter\AbstractFilter $args Filter data + * + * @return $this + */ + public function addMustNot($args) + { + return $this->_addFilter('mustNot', $args); + } + + /** + * Adds general filter based on type. + * + * @param string $type Filter type + * @param array|\Elastica\Filter\AbstractFilter $args Filter data + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + protected function _addFilter($type, $args) + { + if ($args instanceof AbstractFilter) { + $args = $args->toArray(); + } elseif (!is_array($args)) { + throw new InvalidException('Invalid parameter. Has to be array or instance of Elastica\Filter'); + } else { + $parsedArgs = array(); + foreach ($args as $filter) { + if ($filter instanceof AbstractFilter) { + $parsedArgs[] = $filter->toArray(); + } + } + $args = $parsedArgs; + } + + $varName = '_'.$type; + $this->{$varName}[] = $args; + + return $this; + } + + /** + * Converts bool filter to array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array Filter array + */ + public function toArray() + { + $args = array(); + + if (!empty($this->_must)) { + $args['bool']['must'] = $this->_must; + } + + if (!empty($this->_should)) { + $args['bool']['should'] = $this->_should; + } + + if (!empty($this->_mustNot)) { + $args['bool']['must_not'] = $this->_mustNot; + } + + if (isset($args['bool'])) { + $args['bool'] = array_merge($args['bool'], $this->getParams()); + } + + return $args; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/BoolNot.php b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolNot.php new file mode 100644 index 00000000..81db7f65 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolNot.php @@ -0,0 +1,42 @@ +<?php +namespace Elastica\Filter; + +/** + * Not Filter. + * + * @author Lee Parker, Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-not-filter.html + */ +class BoolNot extends AbstractFilter +{ + /** + * Creates Not filter query. + * + * @param \Elastica\Filter\AbstractFilter $filter Filter object + */ + public function __construct(AbstractFilter $filter) + { + $this->setFilter($filter); + } + + /** + * Set filter. + * + * @param \Elastica\Filter\AbstractFilter $filter + * + * @return $this + */ + public function setFilter(AbstractFilter $filter) + { + return $this->setParam('filter', $filter->toArray()); + } + + /** + * @return string + */ + protected function _getBaseName() + { + return 'not'; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/BoolOr.php b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolOr.php new file mode 100644 index 00000000..9091e496 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/BoolOr.php @@ -0,0 +1,20 @@ +<?php +namespace Elastica\Filter; + +/** + * Or Filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-or-filter.html + */ +class BoolOr extends AbstractMulti +{ + /** + * @return string + */ + protected function _getBaseName() + { + return 'or'; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Exists.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Exists.php new file mode 100644 index 00000000..d6dc9962 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Exists.php @@ -0,0 +1,34 @@ +<?php +namespace Elastica\Filter; + +/** + * Exists query. + * + * @author Oleg Cherniy <oleg.cherniy@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-filter.html + */ +class Exists extends AbstractFilter +{ + /** + * Construct exists filter. + * + * @param string $field + */ + public function __construct($field) + { + $this->setField($field); + } + + /** + * Set field. + * + * @param string $field + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/GeoBoundingBox.php b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoBoundingBox.php new file mode 100644 index 00000000..f67febe3 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoBoundingBox.php @@ -0,0 +1,49 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Exception\InvalidException; + +/** + * Geo bounding box filter. + * + * @author Fabian Vogler <fabian@equivalence.ch> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-bounding-box-filter.html + */ +class GeoBoundingBox extends AbstractFilter +{ + /** + * Construct BoundingBoxFilter. + * + * @param string $key Key + * @param array $coordinates Array with top left coordinate as first and bottom right coordinate as second element + */ + public function __construct($key, array $coordinates) + { + $this->addCoordinates($key, $coordinates); + } + + /** + * Add coordinates. + * + * @param string $key Key + * @param array $coordinates Array with top left coordinate as first and bottom right coordinate as second element + * + * @throws \Elastica\Exception\InvalidException If $coordinates doesn't have two elements + * + * @return $this + */ + public function addCoordinates($key, array $coordinates) + { + if (!isset($coordinates[0]) || !isset($coordinates[1])) { + throw new InvalidException('expected $coordinates to be an array with two elements'); + } + + $this->setParam($key, array( + 'top_left' => $coordinates[0], + 'bottom_right' => $coordinates[1], + )); + + return $this; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistance.php b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistance.php new file mode 100644 index 00000000..f4cb51d9 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistance.php @@ -0,0 +1,76 @@ +<?php +namespace Elastica\Filter; + +/** + * Geo distance filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html + */ +class GeoDistance extends AbstractGeoDistance +{ + const DISTANCE_TYPE_ARC = 'arc'; + const DISTANCE_TYPE_PLANE = 'plane'; + const DISTANCE_TYPE_SLOPPY_ARC = 'sloppy_arc'; + + const OPTIMIZE_BBOX_MEMORY = 'memory'; + const OPTIMIZE_BBOX_INDEXED = 'indexed'; + const OPTIMIZE_BBOX_NONE = 'none'; + + /** + * Create GeoDistance object. + * + * @param string $key Key + * @param array|string $location Location as array or geohash: array('lat' => 48.86, 'lon' => 2.35) OR 'drm3btev3e86' + * @param string $distance Distance + * + * @throws \Elastica\Exception\InvalidException + */ + public function __construct($key, $location, $distance) + { + parent::__construct($key, $location); + + $this->setDistance($distance); + } + + /** + * @param string $distance + * + * @return $this + */ + public function setDistance($distance) + { + $this->setParam('distance', $distance); + + return $this; + } + + /** + * See DISTANCE_TYPE_* constants. + * + * @param string $distanceType + * + * @return $this + */ + public function setDistanceType($distanceType) + { + $this->setParam('distance_type', $distanceType); + + return $this; + } + + /** + * See OPTIMIZE_BBOX_* constants. + * + * @param string $optimizeBbox + * + * @return $this + */ + public function setOptimizeBbox($optimizeBbox) + { + $this->setParam('optimize_bbox', $optimizeBbox); + + return $this; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistanceRange.php b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistanceRange.php new file mode 100644 index 00000000..f5cbbeb7 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistanceRange.php @@ -0,0 +1,103 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Exception\InvalidException; + +/** + * Geo distance filter. + * + * @author munkie + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-range-filter.html + */ +class GeoDistanceRange extends AbstractGeoDistance +{ + const RANGE_FROM = 'from'; + const RANGE_TO = 'to'; + const RANGE_LT = 'lt'; + const RANGE_LTE = 'lte'; + const RANGE_GT = 'gt'; + const RANGE_GTE = 'gte'; + + const RANGE_INCLUDE_LOWER = 'include_lower'; + const RANGE_INCLUDE_UPPER = 'include_upper'; + + /** + * @var array + */ + protected $_ranges = array(); + + /** + * @param string $key + * @param array|string $location + * @param array $ranges + * + * @internal param string $distance + */ + public function __construct($key, $location, array $ranges = array()) + { + parent::__construct($key, $location); + + if (!empty($ranges)) { + $this->setRanges($ranges); + } + } + + /** + * @param array $ranges + * + * @return $this + */ + public function setRanges(array $ranges) + { + $this->_ranges = array(); + + foreach ($ranges as $key => $value) { + $this->setRange($key, $value); + } + + return $this; + } + + /** + * @param string $key + * @param mixed $value + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function setRange($key, $value) + { + switch ($key) { + case self::RANGE_TO: + case self::RANGE_FROM: + case self::RANGE_GT: + case self::RANGE_GTE: + case self::RANGE_LT: + case self::RANGE_LTE: + break; + case self::RANGE_INCLUDE_LOWER: + case self::RANGE_INCLUDE_UPPER: + $value = (boolean) $value; + break; + default: + throw new InvalidException('Invalid range parameter given: '.$key); + } + $this->_ranges[$key] = $value; + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + foreach ($this->_ranges as $key => $value) { + $this->setParam($key, $value); + } + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/GeoPolygon.php b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoPolygon.php new file mode 100644 index 00000000..86ca2b80 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoPolygon.php @@ -0,0 +1,56 @@ +<?php +namespace Elastica\Filter; + +/** + * Geo polygon filter. + * + * @author Michael Maclean <mgdm@php.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-polygon-filter.html + */ +class GeoPolygon extends AbstractFilter +{ + /** + * Key. + * + * @var string Key + */ + protected $_key = ''; + + /** + * Points making up polygon. + * + * @var array Points making up polygon + */ + protected $_points = array(); + + /** + * Construct polygon filter. + * + * @param string $key Key + * @param array $points Points making up polygon + */ + public function __construct($key, array $points) + { + $this->_key = $key; + $this->_points = $points; + } + + /** + * Converts filter to array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array + */ + public function toArray() + { + return array( + 'geo_polygon' => array( + $this->_key => array( + 'points' => $this->_points, + ), + ), + ); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapePreIndexed.php b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapePreIndexed.php new file mode 100644 index 00000000..d07cffff --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapePreIndexed.php @@ -0,0 +1,84 @@ +<?php +namespace Elastica\Filter; + +/** + * geo_shape filter for pre-indexed shapes. + * + * Filter pre-indexed shape definitions + * + * @author Bennie Krijger <benniekrijger@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html + */ +class GeoShapePreIndexed extends AbstractGeoShape +{ + /** + * elasticsearch id of the pre-indexed shape. + * + * @var string + */ + protected $_indexedId; + + /** + * elasticsearch type of the pre-indexed shape. + * + * @var string + */ + protected $_indexedType; + + /** + * elasticsearch index of the pre-indexed shape. + * + * @var string + */ + protected $_indexedIndex; + + /** + * elasticsearch path/field name of the pre-indexed shape. + * + * @var string + */ + protected $_indexedPath; + + /** + * Construct geo_shape filter with a pre-indexed shape. + * + * @param string $path The path/field of the shape searched + * @param string $indexedId Id of the pre-indexed shape + * @param string $indexedType Type of the pre-indexed shape + * @param string $indexedIndex Index of the pre-indexed shape + * @param string $indexedPath Path of the pre-indexed shape + */ + public function __construct($path, $indexedId, $indexedType, $indexedIndex, $indexedPath) + { + $this->_path = $path; + $this->_indexedId = $indexedId; + $this->_indexedType = $indexedType; + $this->_indexedIndex = $indexedIndex; + $this->_indexedPath = $indexedPath; + } + + /** + * Converts filter to array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array + */ + public function toArray() + { + return array( + 'geo_shape' => array( + $this->_path => array( + 'indexed_shape' => array( + 'id' => $this->_indexedId, + 'type' => $this->_indexedType, + 'index' => $this->_indexedIndex, + 'path' => $this->_indexedPath, + ), + 'relation' => $this->_relation, + ), + ), + ); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapeProvided.php b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapeProvided.php new file mode 100644 index 00000000..0f25beeb --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapeProvided.php @@ -0,0 +1,73 @@ +<?php +namespace Elastica\Filter; + +/** + * geo_shape filter or provided shapes. + * + * Filter provided shape definitions + * + * @author BennieKrijger <benniekrijger@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html + */ +class GeoShapeProvided extends AbstractGeoShape +{ + const TYPE_ENVELOPE = 'envelope'; + const TYPE_MULTIPOINT = 'multipoint'; + const TYPE_POINT = 'point'; + const TYPE_MULTIPOLYGON = 'multipolygon'; + const TYPE_LINESTRING = 'linestring'; + const TYPE_POLYGON = 'polygon'; + + /** + * Type of the geo_shape. + * + * @var string + */ + protected $_shapeType; + + /** + * Coordinates making up geo_shape. + * + * @var array Coordinates making up geo_shape + */ + protected $_coordinates; + + /** + * Construct geo_shape filter. + * + * @param string $path The path/field of the shape searched + * @param array $coordinates Points making up the shape + * @param string $shapeType Type of the geo_shape: + * point, envelope, linestring, polygon, + * multipoint or multipolygon + */ + public function __construct($path, array $coordinates, $shapeType = self::TYPE_ENVELOPE) + { + $this->_path = $path; + $this->_shapeType = $shapeType; + $this->_coordinates = $coordinates; + } + + /** + * Converts filter to array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array + */ + public function toArray() + { + return array( + 'geo_shape' => array( + $this->_path => array( + 'shape' => array( + 'type' => $this->_shapeType, + 'coordinates' => $this->_coordinates, + ), + 'relation' => $this->_relation, + ), + ), + ); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/GeohashCell.php b/vendor/ruflin/elastica/lib/Elastica/Filter/GeohashCell.php new file mode 100644 index 00000000..dd147152 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/GeohashCell.php @@ -0,0 +1,47 @@ +<?php +namespace Elastica\Filter; + +/** + * Class GeohashCell. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geohash-cell-filter.html + */ +class GeohashCell extends AbstractGeoDistance +{ + /** + * @param string $key The field on which to filter + * @param array|string $location Location as coordinates array or geohash string ['lat' => 40.3, 'lon' => 45.2] + * @param string|int $precision Integer length of geohash prefix or distance (3, or "50m") + * @param bool $neighbors If true, filters cells next to the given cell. + */ + public function __construct($key, $location, $precision = -1, $neighbors = false) + { + parent::__construct($key, $location); + $this->setPrecision($precision); + $this->setNeighbors($neighbors); + } + + /** + * Set the precision for this filter. + * + * @param string|int $precision Integer length of geohash prefix or distance (3, or "50m") + * + * @return $this + */ + public function setPrecision($precision) + { + return $this->setParam('precision', $precision); + } + + /** + * Set the neighbors option for this filter. + * + * @param bool $neighbors If true, filters cells next to the given cell. + * + * @return $this + */ + public function setNeighbors($neighbors) + { + return $this->setParam('neighbors', (bool) $neighbors); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/HasChild.php b/vendor/ruflin/elastica/lib/Elastica/Filter/HasChild.php new file mode 100644 index 00000000..2c4cc0d6 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/HasChild.php @@ -0,0 +1,95 @@ +<?php +namespace Elastica\Filter; + +/** + * Returns parent documents having child docs matching the query. + * + * @author Fabian Vogler <fabian@equivalence.ch> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-filter.html + */ +class HasChild extends AbstractFilter +{ + /** + * Construct HasChild filter. + * + * @param string|\Elastica\Query|\Elastica\Filter\AbstractFilter $query Query string or a Elastica\Query object or a filter + * @param string|\Elastica\Type $type Child document type + */ + public function __construct($query, $type = null) + { + $this->setType($type); + if ($query instanceof AbstractFilter) { + $this->setFilter($query); + } else { + $this->setQuery($query); + } + } + + /** + * Sets query object. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery($query) + { + $query = \Elastica\Query::create($query); + $data = $query->toArray(); + + return $this->setParam('query', $data['query']); + } + + /** + * Sets the filter object. + * + * @param \Elastica\Filter\AbstractFilter $filter + * + * @return $this + */ + public function setFilter($filter) + { + return $this->setParam('filter', $filter->toArray()); + } + + /** + * Set type of the child document. + * + * @param string|\Elastica\Type $type Child document type + * + * @return $this + */ + public function setType($type) + { + if ($type instanceof \Elastica\Type) { + $type = $type->getName(); + } + + return $this->setParam('type', (string) $type); + } + + /** + * Set minimum number of children are required to match for the parent doc to be considered a match. + * + * @param int $count + * + * @return $this + */ + public function setMinimumChildrenCount($count) + { + return $this->setParam('min_children', (int) $count); + } + + /** + * Set maximum number of children are required to match for the parent doc to be considered a match. + * + * @param int $count + * + * @return $this + */ + public function setMaximumChildrenCount($count) + { + return $this->setParam('max_children', (int) $count); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/HasParent.php b/vendor/ruflin/elastica/lib/Elastica/Filter/HasParent.php new file mode 100644 index 00000000..73a2dc5a --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/HasParent.php @@ -0,0 +1,69 @@ +<?php +namespace Elastica\Filter; + +/** + * Returns child documents having parent docs matching the query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-filter.html + */ +class HasParent extends AbstractFilter +{ + /** + * Construct HasParent filter. + * + * @param string|\Elastica\Query|\Elastica\Filter\AbstractFilter $query Query string or a Query object or a filter + * @param string|\Elastica\Type $type Parent document type + */ + public function __construct($query, $type) + { + if ($query instanceof AbstractFilter) { + $this->setFilter($query); + } else { + $this->setQuery($query); + } + $this->setType($type); + } + + /** + * Sets query object. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery($query) + { + $query = \Elastica\Query::create($query); + $data = $query->toArray(); + + return $this->setParam('query', $data['query']); + } + + /** + * Sets filter object. + * + * @param \Elastica\Filter\AbstractFilter $filter + * + * @return $this + */ + public function setFilter($filter) + { + return $this->setParam('filter', $filter->toArray()); + } + + /** + * Set type of the parent document. + * + * @param string|\Elastica\Type $type Parent document type + * + * @return $this + */ + public function setType($type) + { + if ($type instanceof \Elastica\Type) { + $type = $type->getName(); + } + + return $this->setParam('type', (string) $type); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Ids.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Ids.php new file mode 100644 index 00000000..bfb8cc48 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Ids.php @@ -0,0 +1,94 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Type as ElasticaType; + +/** + * Ids Filter. + * + * @author Lee Parker, Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-filter.html + */ +class Ids extends AbstractFilter +{ + /** + * Creates filter object. + * + * @param string|\Elastica\Type $type Type to filter on + * @param array $ids List of ids + */ + public function __construct($type = null, array $ids = array()) + { + $this->setType($type); + $this->setIds($ids); + } + + /** + * Adds one more filter to the and filter. + * + * @param string $id Adds id to filter + * + * @return $this + */ + public function addId($id) + { + return $this->addParam('values', $id); + } + + /** + * Adds one more type to query. + * + * @param string|\Elastica\Type $type Type name or object + * + * @return $this + */ + public function addType($type) + { + if ($type instanceof ElasticaType) { + $type = $type->getName(); + } elseif (empty($type) && !is_numeric($type)) { + // TODO: Shouldn't this throw an exception? + // A type can be 0, but cannot be empty + return $this; + } + + return $this->addParam('type', $type); + } + + /** + * Set type. + * + * @param string|\Elastica\Type $type Type name or object + * + * @return $this + */ + public function setType($type) + { + if ($type instanceof ElasticaType) { + $type = $type->getName(); + } elseif (empty($type) && !is_numeric($type)) { + // TODO: Shouldn't this throw an exception or let handling of invalid params to ES? + // A type can be 0, but cannot be empty + return $this; + } + + return $this->setParam('type', $type); + } + + /** + * Sets the ids to filter. + * + * @param array|string $ids List of ids + * + * @return $this + */ + public function setIds($ids) + { + if (!is_array($ids)) { + $ids = array($ids); + } + + return $this->setParam('values', $ids); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Indices.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Indices.php new file mode 100644 index 00000000..ffaf5975 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Indices.php @@ -0,0 +1,78 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Index as ElasticaIndex; + +/** + * Class Indices. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-indices-filter.html + */ +class Indices extends AbstractFilter +{ + /** + * @param AbstractFilter $filter filter which will be applied to docs in the specified indices + * @param mixed[] $indices + */ + public function __construct(AbstractFilter $filter, array $indices) + { + $this->setIndices($indices)->setFilter($filter); + } + + /** + * Set the indices on which this filter should be applied. + * + * @param mixed[] $indices + * + * @return $this + */ + public function setIndices(array $indices) + { + $this->setParam('indices', array()); + foreach ($indices as $index) { + $this->addIndex($index); + } + + return $this; + } + + /** + * Adds one more index on which this filter should be applied. + * + * @param string|\Elastica\Index $index + * + * @return $this + */ + public function addIndex($index) + { + if ($index instanceof ElasticaIndex) { + $index = $index->getName(); + } + + return $this->addParam('indices', (string) $index); + } + + /** + * Set the filter to be applied to docs in the specified indices. + * + * @param AbstractFilter $filter + * + * @return $this + */ + public function setFilter(AbstractFilter $filter) + { + return $this->setParam('filter', $filter->toArray()); + } + + /** + * Set the filter to be applied to docs in indices which do not match those specified in the "indices" parameter. + * + * @param AbstractFilter $filter + * + * @return $this + */ + public function setNoMatchFilter(AbstractFilter $filter) + { + return $this->setParam('no_match_filter', $filter->toArray()); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Limit.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Limit.php new file mode 100644 index 00000000..bf3f8e13 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Limit.php @@ -0,0 +1,34 @@ +<?php +namespace Elastica\Filter; + +/** + * Limit Filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-limit-filter.html + */ +class Limit extends AbstractFilter +{ + /** + * Construct limit filter. + * + * @param int $limit Limit + */ + public function __construct($limit) + { + $this->setLimit($limit); + } + + /** + * Set the limit. + * + * @param int $limit Limit + * + * @return $this + */ + public function setLimit($limit) + { + return $this->setParam('value', (int) $limit); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/MatchAll.php b/vendor/ruflin/elastica/lib/Elastica/Filter/MatchAll.php new file mode 100644 index 00000000..607c5fd1 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/MatchAll.php @@ -0,0 +1,20 @@ +<?php +namespace Elastica\Filter; + +/** + * Match all filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-all-filter.html + */ +class MatchAll extends AbstractFilter +{ + /** + * Creates match all filter. + */ + public function __construct() + { + $this->_params = new \stdClass(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Missing.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Missing.php new file mode 100644 index 00000000..9b157b2c --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Missing.php @@ -0,0 +1,60 @@ +<?php +namespace Elastica\Filter; + +/** + * Missing Filter. + * + * @author Maciej Wiercinski <maciej@wiercinski.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-missing-filter.html + */ +class Missing extends AbstractFilter +{ + /** + * Construct missing filter. + * + * @param string $field OPTIONAL + */ + public function __construct($field = '') + { + if (strlen($field)) { + $this->setField($field); + } + } + + /** + * Set field. + * + * @param string $field + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', (string) $field); + } + + /** + * Set "existence" parameter. + * + * @param bool $existence + * + * @return $this + */ + public function setExistence($existence) + { + return $this->setParam('existence', (bool) $existence); + } + + /** + * Set "null_value" parameter. + * + * @param bool $nullValue + * + * @return $this + */ + public function setNullValue($nullValue) + { + return $this->setParam('null_value', (bool) $nullValue); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Nested.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Nested.php new file mode 100644 index 00000000..ad21bc7e --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Nested.php @@ -0,0 +1,62 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Query\AbstractQuery; + +/** + * Nested filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-filter.html + */ +class Nested extends AbstractFilter +{ + /** + * Adds field to mlt filter. + * + * @param string $path Nested object path + * + * @return $this + */ + public function setPath($path) + { + return $this->setParam('path', $path); + } + + /** + * Sets nested query. + * + * @param \Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery(AbstractQuery $query) + { + return $this->setParam('query', $query->toArray()); + } + + /** + * Sets nested filter. + * + * @param \Elastica\Filter\AbstractFilter $filter + * + * @return $this + */ + public function setFilter(AbstractFilter $filter) + { + return $this->setParam('filter', $filter->toArray()); + } + + /** + * Set join option. + * + * @param bool $join + * + * @return $this + */ + public function setJoin($join) + { + return $this->setParam('join', (bool) $join); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/NumericRange.php b/vendor/ruflin/elastica/lib/Elastica/Filter/NumericRange.php new file mode 100644 index 00000000..08342616 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/NumericRange.php @@ -0,0 +1,13 @@ +<?php +namespace Elastica\Filter; + +/** + * Numeric Range Filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html + */ +class NumericRange extends Range +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Prefix.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Prefix.php new file mode 100644 index 00000000..e845fd73 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Prefix.php @@ -0,0 +1,80 @@ +<?php +namespace Elastica\Filter; + +/** + * Prefix filter. + * + * @author Jasper van Wanrooy <jasper@vanwanrooy.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-prefix-filter.html + */ +class Prefix extends AbstractFilter +{ + /** + * Holds the name of the field for the prefix. + * + * @var string + */ + protected $_field = ''; + + /** + * Holds the prefix string. + * + * @var string + */ + protected $_prefix = ''; + + /** + * Creates prefix filter. + * + * @param string $field Field name + * @param string $prefix Prefix string + */ + public function __construct($field = '', $prefix = '') + { + $this->setField($field); + $this->setPrefix($prefix); + } + + /** + * Sets the name of the prefix field. + * + * @param string $field Field name + * + * @return $this + */ + public function setField($field) + { + $this->_field = $field; + + return $this; + } + + /** + * Sets the prefix string. + * + * @param string $prefix Prefix string + * + * @return $this + */ + public function setPrefix($prefix) + { + $this->_prefix = $prefix; + + return $this; + } + + /** + * Converts object to an array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array data array + */ + public function toArray() + { + $this->setParam($this->_field, $this->_prefix); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Query.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Query.php new file mode 100644 index 00000000..acb6a124 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Query.php @@ -0,0 +1,91 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Exception\InvalidException; +use Elastica\Query\AbstractQuery; + +/** + * Query filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html + */ +class Query extends AbstractFilter +{ + /** + * Query. + * + * @var array + */ + protected $_query; + + /** + * Construct query filter. + * + * @param array|\Elastica\Query\AbstractQuery $query + */ + public function __construct($query = null) + { + if (!is_null($query)) { + $this->setQuery($query); + } + } + + /** + * Set query. + * + * @param array|\Elastica\Query\AbstractQuery $query + * + * @throws \Elastica\Exception\InvalidException If parameter is invalid + * + * @return $this + */ + public function setQuery($query) + { + if (!$query instanceof AbstractQuery && !is_array($query)) { + throw new InvalidException('expected an array or instance of Elastica\Query\AbstractQuery'); + } + + if ($query instanceof AbstractQuery) { + $query = $query->toArray(); + } + + $this->_query = $query; + + return $this; + } + + /** + * @see \Elastica\Param::_getBaseName() + */ + protected function _getBaseName() + { + if (empty($this->_params)) { + return 'query'; + } else { + return 'fquery'; + } + } + + /** + * @see \Elastica\Param::toArray() + */ + public function toArray() + { + $data = parent::toArray(); + + $name = $this->_getBaseName(); + $filterData = $data[$name]; + + if (empty($filterData)) { + $filterData = $this->_query; + } else { + $filterData['query'] = $this->_query; + } + + $data[$name] = $filterData; + + return $data; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Range.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Range.php new file mode 100644 index 00000000..1e7bf132 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Range.php @@ -0,0 +1,73 @@ +<?php +namespace Elastica\Filter; + +/** + * Range Filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html + */ +class Range extends AbstractFilter +{ + /** + * Fields. + * + * @var array Fields + */ + protected $_fields = array(); + + /** + * Construct range filter. + * + * @param string $fieldName Field name + * @param array $args Field arguments + */ + public function __construct($fieldName = '', array $args = array()) + { + if ($fieldName) { + $this->addField($fieldName, $args); + } + } + + /** + * Ads a field with arguments to the range query. + * + * @param string $fieldName Field name + * @param array $args Field arguments + * + * @return $this + */ + public function addField($fieldName, array $args) + { + $this->_fields[$fieldName] = $args; + + return $this; + } + + /** + * Set execution mode. + * + * @param string $execution Options: "index" or "fielddata" + * + * @return $this + */ + public function setExecution($execution) + { + return $this->setParam('execution', (string) $execution); + } + + /** + * Converts object to array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array Filter array + */ + public function toArray() + { + $this->setParams(array_merge($this->getParams(), $this->_fields)); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Regexp.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Regexp.php new file mode 100644 index 00000000..612dc434 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Regexp.php @@ -0,0 +1,112 @@ +<?php +namespace Elastica\Filter; + +/** + * Regexp filter. + * + * @author Timothy Lamb <trash80@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-filter.html + */ +class Regexp extends AbstractFilter +{ + /** + * Holds the name of the field for the regular expression. + * + * @var string + */ + protected $_field = ''; + + /** + * Holds the regexp string. + * + * @var string + */ + protected $_regexp = ''; + + /** + * Holds the regexp options. + * + * @var array + */ + protected $_options = array(); + + /** + * Create Regexp object. + * + * @param string $field Field name + * @param string $regexp Regular expression + * @param array $options Regular expression options + * + * @throws \Elastica\Exception\InvalidException + */ + public function __construct($field = '', $regexp = '', $options = array()) + { + $this->setField($field); + $this->setRegexp($regexp); + $this->setOptions($options); + } + + /** + * Sets the name of the regexp field. + * + * @param string $field Field name + * + * @return $this + */ + public function setField($field) + { + $this->_field = $field; + + return $this; + } + + /** + * Sets the regular expression query string. + * + * @param string $regexp Regular expression + * + * @return $this + */ + public function setRegexp($regexp) + { + $this->_regexp = $regexp; + + return $this; + } + + /** + * Sets the regular expression query options. + * + * @param array $options Regular expression options + * + * @return $this + */ + public function setOptions($options) + { + $this->_options = $options; + + return $this; + } + + /** + * Converts object to an array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array data array + */ + public function toArray() + { + if (count($this->_options) > 0) { + $options = array('value' => $this->_regexp); + $options = array_merge($options, $this->_options); + + $this->setParam($this->_field, $options); + } else { + $this->setParam($this->_field, $this->_regexp); + } + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Script.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Script.php new file mode 100644 index 00000000..2c8d34bf --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Script.php @@ -0,0 +1,47 @@ +<?php +namespace Elastica\Filter; + +use Elastica; + +/** + * Script filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-filter.html + */ +class Script extends AbstractFilter +{ + /** + * Query object. + * + * @var array|\Elastica\Query\AbstractQuery + */ + protected $_query = null; + + /** + * Construct script filter. + * + * @param array|string|\Elastica\Script $script OPTIONAL Script + */ + public function __construct($script = null) + { + if ($script) { + $this->setScript($script); + } + } + + /** + * Sets script object. + * + * @param \Elastica\Script|string|array $script + * + * @return $this + */ + public function setScript($script) + { + $script = Elastica\Script::create($script); + + return $this->setParams($script->toArray()); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Term.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Term.php new file mode 100644 index 00000000..2a387318 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Term.php @@ -0,0 +1,47 @@ +<?php +namespace Elastica\Filter; + +/** + * Term query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html + */ +class Term extends AbstractFilter +{ + /** + * Construct term filter. + * + * @param array $term Term array + */ + public function __construct(array $term = array()) + { + $this->setRawTerm($term); + } + + /** + * Sets/overwrites key and term directly. + * + * @param array $term Key value pair + * + * @return $this + */ + public function setRawTerm(array $term) + { + return $this->setParams($term); + } + + /** + * Adds a term to the term query. + * + * @param string $key Key to query + * @param string|array $value Values(s) for the query. Boost can be set with array + * + * @return $this + */ + public function setTerm($key, $value) + { + return $this->setRawTerm(array($key => $value)); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Terms.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Terms.php new file mode 100644 index 00000000..c099ab3d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Terms.php @@ -0,0 +1,149 @@ +<?php +namespace Elastica\Filter; + +use Elastica\Exception\InvalidException; + +/** + * Terms filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html + */ +class Terms extends AbstractFilter +{ + /** + * Terms. + * + * @var array Terms + */ + protected $_terms = array(); + + /** + * Params. + * + * @var array Params + */ + protected $_params = array(); + + /** + * Terms key. + * + * @var string Terms key + */ + protected $_key = ''; + + /** + * Creates terms filter. + * + * @param string $key Terms key + * @param array $terms Terms values + */ + public function __construct($key = '', array $terms = array()) + { + $this->setTerms($key, $terms); + } + + /** + * Sets key and terms for the filter. + * + * @param string $key Terms key + * @param array $terms Terms for the query. + * + * @return $this + */ + public function setTerms($key, array $terms) + { + $this->_key = $key; + $this->_terms = array_values($terms); + + return $this; + } + + /** + * Set the lookup parameters for this filter. + * + * @param string $key terms key + * @param string|\Elastica\Type $type document type from which to fetch the terms values + * @param string $id id of the document from which to fetch the terms values + * @param string $path the field from which to fetch the values for the filter + * @param string|array|\Elastica\Index $options An array of options or the index from which to fetch the terms values. Defaults to the current index. + * + * @return $this + */ + public function setLookup($key, $type, $id, $path, $options = array()) + { + $this->_key = $key; + if ($type instanceof \Elastica\Type) { + $type = $type->getName(); + } + $this->_terms = array( + 'type' => $type, + 'id' => $id, + 'path' => $path, + ); + + $index = $options; + if (is_array($options)) { + if (isset($options['index'])) { + $index = $options['index']; + unset($options['index']); + } + $this->_terms = array_merge($options, $this->_terms); + } + + if (!is_null($index)) { + if ($index instanceof \Elastica\Index) { + $index = $index->getName(); + } + $this->_terms['index'] = $index; + } + + return $this; + } + + /** + * Adds an additional term to the query. + * + * @param string $term Filter term + * + * @return $this + */ + public function addTerm($term) + { + $this->_terms[] = $term; + + return $this; + } + + /** + * Converts object to an array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @throws \Elastica\Exception\InvalidException + * + * @return array + */ + public function toArray() + { + if (empty($this->_key)) { + throw new InvalidException('Terms key has to be set'); + } + $this->_params[$this->_key] = $this->_terms; + + return array('terms' => $this->_params); + } + + /** + * Set execution mode. + * + * @param string $execution Options: "bool", "and", "or", "plain" or "fielddata" + * + * @return $this + */ + public function setExecution($execution) + { + return $this->setParam('execution', (string) $execution); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Filter/Type.php b/vendor/ruflin/elastica/lib/Elastica/Filter/Type.php new file mode 100644 index 00000000..f9c17813 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Filter/Type.php @@ -0,0 +1,59 @@ +<?php +namespace Elastica\Filter; + +/** + * Type Filter. + * + * @author James Wilson <jwilson556@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-type-filter.html + */ +class Type extends AbstractFilter +{ + /** + * Type name. + * + * @var string + */ + protected $_type = null; + + /** + * Construct Type Filter. + * + * @param string $type Type name + */ + public function __construct($type = null) + { + if ($type) { + $this->setType($type); + } + } + + /** + * Ads a field with arguments to the range query. + * + * @param string $typeName Type name + * + * @return $this + */ + public function setType($typeName) + { + $this->_type = $typeName; + + return $this; + } + + /** + * Convert object to array. + * + * @see \Elastica\Filter\AbstractFilter::toArray() + * + * @return array Filter array + */ + public function toArray() + { + return array( + 'type' => array('value' => $this->_type), + ); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Index.php b/vendor/ruflin/elastica/lib/Elastica/Index.php new file mode 100644 index 00000000..3b8d431b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Index.php @@ -0,0 +1,515 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; +use Elastica\Exception\ResponseException; +use Elastica\Index\Settings as IndexSettings; +use Elastica\Index\Stats as IndexStats; +use Elastica\Index\Status as IndexStatus; + +/** + * Elastica index object. + * + * Handles reads, deletes and configurations of an index + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Index implements SearchableInterface +{ + /** + * Index name. + * + * @var string Index name + */ + protected $_name = ''; + + /** + * Client object. + * + * @var \Elastica\Client Client object + */ + protected $_client = null; + + /** + * Creates a new index object. + * + * All the communication to and from an index goes of this object + * + * @param \Elastica\Client $client Client object + * @param string $name Index name + * + * @throws \Elastica\Exception\InvalidException + */ + public function __construct(Client $client, $name) + { + $this->_client = $client; + + if (!is_scalar($name)) { + throw new InvalidException('Index name should be a scalar type'); + } + $this->_name = (string) $name; + } + + /** + * Returns a type object for the current index with the given name. + * + * @param string $type Type name + * + * @return \Elastica\Type Type object + */ + public function getType($type) + { + return new Type($this, $type); + } + + /** + * Returns the current status of the index. + * + * @return \Elastica\Index\Status Index status + */ + public function getStatus() + { + return new IndexStatus($this); + } + + /** + * Return Index Stats. + * + * @return \Elastica\Index\Stats + */ + public function getStats() + { + return new IndexStats($this); + } + + /** + * Gets all the type mappings for an index. + * + * @return array + */ + public function getMapping() + { + $path = '_mapping'; + + $response = $this->request($path, Request::GET); + $data = $response->getData(); + + // Get first entry as if index is an Alias, the name of the mapping is the real name and not alias name + $mapping = array_shift($data); + + if (isset($mapping['mappings'])) { + return $mapping['mappings']; + } + + return array(); + } + + /** + * Returns the index settings object. + * + * @return \Elastica\Index\Settings Settings object + */ + public function getSettings() + { + return new IndexSettings($this); + } + + /** + * Uses _bulk to send documents to the server. + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @return \Elastica\Bulk\ResponseSet + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + */ + public function updateDocuments(array $docs) + { + foreach ($docs as $doc) { + $doc->setIndex($this->getName()); + } + + return $this->getClient()->updateDocuments($docs); + } + + /** + * Uses _bulk to send documents to the server. + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @return \Elastica\Bulk\ResponseSet + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + */ + public function addDocuments(array $docs) + { + foreach ($docs as $doc) { + $doc->setIndex($this->getName()); + } + + return $this->getClient()->addDocuments($docs); + } + + /** + * Deletes entries in the db based on a query. + * + * @param \Elastica\Query|string $query Query object + * @param array $options Optional params + * + * @return \Elastica\Response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html + */ + public function deleteByQuery($query, array $options = array()) + { + if (is_string($query)) { + // query_string queries are not supported for delete by query operations + $options['q'] = $query; + + return $this->request('_query', Request::DELETE, array(), $options); + } + $query = Query::create($query); + + return $this->request('_query', Request::DELETE, array('query' => $query->getQuery()), $options); + } + + /** + * Deletes the index. + * + * @return \Elastica\Response Response object + */ + public function delete() + { + $response = $this->request('', Request::DELETE); + + return $response; + } + + /** + * Uses _bulk to delete documents from the server. + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @return \Elastica\Bulk\ResponseSet + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + */ + public function deleteDocuments(array $docs) + { + foreach ($docs as $doc) { + $doc->setIndex($this->getName()); + } + + return $this->getClient()->deleteDocuments($docs); + } + + /** + * Optimizes search index. + * + * Detailed arguments can be found here in the link + * + * @param array $args OPTIONAL Additional arguments + * + * @return array Server response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-optimize.html + */ + public function optimize($args = array()) + { + return $this->request('_optimize', Request::POST, array(), $args); + } + + /** + * Refreshes the index. + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html + */ + public function refresh() + { + return $this->request('_refresh', Request::POST, array()); + } + + /** + * Creates a new index with the given arguments. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html + * + * @param array $args OPTIONAL Arguments to use + * @param bool|array $options OPTIONAL + * bool=> Deletes index first if already exists (default = false). + * array => Associative array of options (option=>value) + * + * @throws \Elastica\Exception\InvalidException + * @throws \Elastica\Exception\ResponseException + * + * @return array Server response + */ + public function create(array $args = array(), $options = null) + { + $path = ''; + $query = array(); + + if (is_bool($options)) { + if ($options) { + try { + $this->delete(); + } catch (ResponseException $e) { + // Table can't be deleted, because doesn't exist + } + } + } else { + if (is_array($options)) { + foreach ($options as $key => $value) { + switch ($key) { + case 'recreate' : + try { + $this->delete(); + } catch (ResponseException $e) { + // Table can't be deleted, because doesn't exist + } + break; + case 'routing' : + $query = array('routing' => $value); + break; + default: + throw new InvalidException('Invalid option '.$key); + break; + } + } + } + } + + return $this->request($path, Request::PUT, $args, $query); + } + + /** + * Checks if the given index is already created. + * + * @return bool True if index exists + */ + public function exists() + { + $response = $this->getClient()->request($this->getName(), Request::HEAD); + $info = $response->getTransferInfo(); + + return (bool) ($info['http_code'] == 200); + } + + /** + * @param string|array|\Elastica\Query $query + * @param int|array $options + * + * @return \Elastica\Search + */ + public function createSearch($query = '', $options = null) + { + $search = new Search($this->getClient()); + $search->addIndex($this); + $search->setOptionsAndQuery($options, $query); + + return $search; + } + + /** + * Searches in this index. + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * + * @return \Elastica\ResultSet ResultSet with all results inside + * + * @see \Elastica\SearchableInterface::search + */ + public function search($query = '', $options = null) + { + $search = $this->createSearch($query, $options); + + return $search->search(); + } + + /** + * Counts results of query. + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * + * @return int number of documents matching the query + * + * @see \Elastica\SearchableInterface::count + */ + public function count($query = '') + { + $search = $this->createSearch($query); + + return $search->count(); + } + + /** + * Opens an index. + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html + */ + public function open() + { + return $this->request('_open', Request::POST); + } + + /** + * Closes the index. + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-open-close.html + */ + public function close() + { + return $this->request('_close', Request::POST); + } + + /** + * Returns the index name. + * + * @return string Index name + */ + public function getName() + { + return $this->_name; + } + + /** + * Returns index client. + * + * @return \Elastica\Client Index client object + */ + public function getClient() + { + return $this->_client; + } + + /** + * Adds an alias to the current index. + * + * @param string $name Alias name + * @param bool $replace OPTIONAL If set, an existing alias will be replaced + * + * @return \Elastica\Response Response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html + */ + public function addAlias($name, $replace = false) + { + $path = '_aliases'; + + $data = array('actions' => array()); + + if ($replace) { + $status = new Status($this->getClient()); + foreach ($status->getIndicesWithAlias($name) as $index) { + $data['actions'][] = array('remove' => array('index' => $index->getName(), 'alias' => $name)); + } + } + + $data['actions'][] = array('add' => array('index' => $this->getName(), 'alias' => $name)); + + return $this->getClient()->request($path, Request::POST, $data); + } + + /** + * Removes an alias pointing to the current index. + * + * @param string $name Alias name + * + * @return \Elastica\Response Response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html + */ + public function removeAlias($name) + { + $path = '_aliases'; + + $data = array('actions' => array(array('remove' => array('index' => $this->getName(), 'alias' => $name)))); + + return $this->getClient()->request($path, Request::POST, $data); + } + + /** + * Clears the cache of an index. + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-clearcache.html + */ + public function clearCache() + { + $path = '_cache/clear'; + // TODO: add additional cache clean arguments + return $this->request($path, Request::POST); + } + + /** + * Flushes the index to storage. + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-flush.html + */ + public function flush($refresh = false) + { + $path = '_flush'; + + return $this->request($path, Request::POST, array(), array('refresh' => $refresh)); + } + + /** + * Can be used to change settings during runtime. One example is to use it for bulk updating. + * + * @param array $data Data array + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html + */ + public function setSettings(array $data) + { + return $this->request('_settings', Request::PUT, $data); + } + + /** + * Makes calls to the elasticsearch server based on this index. + * + * @param string $path Path to call + * @param string $method Rest method to use (GET, POST, DELETE, PUT) + * @param array $data OPTIONAL Arguments as array + * @param array $query OPTIONAL Query params + * + * @return \Elastica\Response Response object + */ + public function request($path, $method, $data = array(), array $query = array()) + { + $path = $this->getName().'/'.$path; + + return $this->getClient()->request($path, $method, $data, $query); + } + + /** + * Analyzes a string. + * + * Detailed arguments can be found here in the link + * + * @param string $text String to be analyzed + * @param array $args OPTIONAL Additional arguments + * + * @return array Server response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-analyze.html + */ + public function analyze($text, $args = array()) + { + $data = $this->request('_analyze', Request::POST, $text, $args)->getData(); + + return $data['tokens']; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Index/Settings.php b/vendor/ruflin/elastica/lib/Elastica/Index/Settings.php new file mode 100644 index 00000000..f97e360a --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Index/Settings.php @@ -0,0 +1,366 @@ +<?php +namespace Elastica\Index; + +use Elastica\Exception\NotFoundException; +use Elastica\Exception\ResponseException; +use Elastica\Index as BaseIndex; +use Elastica\Request; + +/** + * Elastica index settings object. + * + * All settings listed in the update settings API (http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html) + * can be changed on a running indices. To make changes like the merge policy (http://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html) + * the index has to be closed first and reopened after the call + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html + */ +class Settings +{ + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Stats info. + * + * @var array Stats info + */ + protected $_data = array(); + + /** + * Index. + * + * @var \Elastica\Index Index object + */ + protected $_index = null; + + const DEFAULT_REFRESH_INTERVAL = '1s'; + + /** + * Construct. + * + * @param \Elastica\Index $index Index object + */ + public function __construct(BaseIndex $index) + { + $this->_index = $index; + } + + /** + * Returns the current settings of the index. + * + * If param is set, only specified setting is return. + * 'index.' is added in front of $setting. + * + * @param string $setting OPTIONAL Setting name to return + * + * @return array|string|null Settings data + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html + */ + public function get($setting = '') + { + $requestData = $this->request()->getData(); + $data = reset($requestData); + + if (empty($data['settings']) || empty($data['settings']['index'])) { + // should not append, the request should throw a ResponseException + throw new NotFoundException('Index '.$this->getIndex()->getName().' not found'); + } + $settings = $data['settings']['index']; + + if (!$setting) { + // return all array + return $settings; + } + + if (isset($settings[$setting])) { + return $settings[$setting]; + } else { + if (strpos($setting, '.') !== false) { + // translate old dot-notation settings to nested arrays + $keys = explode('.', $setting); + foreach ($keys as $key) { + if (isset($settings[$key])) { + $settings = $settings[$key]; + } else { + return; + } + } + + return $settings; + } + + return; + } + } + + /** + * Sets the number of replicas. + * + * @param int $replicas Number of replicas + * + * @return \Elastica\Response Response object + */ + public function setNumberOfReplicas($replicas) + { + $replicas = (int) $replicas; + + $data = array('number_of_replicas' => $replicas); + + return $this->set($data); + } + + /** + * Sets the index to read only. + * + * @param bool $readOnly (default = true) + * + * @return \Elastica\Response + */ + public function setReadOnly($readOnly = true) + { + return $this->set(array('blocks.write' => $readOnly)); + } + + /** + * getReadOnly. + * + * @return bool + */ + public function getReadOnly() + { + return $this->get('blocks.write') === 'true'; // ES returns a string for this setting + } + + /** + * @return bool + */ + public function getBlocksRead() + { + return (bool) $this->get('blocks.read'); + } + + /** + * @param bool $state OPTIONAL (default = true) + * + * @return \Elastica\Response + */ + public function setBlocksRead($state = true) + { + $state = $state ? 1 : 0; + + return $this->set(array('blocks.read' => $state)); + } + + /** + * @return bool + */ + public function getBlocksWrite() + { + return (bool) $this->get('blocks.write'); + } + + /** + * @param bool $state OPTIONAL (default = true) + * + * @return \Elastica\Response + */ + public function setBlocksWrite($state = true) + { + $state = $state ? 1 : 0; + + return $this->set(array('blocks.write' => $state)); + } + + /** + * @return bool + */ + public function getBlocksMetadata() + { + // TODO will have to be replace by block.metadata.write once https://github.com/elasticsearch/elasticsearch/pull/9203 has been fixed + // the try/catch will have to be remove too + try { + return (bool) $this->get('blocks.metadata'); + } catch (ResponseException $e) { + if (strpos($e->getMessage(), 'ClusterBlockException') !== false) { + // hacky way to test if the metadata is blocked since bug 9203 is not fixed + return true; + } else { + throw $e; + } + } + } + + /** + * @param bool $state OPTIONAL (default = true) + * + * @return \Elastica\Response + */ + public function setBlocksMetadata($state = true) + { + // TODO will have to be replace by block.metadata.write once https://github.com/elasticsearch/elasticsearch/pull/9203 has been fixed + $state = $state ? 1 : 0; + + return $this->set(array('blocks.metadata' => $state)); + } + + /** + * Sets the index refresh interval. + * + * Value can be for example 3s for 3 seconds or + * 5m for 5 minutes. -1 refreshing is disabled. + * + * @param int $interval Number of milliseconds + * + * @return \Elastica\Response Response object + */ + public function setRefreshInterval($interval) + { + return $this->set(array('refresh_interval' => $interval)); + } + + /** + * Returns the refresh interval. + * + * If no interval is set, the default interval is returned + * + * @return string Refresh interval + */ + public function getRefreshInterval() + { + $interval = $this->get('refresh_interval'); + + if (empty($interval)) { + $interval = self::DEFAULT_REFRESH_INTERVAL; + } + + return $interval; + } + + /** + * Return merge policy. + * + * @return string Merge policy type + */ + public function getMergePolicyType() + { + return $this->get('merge.policy.type'); + } + + /** + * Sets merge policy. + * + * @param string $type Merge policy type + * + * @return \Elastica\Response Response object + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html + */ + public function setMergePolicyType($type) + { + $this->getIndex()->close(); + $response = $this->set(array('merge.policy.type' => $type)); + $this->getIndex()->open(); + + return $response; + } + + /** + * Sets the specific merge policies. + * + * To have this changes made the index has to be closed and reopened + * + * @param string $key Merge policy key (for ex. expunge_deletes_allowed) + * @param string $value + * + * @return \Elastica\Response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html + */ + public function setMergePolicy($key, $value) + { + $this->getIndex()->close(); + $response = $this->set(array('merge.policy.'.$key => $value)); + $this->getIndex()->open(); + + return $response; + } + + /** + * Returns the specific merge policy value. + * + * @param string $key Merge policy key (for ex. expunge_deletes_allowed) + * + * @return string Refresh interval + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html + */ + public function getMergePolicy($key) + { + $settings = $this->get(); + if (isset($settings['merge']['policy'][$key])) { + return $settings['merge']['policy'][$key]; + } + + return; + } + + /** + * Can be used to set/update settings. + * + * @param array $data Arguments + * + * @return \Elastica\Response Response object + */ + public function set(array $data) + { + return $this->request($data, Request::PUT); + } + + /** + * Returns the index object. + * + * @return \Elastica\Index Index object + */ + public function getIndex() + { + return $this->_index; + } + + /** + * Updates the given settings for the index. + * + * With elasticsearch 0.16 the following settings are supported + * - index.term_index_interval + * - index.term_index_divisor + * - index.translog.flush_threshold_ops + * - index.translog.flush_threshold_size + * - index.translog.flush_threshold_period + * - index.refresh_interval + * - index.merge.policy + * - index.auto_expand_replicas + * + * @param array $data OPTIONAL Data array + * @param string $method OPTIONAL Transfer method (default = \Elastica\Request::GET) + * + * @return \Elastica\Response Response object + */ + public function request(array $data = array(), $method = Request::GET) + { + $path = '_settings'; + + if (!empty($data)) { + $data = array('index' => $data); + } + + return $this->getIndex()->request($path, $method, $data); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Index/Stats.php b/vendor/ruflin/elastica/lib/Elastica/Index/Stats.php new file mode 100644 index 00000000..d86903dc --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Index/Stats.php @@ -0,0 +1,108 @@ +<?php +namespace Elastica\Index; + +use Elastica\Index as BaseIndex; +use Elastica\Request; + +/** + * Elastica index stats object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-stats.html + */ +class Stats +{ + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Stats info. + * + * @var array Stats info + */ + protected $_data = array(); + + /** + * Index. + * + * @var \Elastica\Index Index object + */ + protected $_index = null; + + /** + * Construct. + * + * @param \Elastica\Index $index Index object + */ + public function __construct(BaseIndex $index) + { + $this->_index = $index; + $this->refresh(); + } + + /** + * Returns the raw stats info. + * + * @return array Stats info + */ + public function getData() + { + return $this->_data; + } + + /** + * Returns the entry in the data array based on the params. + * Various params possible. + * + * @return mixed Data array entry or null if not found + */ + public function get() + { + $data = $this->getData(); + + foreach (func_get_args() as $arg) { + if (isset($data[$arg])) { + $data = $data[$arg]; + } else { + return; + } + } + + return $data; + } + + /** + * Returns the index object. + * + * @return \Elastica\Index Index object + */ + public function getIndex() + { + return $this->_index; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Reloads all status data of this object. + */ + public function refresh() + { + $path = '_stats'; + $this->_response = $this->getIndex()->request($path, Request::GET); + $this->_data = $this->getResponse()->getData(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Index/Status.php b/vendor/ruflin/elastica/lib/Elastica/Index/Status.php new file mode 100644 index 00000000..0b9dff48 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Index/Status.php @@ -0,0 +1,150 @@ +<?php +namespace Elastica\Index; + +use Elastica\Index as BaseIndex; +use Elastica\Request; + +/** + * Elastica index status object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-status.html + */ +class Status +{ + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Stats info. + * + * @var array Stats info + */ + protected $_data = array(); + + /** + * Index. + * + * @var \Elastica\Index Index object + */ + protected $_index = null; + + /** + * Construct. + * + * @param \Elastica\Index $index Index object + */ + public function __construct(BaseIndex $index) + { + $this->_index = $index; + $this->refresh(); + } + + /** + * Returns all status info. + * + * @return array Status info + */ + public function getData() + { + return $this->_data; + } + + /** + * Returns the entry in the data array based on the params. + * Various params possible. + * + * @return mixed Data array entry or null if not found + */ + public function get() + { + $data = $this->getData(); + $data = $data['indices'][$this->getIndex()->getName()]; + + foreach (func_get_args() as $arg) { + if (isset($data[$arg])) { + $data = $data[$arg]; + } else { + return; + } + } + + return $data; + } + + /** + * Returns all index aliases. + * + * @return array Aliases + */ + public function getAliases() + { + $responseData = $this->getIndex()->request('_aliases', \Elastica\Request::GET)->getData(); + + $data = $responseData[$this->getIndex()->getName()]; + if (!empty($data['aliases'])) { + return array_keys($data['aliases']); + } + + return array(); + } + + /** + * Returns all index settings. + * + * @return array Index settings + */ + public function getSettings() + { + $responseData = $this->getIndex()->request('_settings', \Elastica\Request::GET)->getData(); + + return $responseData[$this->getIndex()->getName()]['settings']; + } + + /** + * Checks if the index has the given alias. + * + * @param string $name Alias name + * + * @return bool + */ + public function hasAlias($name) + { + return in_array($name, $this->getAliases()); + } + + /** + * Returns the index object. + * + * @return \Elastica\Index Index object + */ + public function getIndex() + { + return $this->_index; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Reloads all status data of this object. + */ + public function refresh() + { + $path = '_status'; + $this->_response = $this->getIndex()->request($path, Request::GET); + $this->_data = $this->getResponse()->getData(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/JSON.php b/vendor/ruflin/elastica/lib/Elastica/JSON.php new file mode 100644 index 00000000..921bc484 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/JSON.php @@ -0,0 +1,67 @@ +<?php +namespace Elastica; + +use Elastica\Exception\JSONParseException; + +/** + * Elastica JSON tools. + */ +class JSON +{ + /** + * Parse JSON string to an array. + * + * @link http://php.net/manual/en/function.json-decode.php + * @link http://php.net/manual/en/function.json-last-error.php + * + * @param string $json JSON string to parse + * + * @return array PHP array representation of JSON string + */ + public static function parse(/* inherit from json_decode */) + { + // extract arguments + $args = func_get_args(); + + // default to decoding into an assoc array + if (sizeof($args) === 1) { + $args[] = true; + } + + // run decode + $array = call_user_func_array('json_decode', $args); + + // turn errors into exceptions for easier catching + $error = json_last_error(); + if ($error !== JSON_ERROR_NONE) { + throw new JSONParseException($error); + } + + // output + return $array; + } + + /** + * Convert input to JSON string with standard options. + * + * @link http://php.net/manual/en/function.json-encode.php + * + * @param mixed check args for PHP function json_encode + * + * @return string Valid JSON representation of $input + */ + public static function stringify(/* inherit from json_encode */) + { + // extract arguments + $args = func_get_args(); + + // allow special options value for Elasticsearch compatibility + if (sizeof($args) > 1 && $args[1] === 'JSON_ELASTICSEARCH') { + // Use built in JSON constants if available (php >= 5.4) + $args[1] = defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 256; + } + + // run encode and output + return call_user_func_array('json_encode', $args); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Log.php b/vendor/ruflin/elastica/lib/Elastica/Log.php new file mode 100644 index 00000000..c2f0c18a --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Log.php @@ -0,0 +1,81 @@ +<?php +namespace Elastica; + +use Psr\Log\AbstractLogger; + +/** + * Elastica log object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Log extends AbstractLogger +{ + /** + * Log path or true if enabled. + * + * @var string|bool + */ + protected $_log = true; + + /** + * Last logged message. + * + * @var string Last logged message + */ + protected $_lastMessage = ''; + + /** + * Inits log object. + * + * @param string|bool String to set a specific file for logging + */ + public function __construct($log = '') + { + $this->setLog($log); + } + + /** + * Log a message. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return null|void + */ + public function log($level, $message, array $context = array()) + { + $context['error_message'] = $message; + $this->_lastMessage = JSON::stringify($context); + + if (!empty($this->_log) && is_string($this->_log)) { + error_log($this->_lastMessage.PHP_EOL, 3, $this->_log); + } else { + error_log($this->_lastMessage); + } + } + + /** + * Enable/disable log or set log path. + * + * @param bool|string $log Enables log or sets log path + * + * @return $this + */ + public function setLog($log) + { + $this->_log = $log; + + return $this; + } + + /** + * Return last logged message. + * + * @return string Last logged message + */ + public function getLastMessage() + { + return $this->_lastMessage; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Multi/ResultSet.php b/vendor/ruflin/elastica/lib/Elastica/Multi/ResultSet.php new file mode 100644 index 00000000..4d4186af --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Multi/ResultSet.php @@ -0,0 +1,205 @@ +<?php +namespace Elastica\Multi; + +use Elastica\Exception\InvalidException; +use Elastica\Response; +use Elastica\ResultSet as BaseResultSet; +use Elastica\Search as BaseSearch; + +/** + * Elastica multi search result set + * List of result sets for each search request. + * + * @author munkie + */ +class ResultSet implements \Iterator, \ArrayAccess, \Countable +{ + /** + * Result Sets. + * + * @var array|\Elastica\ResultSet[] Result Sets + */ + protected $_resultSets = array(); + + /** + * Current position. + * + * @var int Current position + */ + protected $_position = 0; + + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response; + + /** + * Constructs ResultSet object. + * + * @param \Elastica\Response $response + * @param array|\Elastica\Search[] $searches + */ + public function __construct(Response $response, array $searches) + { + $this->rewind(); + $this->_init($response, $searches); + } + + /** + * @param \Elastica\Response $response + * @param array|\Elastica\Search[] $searches + * + * @throws \Elastica\Exception\InvalidException + */ + protected function _init(Response $response, array $searches) + { + $this->_response = $response; + $responseData = $response->getData(); + + if (isset($responseData['responses']) && is_array($responseData['responses'])) { + reset($searches); + foreach ($responseData['responses'] as $key => $responseData) { + $currentSearch = each($searches); + + if ($currentSearch === false) { + throw new InvalidException('No result found for search #'.$key); + } elseif (!$currentSearch['value'] instanceof BaseSearch) { + throw new InvalidException('Invalid object for search #'.$key.' provided. Should be Elastica\Search'); + } + + $search = $currentSearch['value']; + $query = $search->getQuery(); + + $response = new Response($responseData); + $this->_resultSets[$currentSearch['key']] = new BaseResultSet($response, $query); + } + } + } + + /** + * @return array|\Elastica\ResultSet[] + */ + public function getResultSets() + { + return $this->_resultSets; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * There is at least one result set with error. + * + * @return bool + */ + public function hasError() + { + foreach ($this->getResultSets() as $resultSet) { + if ($resultSet->getResponse()->hasError()) { + return true; + } + } + + return false; + } + + /** + * @return bool|\Elastica\ResultSet + */ + public function current() + { + if ($this->valid()) { + return $this->_resultSets[$this->key()]; + } else { + return false; + } + } + + /** + */ + public function next() + { + $this->_position++; + } + + /** + * @return int + */ + public function key() + { + return $this->_position; + } + + /** + * @return bool + */ + public function valid() + { + return isset($this->_resultSets[$this->key()]); + } + + /** + */ + public function rewind() + { + $this->_position = 0; + } + + /** + * @return int + */ + public function count() + { + return count($this->_resultSets); + } + + /** + * @param string|int $offset + * + * @return bool true on success or false on failure. + */ + public function offsetExists($offset) + { + return isset($this->_resultSets[$offset]); + } + + /** + * @param mixed $offset + * + * @return mixed Can return all value types. + */ + public function offsetGet($offset) + { + return isset($this->_resultSets[$offset]) ? $this->_resultSets[$offset] : null; + } + + /** + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->_resultSets[] = $value; + } else { + $this->_resultSets[$offset] = $value; + } + } + + /** + * @param mixed $offset + */ + public function offsetUnset($offset) + { + unset($this->_resultSets[$offset]); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Multi/Search.php b/vendor/ruflin/elastica/lib/Elastica/Multi/Search.php new file mode 100644 index 00000000..294fc0a7 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Multi/Search.php @@ -0,0 +1,203 @@ +<?php +namespace Elastica\Multi; + +use Elastica\Client; +use Elastica\JSON; +use Elastica\Request; +use Elastica\Search as BaseSearch; + +/** + * Elastica multi search. + * + * @author munkie + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html + */ +class Search +{ + /** + * @var array|\Elastica\Search[] + */ + protected $_searches = array(); + + /** + * @var array + */ + protected $_options = array(); + + /** + * @var \Elastica\Client + */ + protected $_client; + + /** + * Constructs search object. + * + * @param \Elastica\Client $client Client object + */ + public function __construct(Client $client) + { + $this->setClient($client); + } + + /** + * @return \Elastica\Client + */ + public function getClient() + { + return $this->_client; + } + + /** + * @param \Elastica\Client $client + * + * @return $this + */ + public function setClient(Client $client) + { + $this->_client = $client; + + return $this; + } + + /** + * @return $this + */ + public function clearSearches() + { + $this->_searches = array(); + + return $this; + } + + /** + * @param \Elastica\Search $search + * @param string $key Optional key + * + * @return $this + */ + public function addSearch(BaseSearch $search, $key = null) + { + if ($key) { + $this->_searches[$key] = $search; + } else { + $this->_searches[] = $search; + } + + return $this; + } + + /** + * @param array|\Elastica\Search[] $searches + * + * @return $this + */ + public function addSearches(array $searches) + { + foreach ($searches as $key => $search) { + $this->addSearch($search, $key); + } + + return $this; + } + + /** + * @param array|\Elastica\Search[] $searches + * + * @return $this + */ + public function setSearches(array $searches) + { + $this->clearSearches(); + $this->addSearches($searches); + + return $this; + } + + /** + * @return array|\Elastica\Search[] + */ + public function getSearches() + { + return $this->_searches; + } + + /** + * @param string $searchType + * + * @return $this + */ + public function setSearchType($searchType) + { + $this->_options[BaseSearch::OPTION_SEARCH_TYPE] = $searchType; + + return $this; + } + + /** + * @return \Elastica\Multi\ResultSet + */ + public function search() + { + $data = $this->_getData(); + + $response = $this->getClient()->request( + '_msearch', + Request::POST, + $data, + $this->_options + ); + + return new ResultSet($response, $this->getSearches()); + } + + /** + * @return string + */ + protected function _getData() + { + $data = ''; + foreach ($this->getSearches() as $search) { + $data .= $this->_getSearchData($search); + } + + return $data; + } + + /** + * @param \Elastica\Search $search + * + * @return string + */ + protected function _getSearchData(BaseSearch $search) + { + $header = $this->_getSearchDataHeader($search); + $header = (empty($header)) ? new \stdClass() : $header; + $query = $search->getQuery(); + + $data = JSON::stringify($header)."\n"; + $data .= JSON::stringify($query->toArray())."\n"; + + return $data; + } + + /** + * @param \Elastica\Search $search + * + * @return array + */ + protected function _getSearchDataHeader(BaseSearch $search) + { + $header = $search->getOptions(); + + if ($search->hasIndices()) { + $header['index'] = $search->getIndices(); + } + + if ($search->hasTypes()) { + $header['types'] = $search->getTypes(); + } + + return $header; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Node.php b/vendor/ruflin/elastica/lib/Elastica/Node.php new file mode 100644 index 00000000..1453418d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Node.php @@ -0,0 +1,161 @@ +<?php +namespace Elastica; + +use Elastica\Node\Info; +use Elastica\Node\Stats; + +/** + * Elastica cluster node object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Node +{ + /** + * Client. + * + * @var \Elastica\Client + */ + protected $_client = null; + + /** + * @var string Unique node id + */ + protected $_id = ''; + + /** + * Node name. + * + * @var string Node name + */ + protected $_name = ''; + + /** + * Node stats. + * + * @var \Elastica\Node\Stats Node Stats + */ + protected $_stats = null; + + /** + * Node info. + * + * @var \Elastica\Node\Info Node info + */ + protected $_info = null; + + /** + * Create a new node object. + * + * @param string $id Node id or name + * @param \Elastica\Client $client Node object + */ + public function __construct($id, Client $client) + { + $this->_client = $client; + $this->setId($id); + } + + /** + * @return string Unique node id. Can also be name if id not exists. + */ + public function getId() + { + return $this->_id; + } + + /** + * @param string $id Node id + * + * @return $this Refreshed object + */ + public function setId($id) + { + $this->_id = $id; + + return $this->refresh(); + } + + /** + * Get the name of the node. + * + * @return string Node name + */ + public function getName() + { + if (empty($this->_name)) { + $this->_name = $this->getInfo()->getName(); + } + + return $this->_name; + } + + /** + * Returns the current client object. + * + * @return \Elastica\Client Client + */ + public function getClient() + { + return $this->_client; + } + + /** + * Return stats object of the current node. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-stats.html + * + * @return \Elastica\Node\Stats Node stats + */ + public function getStats() + { + if (!$this->_stats) { + $this->_stats = new Stats($this); + } + + return $this->_stats; + } + + /** + * Return info object of the current node. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-info.html + * + * @return \Elastica\Node\Info Node info object + */ + public function getInfo() + { + if (!$this->_info) { + $this->_info = new Info($this); + } + + return $this->_info; + } + + /** + * Refreshes all node information. + * + * This should be called after updating a node to refresh all information + */ + public function refresh() + { + $this->_stats = null; + $this->_info = null; + } + + /** + * Shuts this node down. + * + * @param string $delay OPTIONAL Delay after which node is shut down (default = 1s) + * + * @return \Elastica\Response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-shutdown.html + */ + public function shutdown($delay = '1s') + { + $path = '_cluster/nodes/'.$this->getId().'/_shutdown?delay='.$delay; + + return $this->_client->request($path, Request::POST); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Node/Info.php b/vendor/ruflin/elastica/lib/Elastica/Node/Info.php new file mode 100644 index 00000000..25734641 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Node/Info.php @@ -0,0 +1,220 @@ +<?php +namespace Elastica\Node; + +use Elastica\Node as BaseNode; +use Elastica\Request; + +/** + * Elastica cluster node object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-status.html + */ +class Info +{ + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Stats data. + * + * @var array stats data + */ + protected $_data = array(); + + /** + * Node. + * + * @var \Elastica\Node Node object + */ + protected $_node = null; + + /** + * Query parameters. + * + * @var array + */ + protected $_params = array(); + + /** + * Create new info object for node. + * + * @param \Elastica\Node $node Node object + * @param array $params List of params to return. Can be: settings, os, process, jvm, thread_pool, network, transport, http + */ + public function __construct(BaseNode $node, array $params = array()) + { + $this->_node = $node; + $this->refresh($params); + } + + /** + * Returns the entry in the data array based on the params. + * Several params possible. + * + * Example 1: get('os', 'mem', 'total') returns total memory of the system the + * node is running on + * Example 2: get('os', 'mem') returns an array with all mem infos + * + * @return mixed Data array entry or null if not found + */ + public function get() + { + $data = $this->getData(); + + foreach (func_get_args() as $arg) { + if (isset($data[$arg])) { + $data = $data[$arg]; + } else { + return; + } + } + + return $data; + } + + /** + * Return port of the node. + * + * @return string Returns Node port + */ + public function getPort() + { + // Returns string in format: inet[/192.168.1.115:9201] + $data = $this->get('http_address'); + $data = substr($data, 6, strlen($data) - 7); + $data = explode(':', $data); + + return $data[1]; + } + + /** + * Return IP of the node. + * + * @return string Returns Node ip address + */ + public function getIp() + { + // Returns string in format: inet[/192.168.1.115:9201] + $data = $this->get('http_address'); + $data = substr($data, 6, strlen($data) - 7); + $data = explode(':', $data); + + return $data[0]; + } + + /** + * Return data regarding plugins installed on this node. + * + * @return array plugin data + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-nodes-info.html + */ + public function getPlugins() + { + if (!in_array('plugins', $this->_params)) { + //Plugin data was not retrieved when refresh() was called last. Get it now. + $this->_params[] = 'plugins'; + $this->refresh($this->_params); + } + + return $this->get('plugins'); + } + + /** + * Check if the given plugin is installed on this node. + * + * @param string $name plugin name + * + * @return bool true if the plugin is installed, false otherwise + */ + public function hasPlugin($name) + { + foreach ($this->getPlugins() as $plugin) { + if ($plugin['name'] == $name) { + return true; + } + } + + return false; + } + + /** + * Return all info data. + * + * @return array Data array + */ + public function getData() + { + return $this->_data; + } + + /** + * Return node object. + * + * @return \Elastica\Node Node object + */ + public function getNode() + { + return $this->_node; + } + + /** + * @return string Unique node id + */ + public function getId() + { + return $this->_id; + } + + /** + * @return string Node name + */ + public function getName() + { + return $this->_data['name']; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Reloads all nodes information. Has to be called if informations changed. + * + * @param array $params Params to return (default none). Possible options: settings, os, process, jvm, thread_pool, network, transport, http, plugin + * + * @return \Elastica\Response Response object + */ + public function refresh(array $params = array()) + { + $this->_params = $params; + + $path = '_nodes/'.$this->getNode()->getId(); + + if (!empty($params)) { + $path .= '?'; + foreach ($params as $param) { + $path .= $param.'=true&'; + } + } + + $this->_response = $this->getNode()->getClient()->request($path, Request::GET); + $data = $this->getResponse()->getData(); + + $this->_data = reset($data['nodes']); + $this->_id = key($data['nodes']); + $this->getNode()->setId($this->getId()); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Node/Stats.php b/vendor/ruflin/elastica/lib/Elastica/Node/Stats.php new file mode 100644 index 00000000..1af94b07 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Node/Stats.php @@ -0,0 +1,113 @@ +<?php +namespace Elastica\Node; + +use Elastica\Node as BaseNode; +use Elastica\Request; + +/** + * Elastica cluster node object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-status.html + */ +class Stats +{ + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Stats data. + * + * @var array stats data + */ + protected $_data = array(); + + /** + * Node. + * + * @var \Elastica\Node Node object + */ + protected $_node = null; + + /** + * Create new stats for node. + * + * @param \Elastica\Node $node Elastica node object + */ + public function __construct(BaseNode $node) + { + $this->_node = $node; + $this->refresh(); + } + + /** + * Returns all node stats as array based on the arguments. + * + * Several arguments can be use + * get('index', 'test', 'example') + * + * @return array Node stats for the given field or null if not found + */ + public function get() + { + $data = $this->getData(); + + foreach (func_get_args() as $arg) { + if (isset($data[$arg])) { + $data = $data[$arg]; + } else { + return; + } + } + + return $data; + } + + /** + * Returns all stats data. + * + * @return array Data array + */ + public function getData() + { + return $this->_data; + } + + /** + * Returns node object. + * + * @return \Elastica\Node Node object + */ + public function getNode() + { + return $this->_node; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Reloads all nodes information. Has to be called if informations changed. + * + * @return \Elastica\Response Response object + */ + public function refresh() + { + $path = '_nodes/'.$this->getNode()->getName().'/stats'; + $this->_response = $this->getNode()->getClient()->request($path, Request::GET); + $data = $this->getResponse()->getData(); + $this->_data = reset($data['nodes']); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Param.php b/vendor/ruflin/elastica/lib/Elastica/Param.php new file mode 100644 index 00000000..484fbbc3 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Param.php @@ -0,0 +1,167 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; + +/** + * Class to handle params. + * + * This function can be used to handle params for queries, filter, facets + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Param +{ + /** + * Params. + * + * @var array + */ + protected $_params = array(); + + /** + * Raw Params. + * + * @var array + */ + protected $_rawParams = array(); + + /** + * Converts the params to an array. A default implementation exist to create + * the an array out of the class name (last part of the class name) + * and the params. + * + * @return array Filter array + */ + public function toArray() + { + $data = array($this->_getBaseName() => $this->getParams()); + + if (!empty($this->_rawParams)) { + $data = array_merge($data, $this->_rawParams); + } + + return $data; + } + + /** + * Param's name + * Picks the last part of the class name and makes it snake_case + * You can override this method if you want to change the name. + * + * @return string name + */ + protected function _getBaseName() + { + return Util::getParamName($this); + } + + /** + * Sets params not inside params array. + * + * @param string $key + * @param mixed $value + * + * @return $this + */ + protected function _setRawParam($key, $value) + { + $this->_rawParams[$key] = $value; + + return $this; + } + + /** + * Sets (overwrites) the value at the given key. + * + * @param string $key Key to set + * @param mixed $value Key Value + * + * @return $this + */ + public function setParam($key, $value) + { + $this->_params[$key] = $value; + + return $this; + } + + /** + * Sets (overwrites) all params of this object. + * + * @param array $params Parameter list + * + * @return $this + */ + public function setParams(array $params) + { + $this->_params = $params; + + return $this; + } + + /** + * Adds a param to the list. + * + * This function can be used to add an array of params + * + * @param string $key Param key + * @param mixed $value Value to set + * + * @return $this + */ + public function addParam($key, $value) + { + if ($key != null) { + if (!isset($this->_params[$key])) { + $this->_params[$key] = array(); + } + + $this->_params[$key][] = $value; + } else { + $this->_params = $value; + } + + return $this; + } + + /** + * Returns a specific param. + * + * @param string $key Key to return + * + * @throws \Elastica\Exception\InvalidException If requested key is not set + * + * @return mixed Key value + */ + public function getParam($key) + { + if (!$this->hasParam($key)) { + throw new InvalidException('Param '.$key.' does not exist'); + } + + return $this->_params[$key]; + } + + /** + * Test if a param is set. + * + * @param string $key Key to test + * + * @return bool True if the param is set, false otherwise + */ + public function hasParam($key) + { + return isset($this->_params[$key]); + } + + /** + * Returns the params array. + * + * @return array Params + */ + public function getParams() + { + return $this->_params; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Percolator.php b/vendor/ruflin/elastica/lib/Elastica/Percolator.php new file mode 100644 index 00000000..98d0490a --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Percolator.php @@ -0,0 +1,194 @@ +<?php +namespace Elastica; + +/** + * Percolator class. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-percolate.html + */ +class Percolator +{ + const EXTRA_FILTER = 'filter'; + const EXTRA_QUERY = 'query'; + const EXTRA_SIZE = 'size'; + const EXTRA_TRACK_SCORES = 'track_scores'; + const EXTRA_SORT = 'sort'; + const EXTRA_FACETS = 'facets'; + const EXTRA_AGGS = 'aggs'; + const EXTRA_HIGHLIGHT = 'highlight'; + + private $_extraRequestBodyOptions = array( + self::EXTRA_FILTER, + self::EXTRA_QUERY, + self::EXTRA_SIZE, + self::EXTRA_TRACK_SCORES, + self::EXTRA_SORT, + self::EXTRA_FACETS, + self::EXTRA_AGGS, + self::EXTRA_HIGHLIGHT, + ); + + /** + * Index object. + * + * @var \Elastica\Index + */ + protected $_index = null; + + /** + * Construct new percolator. + * + * @param \Elastica\Index $index + */ + public function __construct(Index $index) + { + $this->_index = $index; + } + + /** + * Registers a percolator query, with optional extra fields to include in the registered query. + * + * @param string $name Query name + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query Query to add + * @param array $fields Extra fields to include in the registered query + * and can be used to filter executed queries. + * + * @return \Elastica\Response + */ + public function registerQuery($name, $query, $fields = array()) + { + $path = $this->_index->getName().'/.percolator/'.$name; + $query = Query::create($query); + + $data = array_merge($query->toArray(), $fields); + + return $this->_index->getClient()->request($path, Request::PUT, $data); + } + + /** + * Removes a percolator query. + * + * @param string $name query name + * + * @return \Elastica\Response + */ + public function unregisterQuery($name) + { + $path = $this->_index->getName().'/.percolator/'.$name; + + return $this->_index->getClient()->request($path, Request::DELETE); + } + + /** + * Match a document to percolator queries. + * + * @param \Elastica\Document $doc + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query Query to filter the percolator queries which + * are executed. + * @param string $type + * @param array $params Supports setting additional request body options to the percolate request. + * [ Percolator::EXTRA_FILTER, + * Percolator::EXTRA_QUERY, + * Percolator::EXTRA_SIZE, + * Percolator::EXTRA_TRACK_SCORES, + * Percolator::EXTRA_SORT, + * Percolator::EXTRA_FACETS, + * Percolator::EXTRA_AGGS, + * Percolator::EXTRA_HIGHLIGHT ] + * + * @return array With matching registered queries. + */ + public function matchDoc(Document $doc, $query = null, $type = 'type', $params = array()) + { + $path = $this->_index->getName().'/'.$type.'/_percolate'; + $data = array('doc' => $doc->getData()); + + $this->_applyAdditionalRequestBodyOptions($params, $data); + + return $this->_percolate($path, $query, $data, $params); + } + + /** + * Percolating an existing document. + * + * @param string $id + * @param string $type + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query Query to filter the percolator queries which + * are executed. + * @param array $params Supports setting additional request body options to the percolate request. + * [ Percolator::EXTRA_FILTER, + * Percolator::EXTRA_QUERY, + * Percolator::EXTRA_SIZE, + * Percolator::EXTRA_TRACK_SCORES, + * Percolator::EXTRA_SORT, + * Percolator::EXTRA_FACETS, + * Percolator::EXTRA_AGGS, + * Percolator::EXTRA_HIGHLIGHT ] + * + * @return array With matching registered queries. + */ + public function matchExistingDoc($id, $type, $query = null, $params = array()) + { + $id = urlencode($id); + $path = $this->_index->getName().'/'.$type.'/'.$id.'/_percolate'; + + $data = array(); + $this->_applyAdditionalRequestBodyOptions($params, $data); + + return $this->_percolate($path, $query, $data, $params); + } + + /** + * Process the provided parameters and apply them to the data array. + * + * @param &$params + * @param &$data + */ + protected function _applyAdditionalRequestBodyOptions(&$params, &$data) + { + foreach ($params as $key => $value) { + if (in_array($key, $this->_extraRequestBodyOptions)) { + $data[$key] = $params[$key]; + unset($params[$key]); + } + } + } + + /** + * @param string $path + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query] $query [description] + * @param array $data + * @param array $params + * + * @return array + */ + protected function _percolate($path, $query, $data = array(), $params = array()) + { + // Add query to filter the percolator queries which are executed. + if ($query) { + $query = Query::create($query); + $data['query'] = $query->getQuery(); + } + + $response = $this->getIndex()->getClient()->request($path, Request::GET, $data, $params); + $data = $response->getData(); + + if (isset($data['matches'])) { + return $data['matches']; + } + + return array(); + } + + /** + * Return index object. + * + * @return \Elastica\Index + */ + public function getIndex() + { + return $this->_index; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query.php b/vendor/ruflin/elastica/lib/Elastica/Query.php new file mode 100644 index 00000000..175c8c95 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query.php @@ -0,0 +1,488 @@ +<?php +namespace Elastica; + +use Elastica\Aggregation\AbstractAggregation; +use Elastica\Exception\InvalidException; +use Elastica\Exception\NotImplementedException; +use Elastica\Facet\AbstractFacet; +use Elastica\Filter\AbstractFilter; +use Elastica\Query\AbstractQuery; +use Elastica\Query\MatchAll; +use Elastica\Query\QueryString; +use Elastica\Suggest\AbstractSuggest; + +/** + * Elastica query object. + * + * Creates different types of queries + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html + */ +class Query extends Param +{ + /** + * Params. + * + * @var array Params + */ + protected $_params = array(); + + /** + * Suggest query or not. + * + * @var int Suggest + */ + protected $_suggest = 0; + + /** + * Creates a query object. + * + * @param array|\Elastica\Query\AbstractQuery $query OPTIONAL Query object (default = null) + */ + public function __construct($query = null) + { + if (is_array($query)) { + $this->setRawQuery($query); + } elseif ($query instanceof AbstractQuery) { + $this->setQuery($query); + } elseif ($query instanceof Suggest) { + $this->setSuggest($query); + } + } + + /** + * Transforms a string or an array to a query object. + * + * If query is empty, + * + * @param mixed $query + * + * @throws \Elastica\Exception\NotImplementedException + * + * @return self + */ + public static function create($query) + { + switch (true) { + case $query instanceof self: + return $query; + case $query instanceof AbstractQuery: + return new self($query); + case $query instanceof AbstractFilter: + $newQuery = new self(); + $newQuery->setPostFilter($query); + + return $newQuery; + case empty($query): + return new self(new MatchAll()); + case is_array($query): + return new self($query); + case is_string($query): + return new self(new QueryString($query)); + case $query instanceof AbstractSuggest: + return new self(new Suggest($query)); + + case $query instanceof Suggest: + return new self($query); + + } + + // TODO: Implement queries without + throw new NotImplementedException(); + } + + /** + * Sets query as raw array. Will overwrite all already set arguments. + * + * @param array $query Query array + * + * @return $this + */ + public function setRawQuery(array $query) + { + $this->_params = $query; + + return $this; + } + + /** + * Sets the query. + * + * @param \Elastica\Query\AbstractQuery $query Query object + * + * @return $this + */ + public function setQuery(AbstractQuery $query) + { + return $this->setParam('query', $query->toArray()); + } + + /** + * Gets the query array. + * + * @return array + **/ + public function getQuery() + { + return $this->getParam('query'); + } + + /** + * Set Filter. + * + * @param \Elastica\Filter\AbstractFilter $filter Filter object + * + * @return $this + * + * @link https://github.com/elasticsearch/elasticsearch/issues/7422 + * @deprecated + */ + public function setFilter(AbstractFilter $filter) + { + trigger_error('Deprecated: Elastica\Query::setFilter() is deprecated. Use Elastica\Query::setPostFilter() instead.', E_USER_DEPRECATED); + + return $this->setPostFilter($filter); + } + + /** + * Sets the start from which the search results should be returned. + * + * @param int $from + * + * @return $this + */ + public function setFrom($from) + { + return $this->setParam('from', $from); + } + + /** + * Sets sort arguments for the query + * Replaces existing values. + * + * @param array $sortArgs Sorting arguments + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html + */ + public function setSort(array $sortArgs) + { + return $this->setParam('sort', $sortArgs); + } + + /** + * Adds a sort param to the query. + * + * @param mixed $sort Sort parameter + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html + */ + public function addSort($sort) + { + return $this->addParam('sort', $sort); + } + + /** + * Sets highlight arguments for the query. + * + * @param array $highlightArgs Set all highlight arguments + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html + */ + public function setHighlight(array $highlightArgs) + { + return $this->setParam('highlight', $highlightArgs); + } + + /** + * Adds a highlight argument. + * + * @param mixed $highlight Add highlight argument + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html + */ + public function addHighlight($highlight) + { + return $this->addParam('highlight', $highlight); + } + + /** + * Sets maximum number of results for this query. + * + * @param int $size OPTIONAL Maximal number of results for query (default = 10) + * + * @return $this + */ + public function setSize($size = 10) + { + return $this->setParam('size', $size); + } + + /** + * Alias for setSize. + * + * @deprecated Use the setSize() method, this method will be removed in future releases + * + * @param int $limit OPTIONAL Maximal number of results for query (default = 10) + * + * @return $this + */ + public function setLimit($limit = 10) + { + return $this->setSize($limit); + } + + /** + * Enables explain on the query. + * + * @param bool $explain OPTIONAL Enabled or disable explain (default = true) + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-explain.html + */ + public function setExplain($explain = true) + { + return $this->setParam('explain', $explain); + } + + /** + * Enables version on the query. + * + * @param bool $version OPTIONAL Enabled or disable version (default = true) + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-version.html + */ + public function setVersion($version = true) + { + return $this->setParam('version', $version); + } + + /** + * Sets the fields to be returned by the search + * NOTICE php will encode modified(or named keys) array into object format in json format request + * so the fields array must a sequence(list) type of array. + * + * @param array $fields Fields to be returned + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-fields.html + */ + public function setFields(array $fields) + { + return $this->setParam('fields', $fields); + } + + /** + * Set script fields. + * + * @param array|\Elastica\ScriptFields $scriptFields Script fields + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html + */ + public function setScriptFields($scriptFields) + { + if (is_array($scriptFields)) { + $scriptFields = new ScriptFields($scriptFields); + } + + return $this->setParam('script_fields', $scriptFields->toArray()); + } + + /** + * Adds a Script to the query. + * + * @param string $name + * @param \Elastica\Script $script Script object + * + * @return $this + */ + public function addScriptField($name, Script $script) + { + $this->_params['script_fields'][$name] = $script->toArray(); + + return $this; + } + + /** + * Sets all facets for this query object. Replaces existing facets. + * + * @param array $facets List of facet objects + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-facets.html + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ + public function setFacets(array $facets) + { + $this->_params['facets'] = array(); + foreach ($facets as $facet) { + $this->addFacet($facet); + } + + return $this; + } + + /** + * Adds a Facet to the query. + * + * @param \Elastica\Facet\AbstractFacet $facet Facet object + * + * @return $this + * + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ + public function addFacet(AbstractFacet $facet) + { + $this->_params['facets'][$facet->getName()] = $facet->toArray(); + + return $this; + } + + /** + * Adds an Aggregation to the query. + * + * @param AbstractAggregation $agg + * + * @return $this + */ + public function addAggregation(AbstractAggregation $agg) + { + if (!array_key_exists('aggs', $this->_params)) { + $this->_params['aggs'] = array(); + } + $this->_params['aggs'][$agg->getName()] = $agg->toArray(); + + return $this; + } + + /** + * Converts all query params to an array. + * + * @return array Query array + */ + public function toArray() + { + if (!isset($this->_params['query']) && ($this->_suggest == 0)) { + $this->setQuery(new MatchAll()); + } + + if (isset($this->_params['facets']) && 0 === count($this->_params['facets'])) { + unset($this->_params['facets']); + } + + if (isset($this->_params['post_filter']) && 0 === count($this->_params['post_filter'])) { + unset($this->_params['post_filter']); + } + + return $this->_params; + } + + /** + * Allows filtering of documents based on a minimum score. + * + * @param int $minScore Minimum score to filter documents by + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function setMinScore($minScore) + { + if (!is_numeric($minScore)) { + throw new InvalidException('has to be numeric param'); + } + + return $this->setParam('min_score', $minScore); + } + + /** + * Add a suggest term. + * + * @param \Elastica\Suggest $suggest suggestion object + * + * @return $this + */ + public function setSuggest(Suggest $suggest) + { + $this->setParams(array_merge( + $this->getParams(), + $suggest->toArray() + )); + + $this->_suggest = 1; + + return $this; + } + + /** + * Add a Rescore. + * + * @param mixed $rescore suggestion object + * + * @return $this + */ + public function setRescore($rescore) + { + if (is_array($rescore)) { + $buffer = array(); + + foreach ($rescore as $rescoreQuery) { + $buffer [] = $rescoreQuery->toArray(); + } + } else { + $buffer = $rescore->toArray(); + } + + return $this->setParam('rescore', $buffer); + } + + /** + * Sets the _source field to be returned with every hit. + * + * @param array|bool $params Fields to be returned or false to disable source + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html + */ + public function setSource($params) + { + return $this->setParam('_source', $params); + } + + /** + * Sets post_filter argument for the query. The filter is applied after the query has executed. + * + * @param array|\Elastica\Filter\AbstractFilter $filter + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-post-filter.html + */ + public function setPostFilter($filter) + { + if ($filter instanceof AbstractFilter) { + $filter = $filter->toArray(); + } else { + trigger_error('Deprecated: Elastica\Query::setPostFilter() passing filter as array is deprecated. Pass instance of AbstractFilter instead.', E_USER_DEPRECATED); + } + + return $this->setParam('post_filter', $filter); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/AbstractQuery.php b/vendor/ruflin/elastica/lib/Elastica/Query/AbstractQuery.php new file mode 100644 index 00000000..fd1c29b0 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/AbstractQuery.php @@ -0,0 +1,13 @@ +<?php +namespace Elastica\Query; + +use Elastica\Param; + +/** + * Abstract query object. Should be extended by all query types. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +abstract class AbstractQuery extends Param +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Bool.php b/vendor/ruflin/elastica/lib/Elastica/Query/Bool.php new file mode 100644 index 00000000..c5bccc54 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Bool.php @@ -0,0 +1,15 @@ +<?php +namespace Elastica\Query; + +/** + * Bool query. + * + * This class is for backward compatibility reason for all php < 7 versions. For PHP 7 and above use BoolFilter as Bool is reserved. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html + */ +class Bool extends BoolQuery +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/BoolQuery.php b/vendor/ruflin/elastica/lib/Elastica/Query/BoolQuery.php new file mode 100644 index 00000000..7b8bd4da --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/BoolQuery.php @@ -0,0 +1,111 @@ +<?php +namespace Elastica\Query; + +use Elastica\Exception\InvalidException; + +/** + * Bool query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html + */ +class BoolQuery extends AbstractQuery +{ + /** + * Add should part to query. + * + * @param \Elastica\Query\AbstractQuery|array $args Should query + * + * @return $this + */ + public function addShould($args) + { + return $this->_addQuery('should', $args); + } + + /** + * Add must part to query. + * + * @param \Elastica\Query\AbstractQuery|array $args Must query + * + * @return $this + */ + public function addMust($args) + { + return $this->_addQuery('must', $args); + } + + /** + * Add must not part to query. + * + * @param \Elastica\Query\AbstractQuery|array $args Must not query + * + * @return $this + */ + public function addMustNot($args) + { + return $this->_addQuery('must_not', $args); + } + + /** + * Adds a query to the current object. + * + * @param string $type Query type + * @param \Elastica\Query\AbstractQuery|array $args Query + * + * @throws \Elastica\Exception\InvalidException If not valid query + * + * @return $this + */ + protected function _addQuery($type, $args) + { + if ($args instanceof AbstractQuery) { + $args = $args->toArray(); + } + + if (!is_array($args)) { + throw new InvalidException('Invalid parameter. Has to be array or instance of Elastica\Query\AbstractQuery'); + } + + return $this->addParam($type, $args); + } + + /** + * Sets boost value of this query. + * + * @param float $boost Boost value + * + * @return $this + */ + public function setBoost($boost) + { + return $this->setParam('boost', $boost); + } + + /** + * Set the minimum number of of should match. + * + * @param int $minimumNumberShouldMatch Should match minimum + * + * @return $this + */ + public function setMinimumNumberShouldMatch($minimumNumberShouldMatch) + { + return $this->setParam('minimum_number_should_match', $minimumNumberShouldMatch); + } + + /** + * Converts array to an object in case no queries are added. + * + * @return array + */ + public function toArray() + { + if (empty($this->_params)) { + $this->_params = new \stdClass(); + } + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Boosting.php b/vendor/ruflin/elastica/lib/Elastica/Query/Boosting.php new file mode 100644 index 00000000..95dcde3d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Boosting.php @@ -0,0 +1,50 @@ +<?php +namespace Elastica\Query; + +/** + * Class Boosting. + * + * @author Balazs Nadasdi <yitsushi@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html + */ +class Boosting extends AbstractQuery +{ + const NEGATIVE_BOOST = 0.2; + + /** + * Set the positive query for this Boosting Query. + * + * @param AbstractQuery $query + * + * @return $this + */ + public function setPositiveQuery(AbstractQuery $query) + { + return $this->setParam('positive', $query->toArray()); + } + + /** + * Set the negative query for this Boosting Query. + * + * @param AbstractQuery $query + * + * @return $this + */ + public function setNegativeQuery(AbstractQuery $query) + { + return $this->setParam('negative', $query->toArray()); + } + + /** + * Set the negative_boost parameter for this Boosting Query. + * + * @param Float $negativeBoost + * + * @return $this + */ + public function setNegativeBoost($negativeBoost) + { + return $this->setParam('negative_boost', (float) $negativeBoost); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Builder.php b/vendor/ruflin/elastica/lib/Elastica/Query/Builder.php new file mode 100644 index 00000000..55b6b903 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Builder.php @@ -0,0 +1,935 @@ +<?php +namespace Elastica\Query; + +use Elastica\Exception\InvalidException; +use Elastica\Exception\JSONParseException; +use Elastica\JSON; + +/** + * Query Builder. + * + * @author Chris Gedrim <chris@gedr.im> + * + * @link http://www.elastic.co/ + * @deprecated This builder is deprecated and will be removed. Use new Elastica\QueryBuilder instead. + **/ +class Builder extends AbstractQuery +{ + /** + * Query string. + * + * @var string + */ + private $_string = '{'; + + /** + * Factory method. + * + * @param string $string JSON encoded string to use as query. + * + * @return self + */ + public static function factory($string = null) + { + return new self($string); + } + + /** + * Constructor. + * + * @param string $string JSON encoded string to use as query. + */ + public function __construct($string = null) + { + if (!$string == null) { + $this->_string .= substr($string, 1, -1); + } + } + + /** + * Output the query string. + * + * @return string + */ + public function __toString() + { + return rtrim($this->_string, ',').'}'; + } + + /** + * {@inheritdoc} + */ + public function toArray() + { + try { + return JSON::parse($input = $this->__toString()); + } catch (JSONParseException $e) { + throw new InvalidException(sprintf( + 'The produced query is not a valid json string : "%s"', + $input + )); + } + } + + /** + * Allow wildcards (*, ?) as the first character in a query. + * + * @param bool $bool Defaults to true. + * + * @return $this + */ + public function allowLeadingWildcard($bool = true) + { + return $this->field('allow_leading_wildcard', (bool) $bool); + } + + /** + * Enable best effort analysis of wildcard terms. + * + * @param bool $bool Defaults to true. + * + * @return $this + */ + public function analyzeWildcard($bool = true) + { + return $this->field('analyze_wildcard', (bool) $bool); + } + + /** + * Set the analyzer name used to analyze the query string. + * + * @param string $analyzer Analyzer to use. + * + * @return $this + */ + public function analyzer($analyzer) + { + return $this->field('analyzer', $analyzer); + } + + /** + * Autogenerate phrase queries. + * + * @param bool $bool Defaults to true. + * + * @return $this + */ + public function autoGeneratePhraseQueries($bool = true) + { + return $this->field('auto_generate_phrase_queries', (bool) $bool); + } + + /** + * Bool Query. + * + * A query that matches documents matching boolean combinations of other queries. + * + * The bool query maps to Lucene BooleanQuery. + * + * It is built using one or more boolean clauses, each clause with a typed + * occurrence. + * + * The occurrence types are: must, should, must_not. + * + * @return $this + */ + public function bool() + { + return $this->fieldOpen('bool'); + } + + /** + * Close a 'bool' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function boolClose() + { + return $this->fieldClose(); + } + + /** + * Sets the boost value of the query. + * + * @param float $boost Defaults to 1.0. + * + * @return $this + */ + public function boost($boost = 1.0) + { + return $this->field('boost', (float) $boost); + } + + /** + * Close a previously opened brace. + * + * @return $this + */ + public function close() + { + $this->_string = rtrim($this->_string, ' ,').'},'; + + return $this; + } + + /** + * Constant Score Query. + * + * A query that wraps a filter or another query and simply returns a constant + * score equal to the query boost for every document in the filter. + * + * Maps to Lucene ConstantScoreQuery. + * + * @return $this + */ + public function constantScore() + { + return $this->fieldOpen('constant_score'); + } + + /** + * Close a 'constant_score' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function constantScoreClose() + { + return $this->fieldClose(); + } + + /** + * The default field for query terms if no prefix field is specified. + * + * @param string $field Defaults to _all. + * + * @return $this + */ + public function defaultField($field = '_all') + { + return $this->field('default_field', $field); + } + + /** + * The default operator used if no explicit operator is specified. + * + * For example, with a default operator of OR, the query "capital of Hungary" + * is translated to "capital OR of OR Hungary", and with default operator of + * AND, the same query is translated to "capital AND of AND Hungary". + * + * @param string $operator Defaults to OR. + * + * @return $this + */ + public function defaultOperator($operator = 'OR') + { + return $this->field('default_operator', $operator); + } + + /** + * Dis Max Query. + * + * A query that generates the union of documents produced by its subqueries, + * and that scores each document with the maximum score for that document as + * produced by any subquery, plus a tie breaking increment for any additional + * matching subqueries. + * + * @return $this + */ + public function disMax() + { + return $this->fieldOpen('dis_max'); + } + + /** + * Close a 'dis_max' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function disMaxClose() + { + return $this->fieldClose(); + } + + /** + * Enable position increments in result queries. + * + * @param bool $bool Defaults to true. + * + * @return $this + */ + public function enablePositionIncrements($bool = true) + { + return $this->field('enable_position_increments', (bool) $bool); + } + + /** + * Enables explanation for each hit on how its score was computed. + * + * @param bool $value Turn on / off explain. + * + * @return $this + */ + public function explain($value = true) + { + return $this->field('explain', $value); + } + + /** + * Open 'facets' block. + * + * Facets provide aggregated data based on a search query. + * + * In the simple case, a facet can return facet counts for various facet + * values for a specific field. + * + * Elasticsearch supports more advanced facet implementations, such as + * statistical or date histogram facets. + * + * @return $this + */ + public function facets() + { + return $this->fieldOpen('facets'); + } + + /** + * Close a facets block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function facetsClose() + { + return $this->close(); + } + + /** + * Add a specific field / value entry. + * + * @param string $name Field to add. + * @param mixed $value Value to set. + * + * @return $this + */ + public function field($name, $value) + { + if (is_bool($value)) { + $value = '"'.var_export($value, true).'"'; + } elseif (is_array($value)) { + $value = '["'.implode('","', $value).'"]'; + } else { + $value = '"'.$value.'"'; + } + + $this->_string .= '"'.$name.'":'.$value.','; + + return $this; + } + + /** + * Close a field block. + * + * Alias of close() for ease of reading in source. + * Passed parameters will be ignored, however they can be useful in source for + * seeing which field is being closed. + * + * Builder::factory() + * ->query() + * ->range() + * ->fieldOpen('created') + * ->gte('2011-07-18 00:00:00') + * ->lt('2011-07-19 00:00:00') + * ->fieldClose('created') + * ->rangeClose() + * ->queryClose(); + * + * @return $this + */ + public function fieldClose() + { + return $this->close(); + } + + /** + * Open a node for the specified name. + * + * @param string $name Field name. + * + * @return $this + */ + public function fieldOpen($name) + { + $this->_string .= '"'.$name.'":'; + $this->open(); + + return $this; + } + + /** + * Explicitly define fields to return. + * + * @param array $fields Array of fields to return. + * + * @return $this + */ + public function fields(array $fields) + { + $this->_string .= '"fields":['; + + foreach ($fields as $field) { + $this->_string .= '"'.$field.'",'; + } + + $this->_string = rtrim($this->_string, ',').'],'; + + return $this; + } + + /** + * Open a 'filter' block. + * + * @return $this + */ + public function filter() + { + return $this->fieldOpen('filter'); + } + + /** + * Close a filter block. + * + * @return $this + */ + public function filterClose() + { + return $this->close(); + } + + /** + * Query. + * + * @return $this + */ + public function filteredQuery() + { + return $this->fieldOpen('filtered'); + } + + /** + * Close a 'filtered_query' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function filteredQueryClose() + { + return $this->fieldClose(); + } + + /** + * Set the from parameter (offset). + * + * @param int $value Result number to start from. + * + * @return $this + */ + public function from($value = 0) + { + return $this->field('from', $value); + } + + /** + * Set the minimum similarity for fuzzy queries. + * + * @param float $value Defaults to 0.5. + * + * @return $this + */ + public function fuzzyMinSim($value = 0.5) + { + return $this->field('fuzzy_min_sim', (float) $value); + } + + /** + * Set the prefix length for fuzzy queries. + * + * @param int $value Defaults to 0. + * + * @return $this + */ + public function fuzzyPrefixLength($value = 0) + { + return $this->field('fuzzy_prefix_length', (int) $value); + } + + /** + * Add a greater than (gt) clause. + * + * Used in range blocks. + * + * @param mixed $value Value to be gt. + * + * @return $this + */ + public function gt($value) + { + return $this->field('gt', $value); + } + + /** + * Add a greater than or equal to (gte) clause. + * + * Used in range blocks. + * + * @param mixed $value Value to be gte to. + * + * @return $this + */ + public function gte($value) + { + return $this->field('gte', $value); + } + + /** + * Automatically lower-case terms of wildcard, prefix, fuzzy, and range queries. + * + * @param bool $bool Defaults to true. + * + * @return $this + */ + public function lowercaseExpandedTerms($bool = true) + { + return $this->field('lowercase_expanded_terms', (bool) $bool); + } + + /** + * Add a less than (lt) clause. + * + * Used in range blocks. + * + * @param mixed $value Value to be lt. + * + * @return $this + */ + public function lt($value) + { + return $this->field('lt', $value); + } + + /** + * Add a less than or equal to (lte) clause. + * + * Used in range blocks. + * + * @param mixed $value Value to be lte to. + * + * @return $this + */ + public function lte($value) + { + return $this->field('lte', $value); + } + + /** + * Match All Query. + * + * A query that matches all documents. + * + * Maps to Lucene MatchAllDocsQuery. + * + * @param float $boost Boost to use. + * + * @return $this + */ + public function matchAll($boost = null) + { + $this->fieldOpen('match_all'); + + if (!$boost == null && is_numeric($boost)) { + $this->field('boost', (float) $boost); + } + + return $this->close(); + } + + /** + * The minimum number of should clauses to match. + * + * @param int $minimum Minimum number that should match. + * + * @return $this + */ + public function minimumNumberShouldMatch($minimum) + { + return $this->field('minimum_number_should_match', (int) $minimum); + } + + /** + * The clause (query) must appear in matching documents. + * + * @return $this + */ + public function must() + { + return $this->fieldOpen('must'); + } + + /** + * Close a 'must' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function mustClose() + { + return $this->fieldClose(); + } + + /** + * The clause (query) must not appear in the matching documents. + * + * Note that it is not possible to search on documents that only consists of + * a must_not clauses. + * + * @return $this + */ + public function mustNot() + { + return $this->fieldOpen('must_not'); + } + + /** + * Close a 'must_not' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function mustNotClose() + { + return $this->fieldClose(); + } + + /** + * Add an opening brace. + * + * @return $this + */ + public function open() + { + $this->_string .= '{'; + + return $this; + } + + /** + * Sets the default slop for phrases. + * + * If zero, then exact phrase matches are required. + * + * @param int $value Defaults to 0. + * + * @return $this + */ + public function phraseSlop($value = 0) + { + return $this->field('phrase_slop', (int) $value); + } + + /** + * Query. + * + * @return $this + */ + public function prefix() + { + return $this->fieldOpen('prefix'); + } + + /** + * Close a 'prefix' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function prefixClose() + { + return $this->fieldClose(); + } + + /** + * Queries to run within a dis_max query. + * + * @param array $queries Array of queries. + * + * @return $this + */ + public function queries(array $queries) + { + $this->_string .= '"queries":['; + + foreach ($queries as $query) { + $this->_string .= $query.','; + } + + $this->_string = rtrim($this->_string, ' ,').'],'; + + return $this; + } + + /** + * Open a query block. + * + * @return $this + */ + public function query() + { + return $this->fieldOpen('query'); + } + + /** + * Close a query block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function queryClose() + { + return $this->close(); + } + + /** + * Query String Query. + * + * A query that uses a query parser in order to parse its content + * + * @return $this + */ + public function queryString() + { + return $this->fieldOpen('query_string'); + } + + /** + * Close a 'query_string' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function queryStringClose() + { + return $this->fieldClose(); + } + + /** + * Open a range block. + * + * @return $this + */ + public function range() + { + return $this->fieldOpen('range'); + } + + /** + * Close a range block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function rangeClose() + { + return $this->close(); + } + + /** + * The clause (query) should appear in the matching document. + * + * A boolean query with no must clauses, one or more should clauses must + * match a document. + * + * @return $this + */ + public function should() + { + return $this->fieldOpen('should'); + } + + /** + * Close a 'should' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function shouldClose() + { + return $this->fieldClose(); + } + + /** + * Set the size parameter (number of records to return). + * + * @param int $value Number of records to return. + * + * @return $this + */ + public function size($value = 10) + { + return $this->field('size', $value); + } + + /** + * Allows to add one or more sort on specific fields. + * + * @return $this + */ + public function sort() + { + return $this->fieldOpen('sort'); + } + + /** + * Close a sort block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function sortClose() + { + return $this->close(); + } + + /** + * Add a field to sort on. + * + * @param string $name Field to sort. + * @param bool $reverse Reverse direction. + * + * @return $this + */ + public function sortField($name, $reverse = false) + { + return $this + ->fieldOpen('sort') + ->fieldOpen($name) + ->field('reverse', $reverse) + ->close() + ->close(); + } + + /** + * Sort on multiple fields. + * + * @param array $fields Associative array where the keys are field names to sort on, and the + * values are the sort order: "asc" or "desc" + * + * @return $this + */ + public function sortFields(array $fields) + { + $this->_string .= '"sort":['; + + foreach ($fields as $fieldName => $order) { + $this->_string .= '{"'.$fieldName.'":"'.$order.'"},'; + } + + $this->_string = rtrim($this->_string, ',').'],'; + + return $this; + } + + /** + * Term Query. + * + * Matches documents that have fields that contain a term (not analyzed). + * + * The term query maps to Lucene TermQuery. + * + * @return $this + */ + public function term() + { + return $this->fieldOpen('term'); + } + + /** + * Close a 'term' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function termClose() + { + return $this->fieldClose(); + } + + /** + * Open a 'text_phrase' block. + * + * @return $this + */ + public function textPhrase() + { + return $this->fieldOpen('text_phrase'); + } + + /** + * Close a 'text_phrase' block. + * + * @return $this + */ + public function textPhraseClose() + { + return $this->close(); + } + + /** + * When using dis_max, the disjunction max tie breaker. + * + * @param float $multiplier Multiplier to use. + * + * @return $this + */ + public function tieBreakerMultiplier($multiplier) + { + return $this->field('tie_breaker_multiplier', (float) $multiplier); + } + + /** + * Query. + * + * @return $this + */ + public function wildcard() + { + return $this->fieldOpen('wildcard'); + } + + /** + * Close a 'wildcard' block. + * + * Alias of close() for ease of reading in source. + * + * @return $this + */ + public function wildcardClose() + { + return $this->fieldClose(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Common.php b/vendor/ruflin/elastica/lib/Elastica/Query/Common.php new file mode 100644 index 00000000..9ca58d2e --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Common.php @@ -0,0 +1,172 @@ +<?php +namespace Elastica\Query; + +/** + * Class Common. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-common-terms-query.html + */ +class Common extends AbstractQuery +{ + const OPERATOR_AND = 'and'; + const OPERATOR_OR = 'or'; + + /** + * @var string + */ + protected $_field; + + /** + * @var array + */ + protected $_queryParams = array(); + + /** + * @param string $field the field on which to query + * @param string $query the query string + * @param float $cutoffFrequency percentage in decimal form (.001 == 0.1%) + */ + public function __construct($field, $query, $cutoffFrequency) + { + $this->setField($field); + $this->setQuery($query); + $this->setCutoffFrequency($cutoffFrequency); + } + + /** + * Set the field on which to query. + * + * @param string $field the field on which to query + * + * @return $this + */ + public function setField($field) + { + $this->_field = $field; + + return $this; + } + + /** + * Set the query string for this query. + * + * @param string $query + * + * @return $this + */ + public function setQuery($query) + { + return $this->setQueryParam('query', $query); + } + + /** + * Set the frequency below which terms will be put in the low frequency group. + * + * @param float $frequency percentage in decimal form (.001 == 0.1%) + * + * @return $this + */ + public function setCutoffFrequency($frequency) + { + return $this->setQueryParam('cutoff_frequency', (float) $frequency); + } + + /** + * Set the logic operator for low frequency terms. + * + * @param string $operator see OPERATOR_* class constants for options + * + * @return $this + */ + public function setLowFrequencyOperator($operator) + { + return $this->setQueryParam('low_freq_operator', $operator); + } + + /** + * Set the logic operator for high frequency terms. + * + * @param string $operator see OPERATOR_* class constants for options + * + * @return $this + */ + public function setHighFrequencyOperator($operator) + { + return $this->setQueryParam('high_frequency_operator', $operator); + } + + /** + * Set the minimum_should_match parameter. + * + * @param int|string $minimum minimum number of low frequency terms which must be present + * + * @return $this + * + * @link Possible values for minimum_should_match http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-minimum-should-match.html + */ + public function setMinimumShouldMatch($minimum) + { + return $this->setQueryParam('minimum_should_match', $minimum); + } + + /** + * Set the boost for this query. + * + * @param float $boost + * + * @return $this + */ + public function setBoost($boost) + { + return $this->setQueryParam('boost', (float) $boost); + } + + /** + * Set the analyzer for this query. + * + * @param string $analyzer + * + * @return $this + */ + public function setAnalyzer($analyzer) + { + return $this->setQueryParam('analyzer', $analyzer); + } + + /** + * Enable / disable computation of score factor based on the fraction of all query terms contained in the document. + * + * @param bool $disable disable_coord is false by default + * + * @return $this + */ + public function setDisableCoord($disable = true) + { + return $this->setQueryParam('disable_coord', (bool) $disable); + } + + /** + * Set a parameter in the body of this query. + * + * @param string $key parameter key + * @param mixed $value parameter value + * + * @return $this + */ + public function setQueryParam($key, $value) + { + $this->_queryParams[$key] = $value; + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + $this->setParam($this->_field, $this->_queryParams); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/ConstantScore.php b/vendor/ruflin/elastica/lib/Elastica/Query/ConstantScore.php new file mode 100644 index 00000000..3578606d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/ConstantScore.php @@ -0,0 +1,70 @@ +<?php +namespace Elastica\Query; + +use Elastica\Filter\AbstractFilter; + +/** + * Constant score query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-constant-score-query.html + */ +class ConstantScore extends AbstractQuery +{ + /** + * Construct constant score query. + * + * @param null|\Elastica\Filter\AbstractFilter|array $filter + */ + public function __construct($filter = null) + { + if (!is_null($filter)) { + $this->setFilter($filter); + } + } + + /** + * Set filter. + * + * @param array|\Elastica\Filter\AbstractFilter $filter + * + * @return $this + */ + public function setFilter($filter) + { + if ($filter instanceof AbstractFilter) { + $filter = $filter->toArray(); + } + + return $this->setParam('filter', $filter); + } + + /** + * Set query. + * + * @param array|\Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery($query) + { + if ($query instanceof AbstractQuery) { + $query = $query->toArray(); + } + + return $this->setParam('query', $query); + } + + /** + * Set boost. + * + * @param float $boost + * + * @return $this + */ + public function setBoost($boost) + { + return $this->setParam('boost', $boost); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/DisMax.php b/vendor/ruflin/elastica/lib/Elastica/Query/DisMax.php new file mode 100644 index 00000000..b3c5f252 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/DisMax.php @@ -0,0 +1,62 @@ +<?php +namespace Elastica\Query; + +use Elastica\Exception\InvalidException; + +/** + * DisMax query. + * + * @author Hung Tran <oohnoitz@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html + */ +class DisMax extends AbstractQuery +{ + /** + * Adds a query to the current object. + * + * @param \Elastica\Query\AbstractQuery|array $args Query + * + * @throws \Elastica\Exception\InvalidException If not valid query + * + * @return $this + */ + public function addQuery($args) + { + if ($args instanceof AbstractQuery) { + $args = $args->toArray(); + } + + if (!is_array($args)) { + throw new InvalidException('Invalid parameter. Has to be array or instance of Elastica\Query\AbstractQuery'); + } + + return $this->addParam('queries', $args); + } + + /** + * Set boost. + * + * @param float $boost + * + * @return $this + */ + public function setBoost($boost) + { + return $this->setParam('boost', $boost); + } + + /** + * Sets tie breaker to multiplier value to balance the scores between lower and higher scoring fields. + * + * If not set, defaults to 0.0 + * + * @param float $tieBreaker + * + * @return $this + */ + public function setTieBreaker($tieBreaker = 0.0) + { + return $this->setParam('tie_breaker', $tieBreaker); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Filtered.php b/vendor/ruflin/elastica/lib/Elastica/Query/Filtered.php new file mode 100644 index 00000000..ac085037 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Filtered.php @@ -0,0 +1,97 @@ +<?php +namespace Elastica\Query; + +use Elastica\Exception\InvalidException; +use Elastica\Filter\AbstractFilter; + +/** + * Filtered query. Needs a query and a filter. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html + */ +class Filtered extends AbstractQuery +{ + /** + * Constructs a filtered query. + * + * @param \Elastica\Query\AbstractQuery $query OPTIONAL Query object + * @param \Elastica\Filter\AbstractFilter $filter OPTIONAL Filter object + */ + public function __construct(AbstractQuery $query = null, AbstractFilter $filter = null) + { + $this->setQuery($query); + $this->setFilter($filter); + } + + /** + * Sets a query. + * + * @param \Elastica\Query\AbstractQuery $query Query object + * + * @return $this + */ + public function setQuery(AbstractQuery $query = null) + { + return $this->setParam('query', $query); + } + + /** + * Sets the filter. + * + * @param \Elastica\Filter\AbstractFilter $filter Filter object + * + * @return $this + */ + public function setFilter(AbstractFilter $filter = null) + { + return $this->setParam('filter', $filter); + } + + /** + * Gets the filter. + * + * @return \Elastica\Filter\AbstractFilter + */ + public function getFilter() + { + return $this->getParam('filter'); + } + + /** + * Gets the query. + * + * @return \Elastica\Query\AbstractQuery + */ + public function getQuery() + { + return $this->getParam('query'); + } + + /** + * Converts query to array. + * + * @return array Query array + * + * @see \Elastica\Query\AbstractQuery::toArray() + */ + public function toArray() + { + $filtered = array(); + + if ($this->hasParam('query') && $this->getParam('query') instanceof AbstractQuery) { + $filtered['query'] = $this->getParam('query')->toArray(); + } + + if ($this->hasParam('filter') && $this->getParam('filter') instanceof AbstractFilter) { + $filtered['filter'] = $this->getParam('filter')->toArray(); + } + + if (empty($filtered)) { + throw new InvalidException('A query and/or filter is required'); + } + + return array('filtered' => $filtered); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/FunctionScore.php b/vendor/ruflin/elastica/lib/Elastica/Query/FunctionScore.php new file mode 100644 index 00000000..b11454fb --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/FunctionScore.php @@ -0,0 +1,260 @@ +<?php +namespace Elastica\Query; + +use Elastica\Filter\AbstractFilter; +use Elastica\Script; + +/** + * Class FunctionScore. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html + */ +class FunctionScore extends AbstractQuery +{ + const BOOST_MODE_MULTIPLY = 'multiply'; + const BOOST_MODE_REPLACE = 'replace'; + const BOOST_MODE_SUM = 'sum'; + const BOOST_MODE_AVERAGE = 'average'; + const BOOST_MODE_MAX = 'max'; + const BOOST_MODE_MIN = 'min'; + + const SCORE_MODE_MULTIPLY = 'multiply'; + const SCORE_MODE_SUM = 'sum'; + const SCORE_MODE_AVERAGE = 'avg'; + const SCORE_MODE_FIRST = 'first'; + const SCORE_MODE_MAX = 'max'; + const SCORE_MODE_MIN = 'min'; + + const DECAY_GAUSS = 'gauss'; + const DECAY_EXPONENTIAL = 'exp'; + const DECAY_LINEAR = 'linear'; + + protected $_functions = array(); + + /** + * Set the child query for this function_score query. + * + * @param AbstractQuery $query + * + * @return $this + */ + public function setQuery(AbstractQuery $query) + { + return $this->setParam('query', $query->toArray()); + } + + /** + * @param AbstractFilter $filter + * + * @return $this + */ + public function setFilter(AbstractFilter $filter) + { + return $this->setParam('filter', $filter->toArray()); + } + + /** + * Add a function to the function_score query. + * + * @param string $functionType valid values are DECAY_* constants and script_score + * @param array|float $functionParams the body of the function. See documentation for proper syntax. + * @param AbstractFilter $filter optional filter to apply to the function + * @param float $weight function weight + * + * @return $this + */ + public function addFunction($functionType, $functionParams, AbstractFilter $filter = null, $weight = null) + { + $function = array( + $functionType => $functionParams, + ); + if (!is_null($filter)) { + $function['filter'] = $filter->toArray(); + } + if ($weight !== null) { + $function['weight'] = $weight; + } + + $this->_functions[] = $function; + + return $this; + } + + /** + * Add a script_score function to the query. + * + * @param Script $script a Script object + * @param AbstractFilter $filter an optional filter to apply to the function + * @param float $weight the weight of the function + * + * @return $this + */ + public function addScriptScoreFunction(Script $script, AbstractFilter $filter = null, $weight = null) + { + return $this->addFunction('script_score', $script->toArray(), $filter, $weight); + } + + /** + * Add a decay function to the query. + * + * @param string $function see DECAY_* constants for valid options + * @param string $field the document field on which to perform the decay function + * @param string $origin the origin value for this decay function + * @param string $scale a scale to define the rate of decay for this function + * @param string $offset If defined, this function will only be computed for documents with a distance from the origin greater than this value + * @param float $decay optionally defines how documents are scored at the distance given by the $scale parameter + * @param float $scaleWeight optional factor by which to multiply the score at the value provided by the $scale parameter + * @param float $weight optional factor by which to multiply the score at the value provided by the $scale parameter + * @param AbstractFilter $filter a filter associated with this function + * + * @return $this + */ + public function addDecayFunction( + $function, + $field, + $origin, + $scale, + $offset = null, + $decay = null, + $weight = null, + AbstractFilter $filter = null + ) { + $functionParams = array( + $field => array( + 'origin' => $origin, + 'scale' => $scale, + ), + ); + if (!is_null($offset)) { + $functionParams[$field]['offset'] = $offset; + } + if (!is_null($decay)) { + $functionParams[$field]['decay'] = (float) $decay; + } + + return $this->addFunction($function, $functionParams, $filter, $weight); + } + + /** + * Add a boost_factor function to the query. + * + * @param float $boostFactor the boost factor value + * @param AbstractFilter $filter a filter associated with this function + * + * @deprecated + */ + public function addBoostFactorFunction($boostFactor, AbstractFilter $filter = null) + { + $this->addWeightFunction($boostFactor, $filter); + } + + /** + * @param float $weight the weight of the function + * @param AbstractFilter $filter a filter associated with this function + */ + public function addWeightFunction($weight, AbstractFilter $filter = null) + { + $this->addFunction('weight', $weight, $filter); + } + + /** + * Add a random_score function to the query. + * + * @param number $seed the seed value + * @param AbstractFilter $filter a filter associated with this function + * @param float $weight an optional boost value associated with this function + */ + public function addRandomScoreFunction($seed, AbstractFilter $filter = null, $weight = null) + { + $this->addFunction('random_score', array('seed' => $seed), $filter, $weight); + } + + /** + * Set an overall boost value for this query. + * + * @param float $boost + * + * @return $this + */ + public function setBoost($boost) + { + return $this->setParam('boost', (float) $boost); + } + + /** + * Restrict the combined boost of the function_score query and its child query. + * + * @param float $maxBoost + * + * @return $this + */ + public function setMaxBoost($maxBoost) + { + return $this->setParam('max_boost', (float) $maxBoost); + } + + /** + * The boost mode determines how the score of this query is combined with that of the child query. + * + * @param string $mode see BOOST_MODE_* constants for valid options. Default is multiply. + * + * @return $this + */ + public function setBoostMode($mode) + { + return $this->setParam('boost_mode', $mode); + } + + /** + * If set, this query will return results in random order. + * + * @param int $seed Set a seed value to return results in the same random order for consistent pagination. + * + * @return $this + */ + public function setRandomScore($seed = null) + { + $seedParam = new \stdClass(); + if (!is_null($seed)) { + $seedParam->seed = $seed; + } + + return $this->setParam('random_score', $seedParam); + } + + /** + * Set the score method. + * + * @param string $mode see SCORE_MODE_* constants for valid options. Default is multiply. + * + * @return $this + */ + public function setScoreMode($mode) + { + return $this->setParam('score_mode', $mode); + } + + /** + * Set min_score option. + * + * @param float $minScore + * + * @return $this + */ + public function setMinScore($minScore) + { + return $this->setParam('min_score', (float) $minScore); + } + + /** + * @return array + */ + public function toArray() + { + if (sizeof($this->_functions)) { + $this->setParam('functions', $this->_functions); + } + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Fuzzy.php b/vendor/ruflin/elastica/lib/Elastica/Query/Fuzzy.php new file mode 100644 index 00000000..a3a46693 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Fuzzy.php @@ -0,0 +1,87 @@ +<?php +namespace Elastica\Query; + +use Elastica\Exception\InvalidException; + +/** + * Fuzzy query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html + */ +class Fuzzy extends AbstractQuery +{ + /** + * Construct a fuzzy query. + * + * @param string $fieldName Field name + * @param string $value String to search for + */ + public function __construct($fieldName = null, $value = null) + { + if ($fieldName and $value) { + $this->setField($fieldName, $value); + } + } + + /** + * Set field for fuzzy query. + * + * @param string $fieldName Field name + * @param string $value String to search for + * + * @return $this + */ + public function setField($fieldName, $value) + { + if (!is_string($value) or !is_string($fieldName)) { + throw new InvalidException('The field and value arguments must be of type string.'); + } + if (count($this->getParams()) > 0 and array_shift(array_keys($this->getParams())) != $fieldName) { + throw new InvalidException('Fuzzy query can only support a single field.'); + } + + return $this->setParam($fieldName, array('value' => $value)); + } + + /** + * Set optional parameters on the existing query. + * + * @param string $param option name + * @param mixed $value Value of the parameter + * + * @return $this + */ + public function setFieldOption($param, $value) + { + //Retrieve the single existing field for alteration. + $params = $this->getParams(); + if (count($params) < 1) { + throw new InvalidException('No field has been set'); + } + $keyArray = array_keys($params); + $params[$keyArray[0]][$param] = $value; + + return $this->setParam($keyArray[0], $params[$keyArray[0]]); + } + + /** + * Deprecated method of setting a field. + * + * @deprecated + */ + public function addField($fieldName, $args) + { + if (!array_key_exists('value', $args)) { + throw new InvalidException('Fuzzy query can only support a single field.'); + } + $this->setField($fieldName, $args['value']); + unset($args['value']); + foreach ($args as $param => $value) { + $this->setFieldOption($param, $value); + } + + return $this; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/FuzzyLikeThis.php b/vendor/ruflin/elastica/lib/Elastica/Query/FuzzyLikeThis.php new file mode 100644 index 00000000..2de480a8 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/FuzzyLikeThis.php @@ -0,0 +1,217 @@ +<?php +namespace Elastica\Query; + +/** + * Fuzzy Like This query. + * + * @author Raul Martinez, Jr <juneym@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-flt-query.html + */ +class FuzzyLikeThis extends AbstractQuery +{ + /** + * Field names. + * + * @var array Field names + */ + protected $_fields = array(); + + /** + * Like text. + * + * @var string Like text + */ + protected $_likeText = ''; + + /** + * Ignore term frequency. + * + * @var bool ignore term frequency + */ + protected $_ignoreTF = false; + + /** + * Max query terms value. + * + * @var int Max query terms value + */ + protected $_maxQueryTerms = 25; + + /** + * minimum similarity. + * + * @var int minimum similarity + */ + protected $_minSimilarity = 0.5; + + /** + * Prefix Length. + * + * @var int Prefix Length + */ + protected $_prefixLength = 0; + + /** + * Boost. + * + * @var float Boost + */ + protected $_boost = 1.0; + + /** + * Analyzer. + * + * @var sting Analyzer + */ + protected $_analyzer; + + /** + * Adds field to flt query. + * + * @param array $fields Field names + * + * @return $this + */ + public function addFields(array $fields) + { + $this->_fields = $fields; + + return $this; + } + + /** + * Set the "like_text" value. + * + * @param string $text + * + * @return $this + */ + public function setLikeText($text) + { + $text = trim($text); + $this->_likeText = $text; + + return $this; + } + + /** + * Set the "ignore_tf" value (ignore term frequency). + * + * @param bool $ignoreTF + * + * @return $this + */ + public function setIgnoreTF($ignoreTF) + { + $this->_ignoreTF = (bool) $ignoreTF; + + return $this; + } + + /** + * Set the minimum similarity. + * + * @param int $value + * + * @return $this + */ + public function setMinSimilarity($value) + { + $value = (float) $value; + $this->_minSimilarity = $value; + + return $this; + } + + /** + * Set boost. + * + * @param float $value Boost value + * + * @return $this + */ + public function setBoost($value) + { + $this->_boost = (float) $value; + + return $this; + } + + /** + * Set Prefix Length. + * + * @param int $value Prefix length + * + * @return $this + */ + public function setPrefixLength($value) + { + $this->_prefixLength = (int) $value; + + return $this; + } + + /** + * Set max_query_terms. + * + * @param int $value Max query terms value + * + * @return $this + */ + public function setMaxQueryTerms($value) + { + $this->_maxQueryTerms = (int) $value; + + return $this; + } + + /** + * Set analyzer. + * + * @param string $text Analyzer text + * + * @return $this + */ + public function setAnalyzer($text) + { + $text = trim($text); + $this->_analyzer = $text; + + return $this; + } + + /** + * Converts fuzzy like this query to array. + * + * @return array Query array + * + * @see \Elastica\Query\AbstractQuery::toArray() + */ + public function toArray() + { + if (!empty($this->_fields)) { + $args['fields'] = $this->_fields; + } + + if (!empty($this->_boost)) { + $args['boost'] = $this->_boost; + } + + if (!empty($this->_analyzer)) { + $args['analyzer'] = $this->_analyzer; + } + + $args['min_similarity'] = ($this->_minSimilarity > 0) ? $this->_minSimilarity : 0; + + $args['like_text'] = $this->_likeText; + $args['prefix_length'] = $this->_prefixLength; + $args['ignore_tf'] = $this->_ignoreTF; + $args['max_query_terms'] = $this->_maxQueryTerms; + + $data = parent::toArray(); + $args = array_merge($args, $data['fuzzy_like_this']); + + return array('fuzzy_like_this' => $args); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/HasChild.php b/vendor/ruflin/elastica/lib/Elastica/Query/HasChild.php new file mode 100644 index 00000000..190fa592 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/HasChild.php @@ -0,0 +1,65 @@ +<?php +namespace Elastica\Query; + +use Elastica\Query as BaseQuery; + +/** + * Returns parent documents having child docs matching the query. + * + * @author Fabian Vogler <fabian@equivalence.ch> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html + */ +class HasChild extends AbstractQuery +{ + /** + * Construct HasChild Query. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * @param string $type Parent document type + */ + public function __construct($query, $type = null) + { + $this->setType($type); + $this->setQuery($query); + } + + /** + * Sets query object. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery($query) + { + $query = BaseQuery::create($query); + $data = $query->toArray(); + + return $this->setParam('query', $data['query']); + } + + /** + * Set type of the parent document. + * + * @param string $type Parent document type + * + * @return $this + */ + public function setType($type) + { + return $this->setParam('type', $type); + } + + /** + * Sets the scope. + * + * @param string $scope Scope + * + * @return $this + */ + public function setScope($scope) + { + return $this->setParam('_scope', $scope); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/HasParent.php b/vendor/ruflin/elastica/lib/Elastica/Query/HasParent.php new file mode 100644 index 00000000..03aae13b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/HasParent.php @@ -0,0 +1,63 @@ +<?php +namespace Elastica\Query; + +use Elastica\Query as BaseQuery; + +/** + * Returns child documents having parent docs matching the query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html + */ +class HasParent extends AbstractQuery +{ + /** + * Construct HasChild Query. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * @param string $type Parent document type + */ + public function __construct($query, $type) + { + $this->setQuery($query); + $this->setType($type); + } + + /** + * Sets query object. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery($query) + { + $query = BaseQuery::create($query); + $data = $query->toArray(); + + return $this->setParam('query', $data['query']); + } + + /** + * Set type of the parent document. + * + * @param string $type Parent document type + * + * @return $this + */ + public function setType($type) + { + return $this->setParam('type', $type); + } + + /** + * Sets the scope. + * + * @param string $scope Scope + * + * @return $this + */ + public function setScope($scope) + { + return $this->setParam('_scope', $scope); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Ids.php b/vendor/ruflin/elastica/lib/Elastica/Query/Ids.php new file mode 100644 index 00000000..5d76efcf --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Ids.php @@ -0,0 +1,121 @@ +<?php +namespace Elastica\Query; + +use Elastica\Type; + +/** + * Ids Query. + * + * @author Lee Parker + * @author Nicolas Ruflin <spam@ruflin.com> + * @author Tim Rupp + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html + */ +class Ids extends AbstractQuery +{ + /** + * Params. + * + * @var array Params + */ + protected $_params = array(); + + /** + * Creates filter object. + * + * @param string|\Elastica\Type $type Type to filter on + * @param array $ids List of ids + */ + public function __construct($type = null, array $ids = array()) + { + $this->setType($type); + $this->setIds($ids); + } + + /** + * Adds one more filter to the and filter. + * + * @param string $id Adds id to filter + * + * @return $this + */ + public function addId($id) + { + $this->_params['values'][] = $id; + + return $this; + } + + /** + * Adds one more type to query. + * + * @param string|\Elastica\Type $type Type name or object + * + * @return $this + */ + public function addType($type) + { + if ($type instanceof Type) { + $type = $type->getName(); + } elseif (empty($type) && !is_numeric($type)) { + // A type can be 0, but cannot be empty + return $this; + } + + $this->_params['type'][] = $type; + + return $this; + } + + /** + * Set type. + * + * @param string|\Elastica\Type $type Type name or object + * + * @return $this + */ + public function setType($type) + { + if ($type instanceof Type) { + $type = $type->getName(); + } elseif (empty($type) && !is_numeric($type)) { + // A type can be 0, but cannot be empty + return $this; + } + + $this->_params['type'] = $type; + + return $this; + } + + /** + * Sets the ids to filter. + * + * @param array|string $ids List of ids + * + * @return $this + */ + public function setIds($ids) + { + if (is_array($ids)) { + $this->_params['values'] = $ids; + } else { + $this->_params['values'] = array($ids); + } + + return $this; + } + + /** + * Converts filter to array. + * + * @see \Elastica\Query\AbstractQuery::toArray() + * + * @return array Query array + */ + public function toArray() + { + return array('ids' => $this->_params); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Image.php b/vendor/ruflin/elastica/lib/Elastica/Query/Image.php new file mode 100644 index 00000000..bf7d028b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Image.php @@ -0,0 +1,187 @@ +<?php +namespace Elastica\Query; + +/** + * Image query. + * + * @author Jacques Moati <jacques@moati.net> + * + * @link https://github.com/kzwang/elasticsearch-image + * + * To use this feature you have to call the following command in the + * elasticsearch directory: + * <code> + * ./bin/plugin --url https://github.com/SibaTokyo/elasticsearch-image/releases/download/1.4.0/elasticsearch-image-1.4.0.zip --install image + * </code> + * This installs the image plugin. More infos + * can be found here: {@link https://github.com/SibaTokyo/elasticsearch-image} + */ +class Image extends AbstractQuery +{ + public function __construct(array $image = array()) + { + $this->setParams($image); + } + + /** + * Sets a param for the given field. + * + * @param string $field + * @param string $key + * @param string $value + * + * @return $this + */ + public function setFieldParam($field, $key, $value) + { + if (!isset($this->_params[$field])) { + $this->_params[$field] = array(); + } + + $this->_params[$field][$key] = $value; + + return $this; + } + + /** + * Set field boost value. + * + * If not set, defaults to 1.0. + * + * @param string $field + * @param float $boost + * + * @return $this + */ + public function setFieldBoost($field, $boost = 1.0) + { + return $this->setFieldParam($field, 'boost', (float) $boost); + } + + /** + * Set field feature value. + * + * If not set, defaults CEDD. + * + * @param string $field + * @param string $feature + * + * @return $this + */ + public function setFieldFeature($field, $feature = 'CEDD') + { + return $this->setFieldParam($field, 'feature', $feature); + } + + /** + * Set field hash value. + * + * If not set, defaults BIT_SAMPLING. + * + * @param string $field + * @param string $hash + * + * @return $this + */ + public function setFieldHash($field, $hash = 'BIT_SAMPLING') + { + return $this->setFieldParam($field, 'hash', $hash); + } + + /** + * Set field image value. + * + * @param string $field + * @param string $path File will be base64_encode + * + * @throws \Exception + * + * @return $this + */ + public function setFieldImage($field, $path) + { + if (!file_exists($path) || !is_readable($path)) { + throw new \Exception(sprintf("File %s can't be open", $path)); + } + + return $this->setFieldParam($field, 'image', base64_encode(file_get_contents($path))); + } + + /** + * Set field index value. + * + * @param string $field + * @param string $index + * + * @return $this + */ + public function setFieldIndex($field, $index) + { + return $this->setFieldParam($field, 'index', $index); + } + + /** + * Set field type value. + * + * @param string $field + * @param string $type + * + * @return $this + */ + public function setFieldType($field, $type) + { + return $this->setFieldParam($field, 'type', $type); + } + + /** + * Set field id value. + * + * @param string $field + * @param string $id + * + * @return $this + */ + public function setFieldId($field, $id) + { + return $this->setFieldParam($field, 'id', $id); + } + + /** + * Set field path value. + * + * @param string $field + * @param string $path + * + * @return $this + */ + public function setFieldPath($field, $path) + { + return $this->setFieldParam($field, 'path', $path); + } + + /** + * Define quickly a reference image already in your elasticsearch database. + * + * If not set, path will be the same as $field. + * + * @param string $field + * @param string $index + * @param string $type + * @param string $id + * @param string $path + * + * @return $this + */ + public function setImageByReference($field, $index, $type, $id, $path = null) + { + if (null === $path) { + $path = $field; + } + + $this->setFieldIndex($field, $index); + $this->setFieldType($field, $type); + $this->setFieldId($field, $id); + + return $this->setFieldPath($field, $path); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Match.php b/vendor/ruflin/elastica/lib/Elastica/Query/Match.php new file mode 100644 index 00000000..abb40970 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Match.php @@ -0,0 +1,222 @@ +<?php +namespace Elastica\Query; + +/** + * Match query. + * + * @author F21 + * @author WONG Wing Lun <luiges90@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html + */ +class Match extends AbstractQuery +{ + const ZERO_TERM_NONE = 'none'; + const ZERO_TERM_ALL = 'all'; + + /** + * @param string $field + * @param mixed $values + */ + public function __construct($field = null, $values = null) + { + if ($field !== null && $values !== null) { + $this->setParam($field, $values); + } + } + + /** + * Sets a param for the message array. + * + * @param string $field + * @param mixed $values + * + * @return $this + */ + public function setField($field, $values) + { + return $this->setParam($field, $values); + } + + /** + * Sets a param for the given field. + * + * @param string $field + * @param string $key + * @param string $value + * + * @return $this + */ + public function setFieldParam($field, $key, $value) + { + if (!isset($this->_params[$field])) { + $this->_params[$field] = array(); + } + + $this->_params[$field][$key] = $value; + + return $this; + } + + /** + * Sets the query string. + * + * @param string $field + * @param string $query + * + * @return $this + */ + public function setFieldQuery($field, $query) + { + return $this->setFieldParam($field, 'query', $query); + } + + /** + * Set field type. + * + * @param string $field + * @param string $type + * + * @return $this + */ + public function setFieldType($field, $type) + { + return $this->setFieldParam($field, 'type', $type); + } + + /** + * Set field operator. + * + * @param string $field + * @param string $operator + * + * @return $this + */ + public function setFieldOperator($field, $operator) + { + return $this->setFieldParam($field, 'operator', $operator); + } + + /** + * Set field analyzer. + * + * @param string $field + * @param string $analyzer + * + * @return $this + */ + public function setFieldAnalyzer($field, $analyzer) + { + return $this->setFieldParam($field, 'analyzer', $analyzer); + } + + /** + * Set field boost value. + * + * If not set, defaults to 1.0. + * + * @param string $field + * @param float $boost + * + * @return $this + */ + public function setFieldBoost($field, $boost = 1.0) + { + return $this->setFieldParam($field, 'boost', (float) $boost); + } + + /** + * Set field minimum should match. + * + * @param string $field + * @param int|string $minimumShouldMatch + * + * @return $this + * + * @link Possible values for minimum_should_match http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-minimum-should-match.html + */ + public function setFieldMinimumShouldMatch($field, $minimumShouldMatch) + { + return $this->setFieldParam($field, 'minimum_should_match', $minimumShouldMatch); + } + + /** + * Set field fuzziness. + * + * @param string $field + * @param mixed $fuzziness + * + * @return $this + */ + public function setFieldFuzziness($field, $fuzziness) + { + return $this->setFieldParam($field, 'fuzziness', $fuzziness); + } + + /** + * Set field fuzzy rewrite. + * + * @param string $field + * @param string $fuzzyRewrite + * + * @return $this + */ + public function setFieldFuzzyRewrite($field, $fuzzyRewrite) + { + return $this->setFieldParam($field, 'fuzzy_rewrite', $fuzzyRewrite); + } + + /** + * Set field prefix length. + * + * @param string $field + * @param int $prefixLength + * + * @return $this + */ + public function setFieldPrefixLength($field, $prefixLength) + { + return $this->setFieldParam($field, 'prefix_length', (int) $prefixLength); + } + + /** + * Set field max expansions. + * + * @param string $field + * @param int $maxExpansions + * + * @return $this + */ + public function setFieldMaxExpansions($field, $maxExpansions) + { + return $this->setFieldParam($field, 'max_expansions', (int) $maxExpansions); + } + + /** + * Set zero terms query. + * + * If not set, default to 'none' + * + * @param string $field + * @param string $zeroTermQuery + * + * @return $this + */ + public function setFieldZeroTermsQuery($field, $zeroTermQuery = 'none') + { + return $this->setFieldParam($field, 'zero_terms_query', $zeroTermQuery); + } + + /** + * Set cutoff frequency. + * + * @param string $field + * @param float $cutoffFrequency + * + * @return $this + */ + public function setFieldCutoffFrequency($field, $cutoffFrequency) + { + return $this->setFieldParam($field, 'cutoff_frequency', $cutoffFrequency); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/MatchAll.php b/vendor/ruflin/elastica/lib/Elastica/Query/MatchAll.php new file mode 100644 index 00000000..d01aaee8 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/MatchAll.php @@ -0,0 +1,20 @@ +<?php +namespace Elastica\Query; + +/** + * Match all query. Returns all results. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-all-query.html + */ +class MatchAll extends AbstractQuery +{ + /** + * Creates match all query. + */ + public function __construct() + { + $this->_params = new \stdClass(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrase.php b/vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrase.php new file mode 100644 index 00000000..54302f90 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrase.php @@ -0,0 +1,13 @@ +<?php +namespace Elastica\Query; + +/** + * Match Phrase query. + * + * @author Jacques Moati <jacques@moati.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html#_phrase + */ +class MatchPhrase extends Match +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrasePrefix.php b/vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrasePrefix.php new file mode 100644 index 00000000..61764bda --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrasePrefix.php @@ -0,0 +1,13 @@ +<?php +namespace Elastica\Query; + +/** + * Match Phrase Prefix query. + * + * @author Jacques Moati <jacques@moati.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html#_match_phrase_prefix + */ +class MatchPhrasePrefix extends Match +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/MoreLikeThis.php b/vendor/ruflin/elastica/lib/Elastica/Query/MoreLikeThis.php new file mode 100644 index 00000000..cd375db5 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/MoreLikeThis.php @@ -0,0 +1,198 @@ +<?php +namespace Elastica\Query; + +/** + * More Like This query. + * + * @author Raul Martinez, Jr <juneym@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html + */ +class MoreLikeThis extends AbstractQuery +{ + /** + * Set fields to which to restrict the mlt query. + * + * @param array $fields Field names + * + * @return \Elastica\Query\MoreLikeThis Current object + */ + public function setFields(array $fields) + { + return $this->setParam('fields', $fields); + } + + /** + * Set document ids for the mlt query. + * + * @param array $ids Document ids + * + * @return \Elastica\Query\MoreLikeThis Current object + */ + public function setIds(array $ids) + { + return $this->setParam('ids', $ids); + } + + /** + * Set the "like_text" value. + * + * @param string $likeText + * + * @return $this + */ + public function setLikeText($likeText) + { + $likeText = trim($likeText); + + return $this->setParam('like_text', $likeText); + } + + /** + * Set boost. + * + * @param float $boost Boost value + * + * @return $this + */ + public function setBoost($boost) + { + return $this->setParam('boost', (float) $boost); + } + + /** + * Set max_query_terms. + * + * @param int $maxQueryTerms Max query terms value + * + * @return $this + */ + public function setMaxQueryTerms($maxQueryTerms) + { + return $this->setParam('max_query_terms', (int) $maxQueryTerms); + } + + /** + * Set percent terms to match. + * + * @param float $percentTermsToMatch Percentage + * + * @return $this + * + * @deprecated Option "percent_terms_to_match" deprecated as of ES 1.5. Use "minimum_should_match" instead. + */ + public function setPercentTermsToMatch($percentTermsToMatch) + { + return $this->setParam('percent_terms_to_match', (float) $percentTermsToMatch); + } + + /** + * Set min term frequency. + * + * @param int $minTermFreq + * + * @return $this + */ + public function setMinTermFrequency($minTermFreq) + { + return $this->setParam('min_term_freq', (int) $minTermFreq); + } + + /** + * set min document frequency. + * + * @param int $minDocFreq + * + * @return $this + */ + public function setMinDocFrequency($minDocFreq) + { + return $this->setParam('min_doc_freq', (int) $minDocFreq); + } + + /** + * set max document frequency. + * + * @param int $maxDocFreq + * + * @return $this + */ + public function setMaxDocFrequency($maxDocFreq) + { + return $this->setParam('max_doc_freq', (int) $maxDocFreq); + } + + /** + * Set min word length. + * + * @param int $minWordLength + * + * @return $this + */ + public function setMinWordLength($minWordLength) + { + return $this->setParam('min_word_length', (int) $minWordLength); + } + + /** + * Set max word length. + * + * @param int $maxWordLength + * + * @return $this + */ + public function setMaxWordLength($maxWordLength) + { + return $this->setParam('max_word_length', (int) $maxWordLength); + } + + /** + * Set boost terms. + * + * @param bool $boostTerms + * + * @return $this + */ + public function setBoostTerms($boostTerms) + { + return $this->setParam('boost_terms', (bool) $boostTerms); + } + + /** + * Set analyzer. + * + * @param string $analyzer + * + * @return $this + */ + public function setAnalyzer($analyzer) + { + $analyzer = trim($analyzer); + + return $this->setParam('analyzer', $analyzer); + } + + /** + * Set stop words. + * + * @param array $stopWords + * + * @return $this + */ + public function setStopWords(array $stopWords) + { + return $this->setParam('stop_words', $stopWords); + } + + /** + * Set minimum_should_match option. + * + * @param int|string $minimumShouldMatch + * + * @return $this + */ + public function setMinimumShouldMatch($minimumShouldMatch) + { + return $this->setParam('minimum_should_match', $minimumShouldMatch); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/MultiMatch.php b/vendor/ruflin/elastica/lib/Elastica/Query/MultiMatch.php new file mode 100644 index 00000000..0771f370 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/MultiMatch.php @@ -0,0 +1,191 @@ +<?php +namespace Elastica\Query; + +/** + * Multi Match. + * + * @author Rodolfo Adhenawer Campagnoli Moraes <adhenawer@gmail.com> + * @author Wong Wing Lun <luiges90@gmail.com> + * @author Tristan Maindron <tmaindron@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html + */ +class MultiMatch extends AbstractQuery +{ + const TYPE_BEST_FIELDS = 'best_fields'; + const TYPE_MOST_FIELDS = 'most_fields'; + const TYPE_CROSS_FIELDS = 'cross_fields'; + const TYPE_PHRASE = 'phrase'; + const TYPE_PHRASE_PREFIX = 'phrase_prefix'; + + const OPERATOR_OR = 'or'; + const OPERATOR_AND = 'and'; + + const ZERO_TERM_NONE = 'none'; + const ZERO_TERM_ALL = 'all'; + + /** + * Sets the query. + * + * @param string $query Query + * + * @return $this + */ + public function setQuery($query = '') + { + return $this->setParam('query', $query); + } + + /** + * Sets Fields to be used in the query. + * + * @param array $fields Fields + * + * @return $this + */ + public function setFields($fields = array()) + { + return $this->setParam('fields', $fields); + } + + /** + * Sets use dis max indicating to either create a dis_max query or a bool query. + * + * If not set, defaults to true. + * + * @param bool $useDisMax + * + * @return $this + */ + public function setUseDisMax($useDisMax = true) + { + return $this->setParam('use_dis_max', $useDisMax); + } + + /** + * Sets tie breaker to multiplier value to balance the scores between lower and higher scoring fields. + * + * If not set, defaults to 0.0. + * + * @param float $tieBreaker + * + * @return $this + */ + public function setTieBreaker($tieBreaker = 0.0) + { + return $this->setParam('tie_breaker', $tieBreaker); + } + + /** + * Sets operator for Match Query. + * + * If not set, defaults to 'or' + * + * @param string $operator + * + * @return $this + */ + public function setOperator($operator = 'or') + { + return $this->setParam('operator', $operator); + } + + /** + * Set field minimum should match for Match Query. + * + * @param mixed $minimumShouldMatch + * + * @return $this + */ + public function setMinimumShouldMatch($minimumShouldMatch) + { + return $this->setParam('minimum_should_match', $minimumShouldMatch); + } + + /** + * Set zero terms query for Match Query. + * + * If not set, default to 'none' + * + * @param string $zeroTermQuery + * + * @return $this + */ + public function setZeroTermsQuery($zeroTermQuery = 'none') + { + return $this->setParam('zero_terms_query', $zeroTermQuery); + } + + /** + * Set cutoff frequency for Match Query. + * + * @param float $cutoffFrequency + * + * @return $this + */ + public function setCutoffFrequency($cutoffFrequency) + { + return $this->setParam('cutoff_frequency', $cutoffFrequency); + } + + /** + * Set type. + * + * @param string $field + * @param string $type + * + * @return $this + */ + public function setType($type) + { + return $this->setParam('type', $type); + } + + /** + * Set fuzziness. + * + * @param float $fuzziness + * + * @return $this + */ + public function setFuzziness($fuzziness) + { + return $this->setParam('fuzziness', (float) $fuzziness); + } + + /** + * Set prefix length. + * + * @param int $prefixLength + * + * @return $this + */ + public function setPrefixLength($prefixLength) + { + return $this->setParam('prefix_length', (int) $prefixLength); + } + + /** + * Set max expansions. + * + * @param int $maxExpansions + * + * @return $this + */ + public function setMaxExpansions($maxExpansions) + { + return $this->setParam('max_expansions', (int) $maxExpansions); + } + + /** + * Set analyzer. + * + * @param string $analyzer + * + * @return $this + */ + public function setAnalyzer($analyzer) + { + return $this->setParam('analyzer', $analyzer); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Nested.php b/vendor/ruflin/elastica/lib/Elastica/Query/Nested.php new file mode 100644 index 00000000..b072cfc8 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Nested.php @@ -0,0 +1,48 @@ +<?php +namespace Elastica\Query; + +/** + * Nested query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html + */ +class Nested extends AbstractQuery +{ + /** + * Adds field to mlt query. + * + * @param string $path Nested object path + * + * @return $this + */ + public function setPath($path) + { + return $this->setParam('path', $path); + } + + /** + * Sets nested query. + * + * @param \Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery(AbstractQuery $query) + { + return $this->setParam('query', $query->toArray()); + } + + /** + * Set score method. + * + * @param string $scoreMode Options: avg, total, max and none. + * + * @return $this + */ + public function setScoreMode($scoreMode) + { + return $this->setParam('score_mode', $scoreMode); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Prefix.php b/vendor/ruflin/elastica/lib/Elastica/Query/Prefix.php new file mode 100644 index 00000000..c2b903ea --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Prefix.php @@ -0,0 +1,47 @@ +<?php +namespace Elastica\Query; + +/** + * Prefix query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html + */ +class Prefix extends AbstractQuery +{ + /** + * Constructs the Prefix query object. + * + * @param array $prefix OPTIONAL Calls setRawPrefix with the given $prefix array + */ + public function __construct(array $prefix = array()) + { + $this->setRawPrefix($prefix); + } + + /** + * setRawPrefix can be used instead of setPrefix if some more special + * values for a prefix have to be set. + * + * @param array $prefix Prefix array + * + * @return $this + */ + public function setRawPrefix(array $prefix) + { + return $this->setParams($prefix); + } + + /** + * Adds a prefix to the prefix query. + * + * @param string $key Key to query + * @param string|array $value Values(s) for the query. Boost can be set with array + * @param float $boost OPTIONAL Boost value (default = 1.0) + * + * @return $this + */ + public function setPrefix($key, $value, $boost = 1.0) + { + return $this->setRawPrefix(array($key => array('value' => $value, 'boost' => $boost))); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/QueryString.php b/vendor/ruflin/elastica/lib/Elastica/Query/QueryString.php new file mode 100644 index 00000000..89ea77cd --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/QueryString.php @@ -0,0 +1,282 @@ +<?php +namespace Elastica\Query; + +use Elastica\Exception\InvalidException; + +/** + * QueryString query. + * + * @author Nicolas Ruflin <spam@ruflin.com>, Jasper van Wanrooy <jasper@vanwanrooy.net> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html + */ +class QueryString extends AbstractQuery +{ + /** + * Query string. + * + * @var string Query string + */ + protected $_queryString = ''; + + /** + * Creates query string object. Calls setQuery with argument. + * + * @param string $queryString OPTIONAL Query string for object + */ + public function __construct($queryString = '') + { + $this->setQuery($queryString); + } + + /** + * Sets a new query string for the object. + * + * @param string $query Query string + * + * @throws \Elastica\Exception\InvalidException If given parameter is not a string + * + * @return $this + */ + public function setQuery($query = '') + { + if (!is_string($query)) { + throw new InvalidException('Parameter has to be a string'); + } + + return $this->setParam('query', $query); + } + + /** + * Sets the default field. + * + * If no field is set, _all is chosen + * + * @param string $field Field + * + * @return $this + */ + public function setDefaultField($field) + { + return $this->setParam('default_field', $field); + } + + /** + * Sets the default operator AND or OR. + * + * If no operator is set, OR is chosen + * + * @param string $operator Operator + * + * @return $this + */ + public function setDefaultOperator($operator) + { + return $this->setParam('default_operator', $operator); + } + + /** + * Sets the analyzer to analyze the query with. + * + * @param string $analyzer Analyser to use + * + * @return $this + */ + public function setAnalyzer($analyzer) + { + return $this->setParam('analyzer', $analyzer); + } + + /** + * Sets the parameter to allow * and ? as first characters. + * + * If not set, defaults to true. + * + * @param bool $allow + * + * @return $this + */ + public function setAllowLeadingWildcard($allow = true) + { + return $this->setParam('allow_leading_wildcard', (bool) $allow); + } + + /** + * Sets the parameter to enable the position increments in result queries. + * + * If not set, defaults to true. + * + * @param bool $enabled + * + * @return $this + */ + public function setEnablePositionIncrements($enabled = true) + { + return $this->setParam('enable_position_increments', (bool) $enabled); + } + + /** + * Sets the fuzzy prefix length parameter. + * + * If not set, defaults to 0. + * + * @param int $length + * + * @return $this + */ + public function setFuzzyPrefixLength($length = 0) + { + return $this->setParam('fuzzy_prefix_length', (int) $length); + } + + /** + * Sets the fuzzy minimal similarity parameter. + * + * If not set, defaults to 0.5 + * + * @param float $minSim + * + * @return $this + */ + public function setFuzzyMinSim($minSim = 0.5) + { + return $this->setParam('fuzzy_min_sim', (float) $minSim); + } + + /** + * Sets the phrase slop. + * + * If zero, exact phrases are required. + * If not set, defaults to zero. + * + * @param int $phraseSlop + * + * @return $this + */ + public function setPhraseSlop($phraseSlop = 0) + { + return $this->setParam('phrase_slop', (int) $phraseSlop); + } + + /** + * Sets the boost value of the query. + * + * If not set, defaults to 1.0. + * + * @param float $boost + * + * @return $this + */ + public function setBoost($boost = 1.0) + { + return $this->setParam('boost', (float) $boost); + } + + /** + * Allows analyzing of wildcard terms. + * + * If not set, defaults to true + * + * @param bool $analyze + * + * @return $this + */ + public function setAnalyzeWildcard($analyze = true) + { + return $this->setParam('analyze_wildcard', (bool) $analyze); + } + + /** + * Sets the param to automatically generate phrase queries. + * + * If not set, defaults to true. + * + * @param bool $autoGenerate + * + * @return $this + */ + public function setAutoGeneratePhraseQueries($autoGenerate = true) + { + return $this->setParam('auto_generate_phrase_queries', (bool) $autoGenerate); + } + + /** + * Sets the fields. If no fields are set, _all is chosen. + * + * @param array $fields Fields + * + * @throws \Elastica\Exception\InvalidException If given parameter is not an array + * + * @return $this + */ + public function setFields(array $fields) + { + if (!is_array($fields)) { + throw new InvalidException('Parameter has to be an array'); + } + + return $this->setParam('fields', $fields); + } + + /** + * Whether to use bool or dis_max queries to internally combine results for multi field search. + * + * @param bool $value Determines whether to use + * + * @return $this + */ + public function setUseDisMax($value = true) + { + return $this->setParam('use_dis_max', (bool) $value); + } + + /** + * When using dis_max, the disjunction max tie breaker. + * + * If not set, defaults to 0. + * + * @param int $tieBreaker + * + * @return $this + */ + public function setTieBreaker($tieBreaker = 0) + { + return $this->setParam('tie_breaker', (float) $tieBreaker); + } + + /** + * Set a re-write condition. See https://github.com/elasticsearch/elasticsearch/issues/1186 for additional information. + * + * @param string $rewrite + * + * @return $this + */ + public function setRewrite($rewrite = '') + { + return $this->setParam('rewrite', $rewrite); + } + + /** + * Set timezone option. + * + * @param string $timezone + * + * @return $this + */ + public function setTimezone($timezone) + { + return $this->setParam('time_zone', $timezone); + } + + /** + * Converts query to array. + * + * @see \Elastica\Query\AbstractQuery::toArray() + * + * @return array Query array + */ + public function toArray() + { + return array('query_string' => array_merge(array('query' => $this->_queryString), $this->getParams())); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Range.php b/vendor/ruflin/elastica/lib/Elastica/Query/Range.php new file mode 100644 index 00000000..b2f9175a --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Range.php @@ -0,0 +1,38 @@ +<?php +namespace Elastica\Query; + +/** + * Range query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html + */ +class Range extends AbstractQuery +{ + /** + * Constructor. + * + * @param string $fieldName Field name + * @param array $args Field arguments + */ + public function __construct($fieldName = null, array $args = array()) + { + if ($fieldName) { + $this->addField($fieldName, $args); + } + } + + /** + * Adds a range field to the query. + * + * @param string $fieldName Field name + * @param array $args Field arguments + * + * @return $this + */ + public function addField($fieldName, array $args) + { + return $this->setParam($fieldName, $args); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Regexp.php b/vendor/ruflin/elastica/lib/Elastica/Query/Regexp.php new file mode 100644 index 00000000..22a48560 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Regexp.php @@ -0,0 +1,40 @@ +<?php +namespace Elastica\Query; + +/** + * Regexp query. + * + * @author Aurélien Le Grand <gnitg@yahoo.fr> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html + */ +class Regexp extends AbstractQuery +{ + /** + * Construct regexp query. + * + * @param string $key OPTIONAL Regexp key + * @param string $value OPTIONAL Regexp value + * @param float $boost OPTIONAL Boost value (default = 1) + */ + public function __construct($key = '', $value = null, $boost = 1.0) + { + if (!empty($key)) { + $this->setValue($key, $value, $boost); + } + } + + /** + * Sets the query expression for a key with its boost value. + * + * @param string $key + * @param string $value + * @param float $boost + * + * @return $this + */ + public function setValue($key, $value, $boost = 1.0) + { + return $this->setParam($key, array('value' => $value, 'boost' => $boost)); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Simple.php b/vendor/ruflin/elastica/lib/Elastica/Query/Simple.php new file mode 100644 index 00000000..6ba9310d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Simple.php @@ -0,0 +1,54 @@ +<?php +namespace Elastica\Query; + +/** + * Simple query + * Pure php array query. Can be used to create any not existing type of query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Simple extends AbstractQuery +{ + /** + * Query. + * + * @var array Query + */ + protected $_query = array(); + + /** + * Constructs a query based on an array. + * + * @param array $query Query array + */ + public function __construct(array $query) + { + $this->setQuery($query); + } + + /** + * Sets new query array. + * + * @param array $query Query array + * + * @return $this + */ + public function setQuery(array $query) + { + $this->_query = $query; + + return $this; + } + + /** + * Converts query to array. + * + * @return array Query array + * + * @see \Elastica\Query\AbstractQuery::toArray() + */ + public function toArray() + { + return $this->_query; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/SimpleQueryString.php b/vendor/ruflin/elastica/lib/Elastica/Query/SimpleQueryString.php new file mode 100644 index 00000000..c2302d44 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/SimpleQueryString.php @@ -0,0 +1,83 @@ +<?php +namespace Elastica\Query; + +/** + * Class SimpleQueryString. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html + */ +class SimpleQueryString extends AbstractQuery +{ + const OPERATOR_AND = 'and'; + const OPERATOR_OR = 'or'; + + /** + * @param string $query + * @param array $fields + */ + public function __construct($query, array $fields = array()) + { + $this->setQuery($query); + if (sizeof($fields)) { + $this->setFields($fields); + } + } + + /** + * Set the querystring for this query. + * + * @param string $query see ES documentation for querystring syntax + * + * @return $this + */ + public function setQuery($query) + { + return $this->setParam('query', $query); + } + + /** + * @param string[] $fields the fields on which to perform this query. Defaults to index.query.default_field. + * + * @return $this + */ + public function setFields(array $fields) + { + return $this->setParam('fields', $fields); + } + + /** + * Set the default operator to use if no explicit operator is defined in the query string. + * + * @param string $operator see OPERATOR_* constants for options + * + * @return $this + */ + public function setDefaultOperator($operator) + { + return $this->setParam('default_operator', $operator); + } + + /** + * Set the analyzer used to analyze each term of the query. + * + * @param string $analyzer + * + * @return $this + */ + public function setAnalyzer($analyzer) + { + return $this->setParam('analyzer', $analyzer); + } + + /** + * Set minimum_should_match option. + * + * @param int|string $minimumShouldMatch + * + * @return $this + */ + public function setMinimumShouldMatch($minimumShouldMatch) + { + return $this->setParam('minimum_should_match', $minimumShouldMatch); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Term.php b/vendor/ruflin/elastica/lib/Elastica/Query/Term.php new file mode 100644 index 00000000..8cfe0a88 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Term.php @@ -0,0 +1,49 @@ +<?php +namespace Elastica\Query; + +/** + * Term query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html + */ +class Term extends AbstractQuery +{ + /** + * Constructs the Term query object. + * + * @param array $term OPTIONAL Calls setTerm with the given $term array + */ + public function __construct(array $term = array()) + { + $this->setRawTerm($term); + } + + /** + * Set term can be used instead of addTerm if some more special + * values for a term have to be set. + * + * @param array $term Term array + * + * @return $this + */ + public function setRawTerm(array $term) + { + return $this->setParams($term); + } + + /** + * Adds a term to the term query. + * + * @param string $key Key to query + * @param string|array $value Values(s) for the query. Boost can be set with array + * @param float $boost OPTIONAL Boost value (default = 1.0) + * + * @return $this + */ + public function setTerm($key, $value, $boost = 1.0) + { + return $this->setRawTerm(array($key => array('value' => $value, 'boost' => $boost))); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Terms.php b/vendor/ruflin/elastica/lib/Elastica/Query/Terms.php new file mode 100644 index 00000000..54f26461 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Terms.php @@ -0,0 +1,107 @@ +<?php +namespace Elastica\Query; + +use Elastica\Exception\InvalidException; + +/** + * Terms query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html + */ +class Terms extends AbstractQuery +{ + /** + * Terms. + * + * @var array Terms + */ + protected $_terms = array(); + + /** + * Params. + * + * @var array Params + */ + protected $_params = array(); + + /** + * Terms key. + * + * @var string Terms key + */ + protected $_key = ''; + + /** + * Construct terms query. + * + * @param string $key OPTIONAL Terms key + * @param array $terms OPTIONAL Terms list + */ + public function __construct($key = '', array $terms = array()) + { + $this->setTerms($key, $terms); + } + + /** + * Sets key and terms for the query. + * + * @param string $key Terms key + * @param array $terms Terms for the query. + * + * @return $this + */ + public function setTerms($key, array $terms) + { + $this->_key = $key; + $this->_terms = array_values($terms); + + return $this; + } + + /** + * Adds a single term to the list. + * + * @param string $term Term + * + * @return $this + */ + public function addTerm($term) + { + $this->_terms[] = $term; + + return $this; + } + + /** + * Sets the minimum matching values. + * + * @param int $minimum Minimum value + * + * @return $this + */ + public function setMinimumMatch($minimum) + { + return $this->setParam('minimum_match', (int) $minimum); + } + + /** + * Converts the terms object to an array. + * + * @see \Elastica\Query\AbstractQuery::toArray() + * + * @throws \Elastica\Exception\InvalidException If term key is empty + * + * @return array Query array + */ + public function toArray() + { + if (empty($this->_key)) { + throw new InvalidException('Terms key has to be set'); + } + $this->setParam($this->_key, $this->_terms); + + return parent::toArray(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/TopChildren.php b/vendor/ruflin/elastica/lib/Elastica/Query/TopChildren.php new file mode 100644 index 00000000..6f15c79d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/TopChildren.php @@ -0,0 +1,53 @@ +<?php +namespace Elastica\Query; + +use Elastica\Query as BaseQuery; + +/** + * Runs the child query with an estimated hits size, and out of the hit docs, aggregates it into parent docs. + * + * @author Wu Yang <darkyoung@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-top-children-query.html + */ +class TopChildren extends AbstractQuery +{ + /** + * Construct topChildren query. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * @param string $type Parent document type + */ + public function __construct($query, $type = null) + { + $this->setQuery($query); + $this->setType($type); + } + + /** + * Sets query object. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setQuery($query) + { + $query = BaseQuery::create($query); + $data = $query->toArray(); + + return $this->setParam('query', $data['query']); + } + + /** + * Set type of the parent document. + * + * @param string $type Parent document type + * + * @return $this + */ + public function setType($type) + { + return $this->setParam('type', $type); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Query/Wildcard.php b/vendor/ruflin/elastica/lib/Elastica/Query/Wildcard.php new file mode 100644 index 00000000..bfa5e751 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Query/Wildcard.php @@ -0,0 +1,40 @@ +<?php +namespace Elastica\Query; + +/** + * Wildcard query. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html + */ +class Wildcard extends AbstractQuery +{ + /** + * Construct wildcard query. + * + * @param string $key OPTIONAL Wildcard key + * @param string $value OPTIONAL Wildcard value + * @param float $boost OPTIONAL Boost value (default = 1) + */ + public function __construct($key = '', $value = null, $boost = 1.0) + { + if (!empty($key)) { + $this->setValue($key, $value, $boost); + } + } + + /** + * Sets the query expression for a key with its boost value. + * + * @param string $key + * @param string $value + * @param float $boost + * + * @return $this + */ + public function setValue($key, $value, $boost = 1.0) + { + return $this->setParam($key, array('value' => $value, 'boost' => $boost)); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder.php new file mode 100644 index 00000000..477c4525 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder.php @@ -0,0 +1,114 @@ +<?php +namespace Elastica; + +use Elastica\Exception\QueryBuilderException; +use Elastica\QueryBuilder\DSL; +use Elastica\QueryBuilder\Facade; +use Elastica\QueryBuilder\Version; +use Elastica\QueryBuilder\Version\Version150; + +/** + * Query Builder. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class QueryBuilder +{ + /** + * @var Version + */ + private $_version; + + /** + * @var Facade[] + */ + private $_facades = array(); + + /** + * Constructor. + * + * @param Version $version + */ + public function __construct(Version $version = null) + { + $this->_version = $version ?: new Version150(); + + $this->addDSL(new DSL\Query()); + $this->addDSL(new DSL\Filter()); + $this->addDSL(new DSL\Aggregation()); + $this->addDSL(new DSL\Suggest()); + } + + /** + * Returns Facade for custom DSL object. + * + * @param $dsl + * @param array $arguments + * + * @throws QueryBuilderException + * + * @return Facade + */ + public function __call($dsl, array $arguments) + { + if (false === isset($this->_facades[$dsl])) { + throw new QueryBuilderException('DSL "'.$dsl.'" not supported'); + } + + return $this->_facades[$dsl]; + } + + /** + * Adds a new DSL object. + * + * @param DSL $dsl + */ + public function addDSL(DSL $dsl) + { + $this->_facades[$dsl->getType()] = new Facade($dsl, $this->_version); + } + + /* + * convenience methods + */ + + /** + * Query DSL. + * + * @return DSL\Query + */ + public function query() + { + return $this->_facades[DSL::TYPE_QUERY]; + } + + /** + * Filter DSL. + * + * @return DSL\Filter + */ + public function filter() + { + return $this->_facades[DSL::TYPE_FILTER]; + } + + /** + * Aggregation DSL. + * + * @return DSL\Aggregation + */ + public function aggregation() + { + return $this->_facades[DSL::TYPE_AGGREGATION]; + } + + /** + * Suggest DSL. + * + * @return DSL\Suggest + */ + public function suggest() + { + return $this->_facades[DSL::TYPE_SUGGEST]; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL.php new file mode 100644 index 00000000..976de5f4 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL.php @@ -0,0 +1,22 @@ +<?php +namespace Elastica\QueryBuilder; + +/** + * DSL Interface. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +interface DSL +{ + const TYPE_QUERY = 'query'; + const TYPE_FILTER = 'filter'; + const TYPE_AGGREGATION = 'aggregation'; + const TYPE_SUGGEST = 'suggest'; + + /** + * must return type for QueryBuilder usage. + * + * @return string + */ + public function getType(); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Aggregation.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Aggregation.php new file mode 100644 index 00000000..8393b8aa --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Aggregation.php @@ -0,0 +1,470 @@ +<?php +namespace Elastica\QueryBuilder\DSL; + +use Elastica\Aggregation\Avg; +use Elastica\Aggregation\Cardinality; +use Elastica\Aggregation\DateHistogram; +use Elastica\Aggregation\DateRange; +use Elastica\Aggregation\ExtendedStats; +use Elastica\Aggregation\Filter as FilterAggregation; +use Elastica\Aggregation\Filters; +use Elastica\Aggregation\GeoDistance; +use Elastica\Aggregation\GeohashGrid; +use Elastica\Aggregation\GlobalAggregation; +use Elastica\Aggregation\Histogram; +use Elastica\Aggregation\IpRange; +use Elastica\Aggregation\Max; +use Elastica\Aggregation\Min; +use Elastica\Aggregation\Missing; +use Elastica\Aggregation\Nested; +use Elastica\Aggregation\Percentiles; +use Elastica\Aggregation\Range; +use Elastica\Aggregation\ReverseNested; +use Elastica\Aggregation\ScriptedMetric; +use Elastica\Aggregation\SignificantTerms; +use Elastica\Aggregation\Stats; +use Elastica\Aggregation\Sum; +use Elastica\Aggregation\Terms; +use Elastica\Aggregation\TopHits; +use Elastica\Aggregation\ValueCount; +use Elastica\Exception\NotImplementedException; +use Elastica\Filter\AbstractFilter; +use Elastica\QueryBuilder\DSL; + +/** + * elasticsearch aggregation DSL. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html + */ +class Aggregation implements DSL +{ + /** + * must return type for QueryBuilder usage. + * + * @return string + */ + public function getType() + { + return DSL::TYPE_AGGREGATION; + } + + /** + * min aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-min-aggregation.html + * + * @param string $name + * + * @return Min + */ + public function min($name) + { + return new Min($name); + } + + /** + * max aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html + * + * @param string $name + * + * @return Max + */ + public function max($name) + { + return new Max($name); + } + + /** + * sum aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html + * + * @param string $name + * + * @return Sum + */ + public function sum($name) + { + return new Sum($name); + } + + /** + * avg aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-avg-aggregation.html + * + * @param string $name + * + * @return Avg + */ + public function avg($name) + { + return new Avg($name); + } + + /** + * stats aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-stats-aggregation.html + * + * @param string $name + * + * @return Stats + */ + public function stats($name) + { + return new Stats($name); + } + + /** + * extended stats aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html + * + * @param string $name + * + * @return ExtendedStats + */ + public function extended_stats($name) + { + return new ExtendedStats($name); + } + + /** + * value count aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html + * + * @param string $name + * @param string $field + * + * @return ValueCount + */ + public function value_count($name, $field) + { + return new ValueCount($name, $field); + } + + /** + * percentiles aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html + * + * @param string $name the name of this aggregation + * @param string $field the field on which to perform this aggregation + * + * @return Percentiles + */ + public function percentiles($name, $field = null) + { + return new Percentiles($name, $field); + } + + /** + * percentile ranks aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-rank-aggregation.html + * + * @param string $name + */ + public function percentile_ranks($name) + { + throw new NotImplementedException(); + } + + /** + * cardinality aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html + * + * @param string $name + * + * @return Cardinality + */ + public function cardinality($name) + { + return new Cardinality($name); + } + + /** + * geo bounds aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-geobounds-aggregation.html + * + * @param string $name + */ + public function geo_bounds($name) + { + throw new NotImplementedException(); + } + + /** + * top hits aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html + * + * @param string $name + * + * @return TopHits + */ + public function top_hits($name) + { + return new TopHits($name); + } + + /** + * scripted metric aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-scripted-metric-aggregation.html + * + * @param string $name + * @param string|null $initScript + * @param string|null $mapScript + * @param string|null $combineScript + * @param string|null $reduceScript + * + * @return ScriptedMetric + */ + public function scripted_metric($name, $initScript = null, $mapScript = null, $combineScript = null, $reduceScript = null) + { + return new ScriptedMetric($name, $initScript, $mapScript, $combineScript, $reduceScript); + } + + /** + * global aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-global-aggregation.html + * + * @param string $name + * + * @return GlobalAggregation + */ + public function global_agg($name) + { + return new GlobalAggregation($name); + } + + /** + * filter aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html + * + * @param string $name + * @param AbstractFilter $filter + * + * @return FilterAggregation + */ + public function filter($name, AbstractFilter $filter = null) + { + return new FilterAggregation($name, $filter); + } + + /** + * filters aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html + * + * @param string $name + * + * @return Filters + */ + public function filters($name) + { + return new Filters($name); + } + + /** + * missing aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-missing-aggregation.html + * + * @param string $name + * @param string $field + * + * @return Missing + */ + public function missing($name, $field) + { + return new Missing($name, $field); + } + + /** + * nested aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html + * + * @param string $name + * @param string $path the nested path for this aggregation + * + * @return Nested + */ + public function nested($name, $path) + { + return new Nested($name, $path); + } + + /** + * reverse nested aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-reverse-nested-aggregation.html + * + * @param string $name The name of this aggregation + * @param string $path Optional path to the nested object for this aggregation. Defaults to the root of the main document. + * + * @return ReverseNested + */ + public function reverse_nested($name, $path = null) + { + return new ReverseNested($name); + } + + /** + * children aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-children-aggregation.html + * + * @param string $name + */ + public function children($name) + { + throw new NotImplementedException(); + } + + /** + * terms aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html + * + * @param string $name + * + * @return Terms + */ + public function terms($name) + { + return new Terms($name); + } + + /** + * significant terms aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html + * + * @param string $name + * + * @return SignificantTerms + */ + public function significant_terms($name) + { + return new SignificantTerms($name); + } + + /** + * range aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-range-aggregation.html + * + * @param string $name + * + * @return Range + */ + public function range($name) + { + return new Range($name); + } + + /** + * date range aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-daterange-aggregation.html + * + * @param string $name + * + * @return DateRange + */ + public function date_range($name) + { + return new DateRange($name); + } + + /** + * ipv4 range aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-iprange-aggregation.html + * + * @param string $name + * @param string $field + * + * @return IpRange + */ + public function ipv4_range($name, $field) + { + return new IpRange($name, $field); + } + + /** + * histogram aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html + * + * @param string $name the name of this aggregation + * @param string $field the name of the field on which to perform the aggregation + * @param int $interval the interval by which documents will be bucketed + * + * @return Histogram + */ + public function histogram($name, $field, $interval) + { + return new Histogram($name, $field, $interval); + } + + /** + * date histogram aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html + * + * @param string $name the name of this aggregation + * @param string $field the name of the field on which to perform the aggregation + * @param int $interval the interval by which documents will be bucketed + * + * @return DateHistogram + */ + public function date_histogram($name, $field, $interval) + { + return new DateHistogram($name, $field, $interval); + } + + /** + * geo distance aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geodistance-aggregation.html + * + * @param string $name the name if this aggregation + * @param string $field the field on which to perform this aggregation + * @param string|array $origin the point from which distances will be calculated + * + * @return GeoDistance + */ + public function geo_distance($name, $field, $origin) + { + return new GeoDistance($name, $field, $origin); + } + + /** + * geohash grid aggregation. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html + * + * @param string $name the name of this aggregation + * @param string $field the field on which to perform this aggregation + * + * @return GeohashGrid + */ + public function geohash_grid($name, $field) + { + return new GeohashGrid($name, $field); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Filter.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Filter.php new file mode 100644 index 00000000..1c41239f --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Filter.php @@ -0,0 +1,480 @@ +<?php +namespace Elastica\QueryBuilder\DSL; + +use Elastica\Filter\AbstractFilter; +use Elastica\Filter\BoolAnd; +use Elastica\Filter\BoolFilter; +use Elastica\Filter\BoolNot; +use Elastica\Filter\BoolOr; +use Elastica\Filter\Exists; +use Elastica\Filter\GeoBoundingBox; +use Elastica\Filter\GeoDistance; +use Elastica\Filter\GeoDistanceRange; +use Elastica\Filter\GeohashCell; +use Elastica\Filter\GeoPolygon; +use Elastica\Filter\GeoShapePreIndexed; +use Elastica\Filter\GeoShapeProvided; +use Elastica\Filter\HasChild; +use Elastica\Filter\HasParent; +use Elastica\Filter\Ids; +use Elastica\Filter\Indices; +use Elastica\Filter\Limit; +use Elastica\Filter\MatchAll; +use Elastica\Filter\Missing; +use Elastica\Filter\Nested; +use Elastica\Filter\NumericRange; +use Elastica\Filter\Prefix; +use Elastica\Filter\Query as QueryFilter; +use Elastica\Filter\Range; +use Elastica\Filter\Regexp; +use Elastica\Filter\Script; +use Elastica\Filter\Term; +use Elastica\Filter\Terms; +use Elastica\Filter\Type; +use Elastica\Query\AbstractQuery; +use Elastica\QueryBuilder\DSL; + +/** + * elasticsearch filter DSL. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filters.html + */ +class Filter implements DSL +{ + /** + * must return type for QueryBuilder usage. + * + * @return string + */ + public function getType() + { + return self::TYPE_FILTER; + } + + /** + * and filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-and-filter.html + * + * @param AbstractFilter[] $filters + * + * @return BoolAnd + */ + public function bool_and(array $filters = array()) + { + return new BoolAnd($filters); + } + + /** + * bool filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html + * + * @return \Elastica\Filter\Bool + */ + public function bool() + { + return new BoolFilter(); + } + + /** + * exists filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-filter.html + * + * @param string $field + * + * @return Exists + */ + public function exists($field) + { + return new Exists($field); + } + + /** + * geo bounding box filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-bounding-box-filter.html + * + * @param string $key + * @param array $coordinates + * + * @return GeoBoundingBox + */ + public function geo_bounding_box($key, array $coordinates) + { + return new GeoBoundingBox($key, $coordinates); + } + + /** + * geo distance filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html + * + * @param string $key Key + * @param array|string $location Location as array or geohash: array('lat' => 48.86, 'lon' => 2.35) OR 'drm3btev3e86' + * @param string $distance Distance + * + * @return GeoDistance + */ + public function geo_distance($key, $location, $distance) + { + return new GeoDistance($key, $location, $distance); + } + + /** + * geo distance rangefilter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-range-filter.html + * + * @param string $key + * @param array|string $location + * @param array $ranges + * + * @return GeoDistanceRange + */ + public function geo_distance_range($key, $location, array $ranges = array()) + { + return new GeoDistanceRange($key, $location, $ranges); + } + + /** + * geo polygon filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-polygon-filter.html + * + * @param string $key Key + * @param array $points Points making up polygon + * + * @return GeoPolygon + */ + public function geo_polygon($key, array $points) + { + return new GeoPolygon($key, $points); + } + + /** + * provided geo shape filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html#_provided_shape_definition + * + * @param string $path + * @param array $coordinates + * @param string $shapeType + * + * @return GeoShapeProvided + */ + public function geo_shape_provided($path, array $coordinates, $shapeType = GeoShapeProvided::TYPE_ENVELOPE) + { + return new GeoShapeProvided($path, $coordinates, $shapeType); + } + + /** + * pre indexed geo shape filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-filter.html#_pre_indexed_shape + * + * @param string $path The path/field of the shape searched + * @param string $indexedId Id of the pre-indexed shape + * @param string $indexedType Type of the pre-indexed shape + * @param string $indexedIndex Index of the pre-indexed shape + * @param string $indexedPath Path of the pre-indexed shape + * + * @return GeoShapePreIndexed + */ + public function geo_shape_pre_indexed($path, $indexedId, $indexedType, $indexedIndex, $indexedPath) + { + return new GeoShapePreIndexed($path, $indexedId, $indexedType, $indexedIndex, $indexedPath); + } + + /** + * geohash cell filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geohash-cell-filter.html + * + * @param string $key The field on which to filter + * @param array|string $location Location as coordinates array or geohash string ['lat' => 40.3, 'lon' => 45.2] + * @param int|string $precision length of geohash prefix or distance (3, or "50m") + * @param bool $neighbors If true, filters cells next to the given cell. + * + * @return GeohashCell + */ + public function geohash_cell($key, $location, $precision = -1, $neighbors = false) + { + return new GeohashCell($key, $location, $precision, $neighbors); + } + + /** + * has child filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-filter.html + * + * @param AbstractQuery|AbstractFilter $query + * @param string $type + * + * @return HasChild + */ + public function has_child($query, $type = null) + { + return new HasChild($query, $type); + } + + /** + * has parent filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-filter.html + * + * @param AbstractQuery|AbstractFilter $query + * @param string $type + * + * @return HasParent + */ + public function has_parent($query, $type) + { + return new HasParent($query, $type); + } + + /** + * ids filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-filter.html + * + * @param string|\Elastica\Type $type + * @param array $ids + * + * @return Ids + */ + public function ids($type = null, array $ids = array()) + { + return new Ids($type, $ids); + } + + /** + * indices filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-indices-filter.html + * + * @param AbstractFilter $filter filter which will be applied to docs in the specified indices + * @param string[] $indices + * + * @return Indices + */ + public function indices(AbstractFilter $filter, array $indices) + { + return new Indices($filter, $indices); + } + + /** + * limit filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-limit-filter.html + * + * @param int $limit Limit + * + * @return Limit + */ + public function limit($limit) + { + return new Limit($limit); + } + + /** + * match all filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-all-filter.html + * + * @return MatchAll + */ + public function match_all() + { + return new MatchAll(); + } + + /** + * missing filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-missing-filter.html + * + * @param string $field + * + * @return Missing + */ + public function missing($field = '') + { + return new Missing($field); + } + + /** + * nested filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-filter.html + * + * @return Nested + */ + public function nested() + { + return new Nested(); + } + + /** + * not filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-not-filter.html + * + * @param AbstractFilter $filter + * + * @return BoolNot + */ + public function bool_not(AbstractFilter $filter) + { + return new BoolNot($filter); + } + + /** + * numeric range filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-numeric-range-filter.html + * + * @param string $fieldName Field name + * @param array $args Field arguments + * + * @return NumericRange + */ + public function numeric_range($fieldName = '', array $args = array()) + { + return new NumericRange($fieldName, $args); + } + + /** + * or filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-or-filter.html + * + * @param AbstractFilter[] $filters + * + * @return BoolOr + */ + public function bool_or(array $filters = array()) + { + return new BoolOr($filters); + } + + /** + * prefix filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-prefix-filter.html + * + * @param string $field + * @param string $prefix + * + * @return Prefix + */ + public function prefix($field = '', $prefix = '') + { + return new Prefix($field, $prefix); + } + + /** + * query filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html + * + * @param array|AbstractQuery $query + * + * @return QueryFilter + */ + public function query($query = null) + { + return new QueryFilter($query); + } + + /** + * range filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html + * + * @param string $fieldName + * @param array $args + * + * @return Range + */ + public function range($fieldName = '', array $args = array()) + { + return new Range($fieldName, $args); + } + + /** + * regexp filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-filter.html + * + * @param string $field Field name + * @param string $regexp Regular expression + * @param array $options Regular expression options + * + * @return Regexp + */ + public function regexp($field = '', $regexp = '', $options = array()) + { + return new Regexp($field, $regexp, $options); + } + + /** + * script filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-filter.html + * + * @param array|string|\Elastica\Script $script + * + * @return Script + */ + public function script($script = null) + { + return new Script($script); + } + + /** + * term filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html + * + * @param array $term + * + * @return Term + */ + public function term(array $term = array()) + { + return new Term($term); + } + + /** + * terms filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html + * + * @param string $key + * @param array $terms + * + * @return Terms + */ + public function terms($key = '', array $terms = array()) + { + return new Terms($key, $terms); + } + + /** + * type filter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-type-filter.html + * + * @param string $type + * + * @return Type + */ + public function type($type = null) + { + return new Type($type); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Query.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Query.php new file mode 100644 index 00000000..7d1aca68 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Query.php @@ -0,0 +1,586 @@ +<?php +namespace Elastica\QueryBuilder\DSL; + +use Elastica\Exception\NotImplementedException; +use Elastica\Filter\AbstractFilter; +use Elastica\Query\AbstractQuery; +use Elastica\Query\BoolQuery; +use Elastica\Query\Boosting; +use Elastica\Query\Common; +use Elastica\Query\ConstantScore; +use Elastica\Query\DisMax; +use Elastica\Query\Filtered; +use Elastica\Query\FunctionScore; +use Elastica\Query\Fuzzy; +use Elastica\Query\FuzzyLikeThis; +use Elastica\Query\HasChild; +use Elastica\Query\HasParent; +use Elastica\Query\Ids; +use Elastica\Query\Match; +use Elastica\Query\MatchAll; +use Elastica\Query\MoreLikeThis; +use Elastica\Query\MultiMatch; +use Elastica\Query\Nested; +use Elastica\Query\Prefix; +use Elastica\Query\QueryString; +use Elastica\Query\Range; +use Elastica\Query\Regexp; +use Elastica\Query\SimpleQueryString; +use Elastica\Query\Term; +use Elastica\Query\Terms; +use Elastica\Query\TopChildren; +use Elastica\Query\Wildcard; +use Elastica\QueryBuilder\DSL; + +/** + * elasticsearch query DSL. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-queries.html + */ +class Query implements DSL +{ + /** + * must return type for QueryBuilder usage. + * + * @return string + */ + public function getType() + { + return self::TYPE_QUERY; + } + + /** + * match query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html + * + * @param string $field + * @param mixed $values + * + * @return Match + */ + public function match($field = null, $values = null) + { + return new Match($field, $values); + } + + /** + * multi match query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html + * + * @return \Elastica\Query\MultiMatch + */ + public function multi_match() + { + return new MultiMatch(); + } + + /** + * bool query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html + * + * @return \Elastica\Query\BoolQuery + */ + public function bool() + { + return new BoolQuery(); + } + + /** + * boosting query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html + * + * @return Boosting + */ + public function boosting() + { + return new Boosting(); + } + + /** + * common terms query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-common-terms-query.html + * + * @param string $field + * @param string $query + * @param float $cutoffFrequency percentage in decimal form (.001 == 0.1%) + * + * @return Common + */ + public function common_terms($field, $query, $cutoffFrequency) + { + return new Common($field, $query, $cutoffFrequency); + } + + /** + * custom filters score query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-custom-filters-score-query.html + */ + public function custom_filters_score() + { + throw new NotImplementedException(); + } + + /** + * custom score query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-custom-score-query.html + */ + public function custom_score() + { + throw new NotImplementedException(); + } + + /** + * custom boost factor query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-custom-boost-factor-query.html + */ + public function custom_boost_factor() + { + throw new NotImplementedException(); + } + + /** + * constant score query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-constant-score-query.html + * + * @param null|\Elastica\Filter\AbstractFilter|array $filter + * + * @return ConstantScore + */ + public function constant_score($filter = null) + { + return new ConstantScore($filter); + } + + /** + * dis max query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html + * + * @return DisMax + */ + public function dis_max() + { + return new DisMax(); + } + + /** + * field query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-field-query.html + */ + public function field() + { + throw new NotImplementedException(); + } + + /** + * filtered query. + * + * @param AbstractFilter $filter + * @param AbstractQuery $query + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html + * + * @return Filtered + */ + public function filtered(AbstractQuery $query = null, AbstractFilter $filter = null) + { + return new Filtered($query, $filter); + } + + /** + * fuzzy like this query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-flt-query.html + * + * @return FuzzyLikeThis + */ + public function fuzzy_like_this() + { + return new FuzzyLikeThis(); + } + + /** + * fuzzy like this field query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-flt-field-query.html + */ + public function fuzzy_like_this_field() + { + throw new NotImplementedException(); + } + + /** + * function score query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html + * + * @return FunctionScore + */ + public function function_score() + { + return new FunctionScore(); + } + + /** + * fuzzy query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html + * + * @param string $fieldName Field name + * @param string $value String to search for + * + * @return Fuzzy + */ + public function fuzzy($fieldName = null, $value = null) + { + return new Fuzzy($fieldName, $value); + } + + /** + * geo shape query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-query.html + */ + public function geo_shape() + { + throw new NotImplementedException(); + } + + /** + * has child query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * @param string $type Parent document type + * + * @return HasChild + */ + public function has_child($query, $type = null) + { + return new HasChild($query, $type); + } + + /** + * has parent query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * @param string $type Parent document type + * + * @return HasParent + */ + public function has_parent($query, $type) + { + return new HasParent($query, $type); + } + + /** + * ids query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html + * + * @param array|string|\Elastica\Type $type + * @param array $ids + * + * @return Ids + */ + public function ids($type = null, array $ids = array()) + { + return new Ids($type, $ids); + } + + /** + * indices query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-indices-query.html + */ + public function indices() + { + throw new NotImplementedException(); + } + + /** + * match all query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-all-query.html + * + * @return MatchAll + */ + public function match_all() + { + return new MatchAll(); + } + + /** + * more like this query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html + * + * @return MoreLikeThis + */ + public function more_like_this() + { + return new MoreLikeThis(); + } + + /** + * more_like_this_field query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/1.4/query-dsl-mlt-field-query.html + * @deprecated More Like This Field query is deprecated as of ES 1.4 and will be removed in ES 2.0 + */ + public function more_like_this_field() + { + throw new NotImplementedException(); + } + + /** + * nested query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html + * + * @return Nested + */ + public function nested() + { + return new Nested(); + } + + /** + * prefix query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html + * + * @param array $prefix Prefix array + * + * @return Prefix + */ + public function prefix(array $prefix = array()) + { + return new Prefix($prefix); + } + + /** + * query string query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html + * + * @param string $queryString OPTIONAL Query string for object + * + * @return QueryString + */ + public function query_string($queryString = '') + { + return new QueryString($queryString); + } + + /** + * simple_query_string query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html + * + * @param string $query + * @param array $fields + * + * @return SimpleQueryString + */ + public function simple_query_string($query, array $fields = array()) + { + return new SimpleQueryString($query, $fields); + } + + /** + * range query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html + * + * @param string $fieldName + * @param array $args + * + * @return Range + */ + public function range($fieldName = null, array $args = array()) + { + return new Range($fieldName, $args); + } + + /** + * regexp query. + * + * @param string $key + * @param string $value + * @param float $boost + * + * @return Regexp + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html + */ + public function regexp($key = '', $value = null, $boost = 1.0) + { + return new Regexp($key, $value, $boost); + } + + /** + * span first query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-first-query.html + */ + public function span_first() + { + throw new NotImplementedException(); + } + + /** + * span multi term query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-multi-term-query.html + */ + public function span_multi_term() + { + throw new NotImplementedException(); + } + + /** + * span near query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-near-query.html + */ + public function span_near() + { + throw new NotImplementedException(); + } + + /** + * span not query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-not-query.html + */ + public function span_not() + { + throw new NotImplementedException(); + } + + /** + * span or query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-or-query.html + */ + public function span_or() + { + throw new NotImplementedException(); + } + + /** + * span term query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-span-term-query.html + */ + public function span_term() + { + throw new NotImplementedException(); + } + + /** + * term query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html + * + * @param array $term + * + * @return Term + */ + public function term(array $term = array()) + { + return new Term($term); + } + + /** + * terms query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html + * + * @param string $key + * @param array $terms + * + * @return Terms + */ + public function terms($key = '', array $terms = array()) + { + return new Terms($key, $terms); + } + + /** + * top children query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-top-children-query.html + * + * @param string|AbstractQuery|\Elastica\Query $query + * @param string $type + * + * @return TopChildren + */ + public function top_children($query, $type = null) + { + return new TopChildren($query, $type); + } + + /** + * wildcard query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html + * + * @param string $key OPTIONAL Wildcard key + * @param string $value OPTIONAL Wildcard value + * @param float $boost OPTIONAL Boost value (default = 1) + * + * @return Wildcard + */ + public function wildcard($key = '', $value = null, $boost = 1.0) + { + return new Wildcard($key, $value, $boost); + } + + /** + * text query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/0.90/query-dsl-text-query.html + */ + public function text() + { + throw new NotImplementedException(); + } + + /** + * minimum should match query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-minimum-should-match.html + */ + public function minimum_should_match() + { + throw new NotImplementedException(); + } + + /** + * template query. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-template-query.html + */ + public function template() + { + throw new NotImplementedException(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Suggest.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Suggest.php new file mode 100644 index 00000000..9a54ccde --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Suggest.php @@ -0,0 +1,83 @@ +<?php +namespace Elastica\QueryBuilder\DSL; + +use Elastica\Exception\NotImplementedException; +use Elastica\QueryBuilder\DSL; +use Elastica\Suggest\Completion; +use Elastica\Suggest\Phrase; +use Elastica\Suggest\Term; + +/** + * elasticsearch suggesters DSL. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html + */ +class Suggest implements DSL +{ + /** + * must return type for QueryBuilder usage. + * + * @return string + */ + public function getType() + { + return self::TYPE_SUGGEST; + } + + /** + * term suggester. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-term.html + * + * @param $name + * @param $field + * + * @return Term + */ + public function term($name, $field) + { + return new Term($name, $field); + } + + /** + * phrase suggester. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-phrase.html + * + * @param $name + * @param $field + * + * @return Phrase + */ + public function phrase($name, $field) + { + return new Phrase($name, $field); + } + + /** + * completion suggester. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html + * + * @param string $name + * @param string $field + * + * @return Completion + */ + public function completion($name, $field) + { + return new Completion($name, $field); + } + + /** + * context suggester. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/suggester-context.html + */ + public function context() + { + throw new NotImplementedException(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Facade.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Facade.php new file mode 100644 index 00000000..b0f6da82 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Facade.php @@ -0,0 +1,64 @@ +<?php +namespace Elastica\QueryBuilder; + +use Elastica\Exception\QueryBuilderException; + +/** + * Facade for a specific DSL object. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + **/ +class Facade +{ + /** + * @var DSL + */ + private $_dsl; + + /** + * @var Version + */ + private $_version; + + /** + * Constructor. + * + * @param DSL $dsl + * @param Version $version + */ + public function __construct(DSL $dsl, Version $version) + { + $this->_dsl = $dsl; + $this->_version = $version; + } + + /** + * Executes DSL methods. + * + * @param string $name + * @param array $arguments + * + * @throws QueryBuilderException + * + * @return mixed + */ + public function __call($name, array $arguments) + { + // defined check + if (false === method_exists($this->_dsl, $name)) { + throw new QueryBuilderException( + 'undefined '.$this->_dsl->getType().' "'.$name.'"' + ); + } + + // version support check + if (false === $this->_version->supports($name, $this->_dsl->getType())) { + $reflection = new \ReflectionClass($this->_version); + throw new QueryBuilderException( + $this->_dsl->getType().' "'.$name.'" in '.$reflection->getShortName().' not supported' + ); + } + + return call_user_func_array(array($this->_dsl, $name), $arguments); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version.php new file mode 100644 index 00000000..5230600d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version.php @@ -0,0 +1,101 @@ +<?php +namespace Elastica\QueryBuilder; + +/** + * Abstract Version class. + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +abstract class Version +{ + /** + * supported query methods. + * + * @var string[] + */ + protected $queries = array(); + + /** + * supported filter methods. + * + * @var string[] + */ + protected $filters = array(); + + /** + * supported aggregation methods. + * + * @var string[] + */ + protected $aggregations = array(); + + /** + * supported $suggester methods. + * + * @var string[] + */ + protected $suggesters = array(); + + /** + * returns true if $name is supported, false otherwise. + * + * @param string $name + * @param $type + * + * @return bool + */ + public function supports($name, $type) + { + switch ($type) { + case DSL::TYPE_QUERY: + $supports = in_array($name, $this->queries); + break; + case DSL::TYPE_FILTER: + $supports = in_array($name, $this->filters); + break; + case DSL::TYPE_AGGREGATION: + $supports = in_array($name, $this->aggregations); + break; + case DSL::TYPE_SUGGEST: + $supports = in_array($name, $this->suggesters); + break; + default: + // disables version check in Facade for custom DSL objects + $supports = true; + } + + return $supports; + } + + /** + * @return string[] + */ + public function getAggregations() + { + return $this->aggregations; + } + + /** + * @return string[] + */ + public function getFilters() + { + return $this->filters; + } + + /** + * @return string[] + */ + public function getQueries() + { + return $this->queries; + } + + /** + * @return string[] + */ + public function getSuggesters() + { + return $this->suggesters; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version090.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version090.php new file mode 100644 index 00000000..193ba852 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version090.php @@ -0,0 +1,97 @@ +<?php +namespace Elastica\QueryBuilder\Version; + +use Elastica\QueryBuilder\Version; + +/** + * elasticsearch 0.9 DSL. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/0.90/index.html + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class Version090 extends Version +{ + protected $queries = array( + 'match', + 'multi_match', + 'bool', + 'boosting', + 'common_terms', + 'custom_filters_score', + 'custom_score', + 'custom_boost_factor', + 'constant_score', + 'dis_max', + 'field', + 'filtered', + 'fuzzy_like_this', + 'fuzzy_like_this_field', + 'function_score', + 'fuzzy', + 'geo_shape', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'match_all', + 'more_like_this', + 'more_like_this_field', + 'nested', + 'prefix', + 'query_string', + 'simple_query_string', + 'range', + 'regexp', + 'span_first', + 'span_multi_term', + 'span_near', + 'span_not', + 'span_or', + 'span_term', + 'term', + 'terms', + 'top_children', + 'wildcard', + 'text', + 'minimum_should_match', + ); + + protected $filters = array( + 'bool_and', // original: bool + 'bool', + 'exists', + 'geo_bounding_box', + 'geo_distance', + 'geo_distance_range', + 'geo_polygon', + 'geo_shape_provided', // original: geo_shape + 'geo_shape_pre_indexed', // original: geo_shape + 'geohash_cell', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'limit', + 'match_all', + 'missing', + 'nested', + 'bool_not', // original: not + 'numeric_range', + 'bool_or', // original: or + 'prefix', + 'query', + 'range', + 'regexp', + 'script', + 'term', + 'terms', + 'type', + ); + + protected $suggesters = array( + 'term', + 'phrase', + 'completion', + ); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version100.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version100.php new file mode 100644 index 00000000..66a5c9cd --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version100.php @@ -0,0 +1,123 @@ +<?php +namespace Elastica\QueryBuilder\Version; + +use Elastica\QueryBuilder\Version; + +/** + * elasticsearch 1.0 DSL. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/1.x/index.html + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class Version100 extends Version +{ + protected $queries = array( + 'match', + 'multi_match', + 'bool', + 'boosting', + 'common_terms', + 'constant_score', + 'dis_max', + 'filtered', + 'fuzzy_like_this', + 'fuzzy_like_this_field', + 'function_score', + 'fuzzy', + 'geo_shape', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'match_all', + 'more_like_this', + 'more_like_this_field', + 'nested', + 'prefix', + 'query_string', + 'simple_query_string', + 'range', + 'regexp', + 'span_first', + 'span_multi_term', + 'span_near', + 'span_not', + 'span_or', + 'span_term', + 'term', + 'terms', + 'top_children', + 'wildcard', + 'minimum_should_match', + + // removed in 1.0.0 + // 'text' + // 'field' + // 'custom_filters_score' + // 'custom_score' + // 'custom_boost_factor' + ); + + protected $filters = array( + 'bool_and', // original: bool + 'bool', + 'exists', + 'geo_bounding_box', + 'geo_distance', + 'geo_distance_range', + 'geo_polygon', + 'geo_shape_provided', // original: geo_shape + 'geo_shape_pre_indexed', // original: geo_shape + 'geohash_cell', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'limit', + 'match_all', + 'missing', + 'nested', + 'bool_not', // original: not + 'bool_or', // original: or + 'prefix', + 'query', + 'range', + 'regexp', + 'script', + 'term', + 'terms', + 'type', + + // removed in 1.0.0 + // 'numeric_range' + ); + + protected $aggregations = array( + 'min', + 'max', + 'sum', + 'avg', + 'stats', + 'extended_stats', + 'value_count', + 'global_agg', // original: global + 'filter', + 'missing', + 'nested', + 'terms', + 'range', + 'date_range', + 'ipv4_range', + 'histogram', + 'date_histogram', + 'geo_distance', + 'geohash_grid', + ); + + protected $suggesters = array( + 'term', + 'phrase', + 'completion', + ); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version110.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version110.php new file mode 100644 index 00000000..b6465e76 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version110.php @@ -0,0 +1,131 @@ +<?php +namespace Elastica\QueryBuilder\Version; + +use Elastica\QueryBuilder\Version; + +/** + * elasticsearch 1.1 DSL. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/1.x/index.html + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class Version110 extends Version +{ + protected $queries = array( + 'match', + 'multi_match', + 'bool', + 'boosting', + 'common_terms', + 'constant_score', + 'dis_max', + 'filtered', + 'fuzzy_like_this', + 'fuzzy_like_this_field', + 'function_score', + 'fuzzy', + 'geo_shape', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'match_all', + 'more_like_this', + 'more_like_this_field', + 'nested', + 'prefix', + 'query_string', + 'simple_query_string', + 'range', + 'regexp', + 'span_first', + 'span_multi_term', + 'span_near', + 'span_not', + 'span_or', + 'span_term', + 'term', + 'terms', + 'top_children', + 'wildcard', + 'minimum_should_match', + + // removed in 1.0.0 + // 'text' + // 'field' + // 'custom_filters_score' + // 'custom_score' + // 'custom_boost_factor' + + // new in 1.1.0 + 'template', + ); + + protected $filters = array( + 'bool_and', // original: bool + 'bool', + 'exists', + 'geo_bounding_box', + 'geo_distance', + 'geo_distance_range', + 'geo_polygon', + 'geo_shape_provided', // original: geo_shape + 'geo_shape_pre_indexed', // original: geo_shape + 'geohash_cell', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'limit', + 'match_all', + 'missing', + 'nested', + 'bool_not', // original: not + 'bool_or', // original: or + 'prefix', + 'query', + 'range', + 'regexp', + 'script', + 'term', + 'terms', + 'type', + + // removed in 1.0.0 + // 'numeric_range' + ); + + protected $aggregations = array( + 'min', + 'max', + 'sum', + 'avg', + 'stats', + 'extended_stats', + 'value_count', + 'global_agg', // original: global + 'filter', + 'missing', + 'nested', + 'terms', + 'range', + 'date_range', + 'ipv4_range', + 'histogram', + 'date_histogram', + 'geo_distance', + 'geohash_grid', + + // new in 1.1.0 + 'percentiles', + 'cardinality', + 'significant_terms', + ); + + protected $suggesters = array( + 'term', + 'phrase', + 'completion', + ); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version120.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version120.php new file mode 100644 index 00000000..f74e3bdc --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version120.php @@ -0,0 +1,137 @@ +<?php +namespace Elastica\QueryBuilder\Version; + +use Elastica\QueryBuilder\Version; + +/** + * elasticsearch 1.2 DSL. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/1.x/index.html + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class Version120 extends Version +{ + protected $queries = array( + 'match', + 'multi_match', + 'bool', + 'boosting', + 'common_terms', + 'constant_score', + 'dis_max', + 'filtered', + 'fuzzy_like_this', + 'fuzzy_like_this_field', + 'function_score', + 'fuzzy', + 'geo_shape', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'match_all', + 'more_like_this', + 'more_like_this_field', + 'nested', + 'prefix', + 'query_string', + 'simple_query_string', + 'range', + 'regexp', + 'span_first', + 'span_multi_term', + 'span_near', + 'span_not', + 'span_or', + 'span_term', + 'term', + 'terms', + 'top_children', + 'wildcard', + 'minimum_should_match', + + // removed in 1.0.0 + // 'text' + // 'field' + // 'custom_filters_score' + // 'custom_score' + // 'custom_boost_factor' + + // new in 1.1.0 + 'template', + ); + + protected $filters = array( + 'bool_and', // original: bool + 'bool', + 'exists', + 'geo_bounding_box', + 'geo_distance', + 'geo_distance_range', + 'geo_polygon', + 'geo_shape_provided', // original: geo_shape + 'geo_shape_pre_indexed', // original: geo_shape + 'geohash_cell', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'limit', + 'match_all', + 'missing', + 'nested', + 'bool_not', // original: not + 'bool_or', // original: or + 'prefix', + 'query', + 'range', + 'regexp', + 'script', + 'term', + 'terms', + 'type', + + // removed in 1.0.0 + // 'numeric_range' + ); + + protected $aggregations = array( + 'min', + 'max', + 'sum', + 'avg', + 'stats', + 'extended_stats', + 'value_count', + 'global_agg', // original: global + 'filter', + 'missing', + 'nested', + 'terms', + 'range', + 'date_range', + 'ipv4_range', + 'histogram', + 'date_histogram', + 'geo_distance', + 'geohash_grid', + + // new in 1.1.0 + 'percentiles', + 'cardinality', + 'significant_terms', + + // new in 1.2.0 + 'reverse_nested', + ); + + protected $suggesters = array( + 'term', + 'phrase', + 'completion', + + // new in 1.2.0 + 'context', + ); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version130.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version130.php new file mode 100644 index 00000000..ad52e3e7 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version130.php @@ -0,0 +1,142 @@ +<?php +namespace Elastica\QueryBuilder\Version; + +use Elastica\QueryBuilder\Version; + +/** + * elasticsearch 1.3 DSL. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/1.3/index.html + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class Version130 extends Version +{ + protected $queries = array( + 'match', + 'multi_match', + 'bool', + 'boosting', + 'common_terms', + 'constant_score', + 'dis_max', + 'filtered', + 'fuzzy_like_this', + 'fuzzy_like_this_field', + 'function_score', + 'fuzzy', + 'geo_shape', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'match_all', + 'more_like_this', + 'more_like_this_field', + 'nested', + 'prefix', + 'query_string', + 'simple_query_string', + 'range', + 'regexp', + 'span_first', + 'span_multi_term', + 'span_near', + 'span_not', + 'span_or', + 'span_term', + 'term', + 'terms', + 'top_children', + 'wildcard', + 'minimum_should_match', + + // removed in 1.0.0 + // 'text' + // 'field' + // 'custom_filters_score' + // 'custom_score' + // 'custom_boost_factor' + + // new in 1.1.0 + 'template', + ); + + protected $filters = array( + 'bool_and', // original: bool + 'bool', + 'exists', + 'geo_bounding_box', + 'geo_distance', + 'geo_distance_range', + 'geo_polygon', + 'geo_shape_provided', // original: geo_shape + 'geo_shape_pre_indexed', // original: geo_shape + 'geohash_cell', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'limit', + 'match_all', + 'missing', + 'nested', + 'bool_not', // original: not + 'bool_or', // original: or + 'prefix', + 'query', + 'range', + 'regexp', + 'script', + 'term', + 'terms', + 'type', + + // removed in 1.0.0 + // 'numeric_range' + ); + + protected $aggregations = array( + 'min', + 'max', + 'sum', + 'avg', + 'stats', + 'extended_stats', + 'value_count', + 'global_agg', // original: global + 'filter', + 'missing', + 'nested', + 'terms', + 'range', + 'date_range', + 'ipv4_range', + 'histogram', + 'date_histogram', + 'geo_distance', + 'geohash_grid', + + // new in 1.1.0 + 'percentiles', + 'cardinality', + 'significant_terms', + + // new in 1.2.0 + 'reverse_nested', + + // new in 1.3.0 + 'percentile_ranks', + 'geo_bounds', + 'top_hits', + ); + + protected $suggesters = array( + 'term', + 'phrase', + 'completion', + + // new in 1.2.0 + 'context', + ); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version140.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version140.php new file mode 100644 index 00000000..7b5d73e3 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version140.php @@ -0,0 +1,145 @@ +<?php +namespace Elastica\QueryBuilder\Version; + +/** + * elasticsearch 1.4 DSL. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/1.4/index.html + * + * @author Manuel Andreo Garcia <andreo.garcia@googlemail.com> + */ +class Version140 extends Version130 +{ + protected $queries = array( + 'match', + 'multi_match', + 'bool', + 'boosting', + 'common_terms', + 'constant_score', + 'dis_max', + 'filtered', + 'fuzzy_like_this', + 'fuzzy_like_this_field', + 'function_score', + 'fuzzy', + 'geo_shape', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'match_all', + 'more_like_this', + 'more_like_this_field', + 'nested', + 'prefix', + 'query_string', + 'simple_query_string', + 'range', + 'regexp', + 'span_first', + 'span_multi_term', + 'span_near', + 'span_not', + 'span_or', + 'span_term', + 'term', + 'terms', + 'top_children', + 'wildcard', + 'minimum_should_match', + + // removed in 1.0.0 + // 'text' + // 'field' + // 'custom_filters_score' + // 'custom_score' + // 'custom_boost_factor' + + // new in 1.1.0 + 'template', + ); + + protected $filters = array( + 'bool_and', // original: bool + 'bool', + 'exists', + 'geo_bounding_box', + 'geo_distance', + 'geo_distance_range', + 'geo_polygon', + 'geo_shape_provided', // original: geo_shape + 'geo_shape_pre_indexed', // original: geo_shape + 'geohash_cell', + 'has_child', + 'has_parent', + 'ids', + 'indices', + 'limit', + 'match_all', + 'missing', + 'nested', + 'bool_not', // original: not + 'bool_or', // original: or + 'prefix', + 'query', + 'range', + 'regexp', + 'script', + 'term', + 'terms', + 'type', + + // removed in 1.0.0 + // 'numeric_range' + ); + + protected $aggregations = array( + 'min', + 'max', + 'sum', + 'avg', + 'stats', + 'extended_stats', + 'value_count', + 'global_agg', // original: global + 'filter', + 'missing', + 'nested', + 'terms', + 'range', + 'date_range', + 'ipv4_range', + 'histogram', + 'date_histogram', + 'geo_distance', + 'geohash_grid', + + // new in 1.1.0 + 'percentiles', + 'cardinality', + 'significant_terms', + + // new in 1.2.0 + 'reverse_nested', + + // new in 1.3.0 + 'percentile_ranks', + 'geo_bounds', + 'top_hits', + + // new in 1.4.0 + 'scripted_metric', + 'filters', + 'children', + ); + + protected $suggesters = array( + 'term', + 'phrase', + 'completion', + + // new in 1.2.0 + 'context', + ); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version150.php b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version150.php new file mode 100644 index 00000000..fcb5e087 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version150.php @@ -0,0 +1,14 @@ +<?php +namespace Elastica\QueryBuilder\Version; + +/** + * elasticsearch 1.5 DSL. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/1.5/index.html + * + * @author Igor Denisenko <im.denisenko@yahoo.com> + */ +class Version150 extends Version140 +{ + // nothing was added nor removed +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Request.php b/vendor/ruflin/elastica/lib/Elastica/Request.php new file mode 100644 index 00000000..ab26ff09 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Request.php @@ -0,0 +1,204 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; + +/** + * Elastica Request object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Request extends Param +{ + const HEAD = 'HEAD'; + const POST = 'POST'; + const PUT = 'PUT'; + const GET = 'GET'; + const DELETE = 'DELETE'; + + /** + * @var \Elastica\Connection + */ + protected $_connection; + + /** + * Construct. + * + * @param string $path Request path + * @param string $method OPTIONAL Request method (use const's) (default = self::GET) + * @param array $data OPTIONAL Data array + * @param array $query OPTIONAL Query params + * @param Connection $connection + * + * @return \Elastica\Request OPTIONAL Connection object + */ + public function __construct($path, $method = self::GET, $data = array(), array $query = array(), Connection $connection = null) + { + $this->setPath($path); + $this->setMethod($method); + $this->setData($data); + $this->setQuery($query); + + if ($connection) { + $this->setConnection($connection); + } + } + + /** + * Sets the request method. Use one of the for consts. + * + * @param string $method Request method + * + * @return $this + */ + public function setMethod($method) + { + return $this->setParam('method', $method); + } + + /** + * Get request method. + * + * @return string Request method + */ + public function getMethod() + { + return $this->getParam('method'); + } + + /** + * Sets the request data. + * + * @param array $data Request data + * + * @return $this + */ + public function setData($data) + { + return $this->setParam('data', $data); + } + + /** + * Return request data. + * + * @return array Request data + */ + public function getData() + { + return $this->getParam('data'); + } + + /** + * Sets the request path. + * + * @param string $path Request path + * + * @return $this + */ + public function setPath($path) + { + return $this->setParam('path', $path); + } + + /** + * Return request path. + * + * @return string Request path + */ + public function getPath() + { + return $this->getParam('path'); + } + + /** + * Return query params. + * + * @return array Query params + */ + public function getQuery() + { + return $this->getParam('query'); + } + + /** + * @param array $query + * + * @return $this + */ + public function setQuery(array $query = array()) + { + return $this->setParam('query', $query); + } + + /** + * @param \Elastica\Connection $connection + * + * @return $this + */ + public function setConnection(Connection $connection) + { + $this->_connection = $connection; + + return $this; + } + + /** + * Return Connection Object. + * + * @throws Exception\InvalidException If no valid connection was setted + * + * @return \Elastica\Connection + */ + public function getConnection() + { + if (empty($this->_connection)) { + throw new InvalidException('No valid connection object set'); + } + + return $this->_connection; + } + + /** + * Sends request to server. + * + * @return \Elastica\Response Response object + */ + public function send() + { + $transport = $this->getConnection()->getTransportObject(); + + // Refactor: Not full toArray needed in exec? + return $transport->exec($this, $this->getConnection()->toArray()); + } + + /** + * @return array + */ + public function toArray() + { + $data = $this->getParams(); + if ($this->_connection) { + $data['connection'] = $this->_connection->getParams(); + } + + return $data; + } + + /** + * Converts request to curl request format. + * + * @return string + */ + public function toString() + { + return JSON::stringify($this->toArray()); + } + + /** + * @return string + */ + public function __toString() + { + return $this->toString(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Rescore/AbstractRescore.php b/vendor/ruflin/elastica/lib/Elastica/Rescore/AbstractRescore.php new file mode 100644 index 00000000..0839424d --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Rescore/AbstractRescore.php @@ -0,0 +1,36 @@ +<?php +namespace Elastica\Rescore; + +use Elastica\Param; + +/** + * Abstract rescore object. Should be extended by all rescorers. + * + * @author Jason Hu <mjhu91@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-rescore.html + */ +abstract class AbstractRescore extends Param +{ + /** + * Overridden to return rescore as name. + * + * @return string name + */ + protected function _getBaseName() + { + return 'rescore'; + } + + /** + * Sets window_size. + * + * @param int $size + * + * @return $this + */ + public function setWindowSize($size) + { + return $this->setParam('window_size', $size); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Rescore/Query.php b/vendor/ruflin/elastica/lib/Elastica/Rescore/Query.php new file mode 100644 index 00000000..3b0a1071 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Rescore/Query.php @@ -0,0 +1,91 @@ +<?php +namespace Elastica\Rescore; + +use Elastica\Query as BaseQuery; + +/** + * Query Rescore. + * + * @author Jason Hu <mjhu91@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-rescore.html + */ +class Query extends AbstractRescore +{ + /** + * Constructor. + * + * @param string|\Elastica\Query\AbstractQuery $rescoreQuery + * @param string|\Elastica\Query\AbstractQuery $query + */ + public function __construct($query = null) + { + $this->setParam('query', array()); + $this->setRescoreQuery($query); + } + + /** + * Override default implementation so params are in the format + * expected by elasticsearch. + * + * @return array Rescore array + */ + public function toArray() + { + $data = $this->getParams(); + + if (!empty($this->_rawParams)) { + $data = array_merge($data, $this->_rawParams); + } + + return $data; + } + + /** + * Sets rescoreQuery object. + * + * @param string|\Elastica\Query|\Elastica\Query\AbstractQuery $query + * + * @return $this + */ + public function setRescoreQuery($rescoreQuery) + { + $query = BaseQuery::create($rescoreQuery); + $data = $query->toArray(); + + $query = $this->getParam('query'); + $query['rescore_query'] = $data['query']; + + return $this->setParam('query', $query); + } + + /** + * Sets query_weight. + * + * @param float $weight + * + * @return $this + */ + public function setQueryWeight($weight) + { + $query = $this->getParam('query'); + $query['query_weight'] = $weight; + + return $this->setParam('query', $query); + } + + /** + * Sets rescore_query_weight. + * + * @param float $size + * + * @return $this + */ + public function setRescoreQueryWeight($weight) + { + $query = $this->getParam('query'); + $query['rescore_query_weight'] = $weight; + + return $this->setParam('query', $query); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Response.php b/vendor/ruflin/elastica/lib/Elastica/Response.php new file mode 100644 index 00000000..b537fe80 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Response.php @@ -0,0 +1,308 @@ +<?php +namespace Elastica; + +use Elastica\Exception\JSONParseException; +use Elastica\Exception\NotFoundException; + +/** + * Elastica Response object. + * + * Stores query time, and result array -> is given to result set, returned by ... + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Response +{ + /** + * Query time. + * + * @var float Query time + */ + protected $_queryTime = null; + + /** + * Response string (json). + * + * @var string Response + */ + protected $_responseString = ''; + + /** + * Error. + * + * @var bool Error + */ + protected $_error = false; + + /** + * Transfer info. + * + * @var array transfer info + */ + protected $_transferInfo = array(); + + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * HTTP response status code. + * + * @var int + */ + protected $_status = null; + + /** + * Construct. + * + * @param string|array $responseString Response string (json) + * @param int $responseStatus http status code + */ + public function __construct($responseString, $responseStatus = null) + { + if (is_array($responseString)) { + $this->_response = $responseString; + } else { + $this->_responseString = $responseString; + } + $this->_status = $responseStatus; + } + + /** + * Error message. + * + * @return string Error message + */ + public function getError() + { + $message = ''; + $response = $this->getData(); + + if (isset($response['error'])) { + $message = $response['error']; + } + + return $message; + } + + /** + * True if response has error. + * + * @return bool True if response has error + */ + public function hasError() + { + $response = $this->getData(); + + if (isset($response['error'])) { + return true; + } + + return false; + } + + /** + * True if response has failed shards. + * + * @return bool True if response has failed shards + */ + public function hasFailedShards() + { + try { + $shardsStatistics = $this->getShardsStatistics(); + } catch (NotFoundException $e) { + return false; + } + + return array_key_exists('failures', $shardsStatistics); + } + + /** + * Checks if the query returned ok. + * + * @return bool True if ok + */ + public function isOk() + { + $data = $this->getData(); + + // Bulk insert checks. Check every item + if (isset($data['status'])) { + if ($data['status'] >= 200 && $data['status'] <= 300) { + return true; + } + + return false; + } + + if (isset($data['items'])) { + if (isset($data['errors']) && true === $data['errors']) { + return false; + } + + foreach ($data['items'] as $item) { + if (isset($item['index']['ok']) && false == $item['index']['ok']) { + return false; + } elseif (isset($item['index']['status']) && ($item['index']['status'] < 200 || $item['index']['status'] >= 300)) { + return false; + } + } + + return true; + } + + if ($this->_status >= 200 && $this->_status <= 300) { + // http status is ok + return true; + } + + return (isset($data['ok']) && $data['ok']); + } + + /** + * @return int + */ + public function getStatus() + { + return $this->_status; + } + + /** + * Response data array. + * + * @return array Response data array + */ + public function getData() + { + if ($this->_response == null) { + $response = $this->_responseString; + if ($response === false) { + $this->_error = true; + } else { + try { + $response = JSON::parse($response); + } catch (JSONParseException $e) { + // leave reponse as is if parse fails + } + } + + if (empty($response)) { + $response = array(); + } + + if (is_string($response)) { + $response = array('message' => $response); + } + + $this->_response = $response; + } + + return $this->_response; + } + + /** + * Gets the transfer information. + * + * @return array Information about the curl request. + */ + public function getTransferInfo() + { + return $this->_transferInfo; + } + + /** + * Sets the transfer info of the curl request. This function is called + * from the \Elastica\Client::_callService . + * + * @param array $transferInfo The curl transfer information. + * + * @return $this + */ + public function setTransferInfo(array $transferInfo) + { + $this->_transferInfo = $transferInfo; + + return $this; + } + + /** + * Returns query execution time. + * + * @return float Query time + */ + public function getQueryTime() + { + return $this->_queryTime; + } + + /** + * Sets the query time. + * + * @param float $queryTime Query time + * + * @return $this + */ + public function setQueryTime($queryTime) + { + $this->_queryTime = $queryTime; + + return $this; + } + + /** + * Time request took. + * + * @throws \Elastica\Exception\NotFoundException + * + * @return int Time request took + */ + public function getEngineTime() + { + $data = $this->getData(); + + if (!isset($data['took'])) { + throw new NotFoundException('Unable to find the field [took]from the response'); + } + + return $data['took']; + } + + /** + * Get the _shard statistics for the response. + * + * @throws \Elastica\Exception\NotFoundException + * + * @return array + */ + public function getShardsStatistics() + { + $data = $this->getData(); + + if (!isset($data['_shards'])) { + throw new NotFoundException('Unable to find the field [_shards] from the response'); + } + + return $data['_shards']; + } + + /** + * Get the _scroll value for the response. + * + * @throws \Elastica\Exception\NotFoundException + * + * @return string + */ + public function getScrollId() + { + $data = $this->getData(); + + if (!isset($data['_scroll_id'])) { + throw new NotFoundException('Unable to find the field [_scroll_id] from the response'); + } + + return $data['_scroll_id']; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Result.php b/vendor/ruflin/elastica/lib/Elastica/Result.php new file mode 100644 index 00000000..6b3c68f2 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Result.php @@ -0,0 +1,217 @@ +<?php +namespace Elastica; + +/** + * Elastica result item. + * + * Stores all information from a result + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Result +{ + /** + * Hit array. + * + * @var array Hit array + */ + protected $_hit = array(); + + /** + * Constructs a single results object. + * + * @param array $hit Hit data + */ + public function __construct(array $hit) + { + $this->_hit = $hit; + } + + /** + * Returns a param from the result hit array. + * + * This function can be used to retrieve all data for which a specific + * function doesn't exist. + * If the param does not exist, an empty array is returned + * + * @param string $name Param name + * + * @return array Result data + */ + public function getParam($name) + { + if (isset($this->_hit[$name])) { + return $this->_hit[$name]; + } + + return array(); + } + + /** + * Test if a param from the result hit is set. + * + * @param string $name Param name to test + * + * @return bool True if the param is set, false otherwise + */ + public function hasParam($name) + { + return isset($this->_hit[$name]); + } + + /** + * Returns the hit id. + * + * @return string Hit id + */ + public function getId() + { + return $this->getParam('_id'); + } + + /** + * Returns the type of the result. + * + * @return string Result type + */ + public function getType() + { + return $this->getParam('_type'); + } + + /** + * Returns list of fields. + * + * @return array Fields list + */ + public function getFields() + { + return $this->getParam('fields'); + } + + /** + * Returns whether result has fields. + * + * @return bool + */ + public function hasFields() + { + return $this->hasParam('fields'); + } + + /** + * Returns the index name of the result. + * + * @return string Index name + */ + public function getIndex() + { + return $this->getParam('_index'); + } + + /** + * Returns the score of the result. + * + * @return float Result score + */ + public function getScore() + { + return $this->getParam('_score'); + } + + /** + * Returns the raw hit array. + * + * @return array Hit array + */ + public function getHit() + { + return $this->_hit; + } + + /** + * Returns the version information from the hit. + * + * @return string|int Document version + */ + public function getVersion() + { + return $this->getParam('_version'); + } + + /** + * Returns result data. + * + * Checks for partial result data with getFields, falls back to getSource + * + * @return array Result data array + */ + public function getData() + { + if (isset($this->_hit['fields']) && !isset($this->_hit['_source'])) { + return $this->getFields(); + } + + return $this->getSource(); + } + + /** + * Returns the result source. + * + * @return array Source data array + */ + public function getSource() + { + return $this->getParam('_source'); + } + + /** + * Returns result data. + * + * @return array Result data array + */ + public function getHighlights() + { + return $this->getParam('highlight'); + } + + /** + * Returns explanation on how its score was computed. + * + * @return array explanations + */ + public function getExplanation() + { + return $this->getParam('_explanation'); + } + + /** + * Magic function to directly access keys inside the result. + * + * Returns null if key does not exist + * + * @param string $key Key name + * + * @return mixed Key value + */ + public function __get($key) + { + $source = $this->getData(); + + return array_key_exists($key, $source) ? $source[$key] : null; + } + + /** + * Magic function to support isset() calls. + * + * @param string $key Key name + * + * @return bool + */ + public function __isset($key) + { + $source = $this->getData(); + + return array_key_exists($key, $source) && $source[$key] !== null; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/ResultSet.php b/vendor/ruflin/elastica/lib/Elastica/ResultSet.php new file mode 100644 index 00000000..ae4141b9 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/ResultSet.php @@ -0,0 +1,433 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; + +/** + * Elastica result set. + * + * List of all hits that are returned for a search on elasticsearch + * Result set implements iterator + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class ResultSet implements \Iterator, \Countable, \ArrayAccess +{ + /** + * Class for the static create method to use. + * + * @var string + */ + protected static $_class = 'Elastica\\ResultSet'; + + /** + * Results. + * + * @var array Results + */ + protected $_results = array(); + + /** + * Current position. + * + * @var int Current position + */ + protected $_position = 0; + + /** + * Response. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Query. + * + * @var \Elastica\Query Query object + */ + protected $_query; + + /** + * @var int + */ + protected $_took = 0; + + /** + * @var bool + */ + protected $_timedOut = false; + + /** + * @var int + */ + protected $_totalHits = 0; + + /** + * @var float + */ + protected $_maxScore = 0; + + /** + * Constructs ResultSet object. + * + * @param \Elastica\Response $response Response object + * @param \Elastica\Query $query Query object + */ + public function __construct(Response $response, Query $query) + { + $this->rewind(); + $this->_init($response); + $this->_query = $query; + } + + /** + * Creates a new ResultSet object. Can be configured to return a different + * implementation of the ResultSet class. + * + * @param Response $response + * @param Query $query + * + * @return ResultSet + */ + public static function create(Response $response, Query $query) + { + $class = static::$_class; + + return new $class($response, $query); + } + + /** + * Sets the class to be used for the static create method. + * + * @param string $class + */ + public static function setClass($class) + { + static::$_class = $class; + } + + /** + * Loads all data into the results object (initialisation). + * + * @param \Elastica\Response $response Response object + */ + protected function _init(Response $response) + { + $this->_response = $response; + $result = $response->getData(); + $this->_totalHits = isset($result['hits']['total']) ? $result['hits']['total'] : 0; + $this->_maxScore = isset($result['hits']['max_score']) ? $result['hits']['max_score'] : 0; + $this->_took = isset($result['took']) ? $result['took'] : 0; + $this->_timedOut = !empty($result['timed_out']); + if (isset($result['hits']['hits'])) { + foreach ($result['hits']['hits'] as $hit) { + $this->_results[] = new Result($hit); + } + } + } + + /** + * Returns all results. + * + * @return Result[] Results + */ + public function getResults() + { + return $this->_results; + } + + /** + * Returns true if the response contains suggestion results; false otherwise. + * + * @return bool + */ + public function hasSuggests() + { + $data = $this->_response->getData(); + + return isset($data['suggest']); + } + + /** + * Return all suggests. + * + * @return array suggest results + */ + public function getSuggests() + { + $data = $this->_response->getData(); + + return isset($data['suggest']) ? $data['suggest'] : array(); + } + + /** + * Returns whether facets exist. + * + * @return bool Facet existence + * + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ + public function hasFacets() + { + $data = $this->_response->getData(); + + return isset($data['facets']); + } + + /** + * Returns whether aggregations exist. + * + * @return bool Aggregation existence + */ + public function hasAggregations() + { + $data = $this->_response->getData(); + + return isset($data['aggregations']); + } + + /** + * Returns all aggregation results. + * + * @return array + */ + public function getAggregations() + { + $data = $this->_response->getData(); + + return isset($data['aggregations']) ? $data['aggregations'] : array(); + } + + /** + * Retrieve a specific aggregation from this result set. + * + * @param string $name the name of the desired aggregation + * + * @throws Exception\InvalidException if an aggregation by the given name cannot be found + * + * @return array + */ + public function getAggregation($name) + { + $data = $this->_response->getData(); + + if (isset($data['aggregations']) && isset($data['aggregations'][$name])) { + return $data['aggregations'][$name]; + } + throw new InvalidException("This result set does not contain an aggregation named {$name}."); + } + + /** + * Returns all facets results. + * + * @return array Facet results + * + * @deprecated Facets are deprecated and will be removed in a future release. You are encouraged to migrate to aggregations instead. + */ + public function getFacets() + { + $data = $this->_response->getData(); + + return isset($data['facets']) ? $data['facets'] : array(); + } + + /** + * Returns the total number of found hits. + * + * @return int Total hits + */ + public function getTotalHits() + { + return (int) $this->_totalHits; + } + + /** + * Returns the max score of the results found. + * + * @return float Max Score + */ + public function getMaxScore() + { + return (float) $this->_maxScore; + } + + /** + * Returns the total number of ms for this search to complete. + * + * @return int Total time + */ + public function getTotalTime() + { + return (int) $this->_took; + } + + /** + * Returns true iff the query has timed out. + * + * @return bool Timed out + */ + public function hasTimedOut() + { + return (bool) $this->_timedOut; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * @return \Elastica\Query + */ + public function getQuery() + { + return $this->_query; + } + + /** + * Returns size of current set. + * + * @return int Size of set + */ + public function count() + { + return sizeof($this->_results); + } + + /** + * Returns size of current suggests. + * + * @return int Size of suggests + */ + public function countSuggests() + { + return sizeof($this->getSuggests()); + } + + /** + * Returns the current object of the set. + * + * @return \Elastica\Result|bool Set object or false if not valid (no more entries) + */ + public function current() + { + if ($this->valid()) { + return $this->_results[$this->key()]; + } else { + return false; + } + } + + /** + * Sets pointer (current) to the next item of the set. + */ + public function next() + { + $this->_position++; + + return $this->current(); + } + + /** + * Returns the position of the current entry. + * + * @return int Current position + */ + public function key() + { + return $this->_position; + } + + /** + * Check if an object exists at the current position. + * + * @return bool True if object exists + */ + public function valid() + { + return isset($this->_results[$this->key()]); + } + + /** + * Resets position to 0, restarts iterator. + */ + public function rewind() + { + $this->_position = 0; + } + + /** + * Whether a offset exists. + * + * @link http://php.net/manual/en/arrayaccess.offsetexists.php + * + * @param int $offset + * + * @return bool true on success or false on failure. + */ + public function offsetExists($offset) + { + return isset($this->_results[$offset]); + } + + /** + * Offset to retrieve. + * + * @link http://php.net/manual/en/arrayaccess.offsetget.php + * + * @param int $offset + * + * @throws Exception\InvalidException If offset doesn't exist + * + * @return Result|null + */ + public function offsetGet($offset) + { + if ($this->offsetExists($offset)) { + return $this->_results[$offset]; + } else { + throw new InvalidException('Offset does not exist.'); + } + } + + /** + * Offset to set. + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php + * + * @param int $offset + * @param Result $value + * + * @throws Exception\InvalidException + */ + public function offsetSet($offset, $value) + { + if (!($value instanceof Result)) { + throw new InvalidException('ResultSet is a collection of Result only.'); + } + + if (!isset($this->_results[$offset])) { + throw new InvalidException('Offset does not exist.'); + } + + $this->_results[$offset] = $value; + } + + /** + * Offset to unset. + * + * @link http://php.net/manual/en/arrayaccess.offsetunset.php + * + * @param int $offset + */ + public function offsetUnset($offset) + { + unset($this->_results[$offset]); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/ScanAndScroll.php b/vendor/ruflin/elastica/lib/Elastica/ScanAndScroll.php new file mode 100644 index 00000000..6713856e --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/ScanAndScroll.php @@ -0,0 +1,80 @@ +<?php +namespace Elastica; + +/** + * Scan and Scroll Iterator. + * + * @author Manuel Andreo Garcia <andreo.garcia@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/guide/current/scan-scroll.html + */ +class ScanAndScroll extends Scroll +{ + /** + * @var int + */ + public $sizePerShard; + + /** + * Constructor. + * + * @param Search $search + * @param string $expiryTime + * @param int $sizePerShard + */ + public function __construct(Search $search, $expiryTime = '1m', $sizePerShard = 1000) + { + $this->sizePerShard = $sizePerShard; + + parent::__construct($search, $expiryTime); + } + + /** + * Initial scan search. + * + * @link http://php.net/manual/en/iterator.rewind.php + */ + public function rewind() + { + // reset state + $this->_nextScrollId = null; + $this->_options = array(null, null, null, null); + + $this->_saveOptions(); + + // initial scan request + $this->_search->getQuery()->setSize($this->sizePerShard); + $this->_search->setOption(Search::OPTION_SCROLL, $this->expiryTime); + $this->_search->setOption(Search::OPTION_SCROLL_ID, null); + $this->_search->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_SCAN); + $this->_setScrollId($this->_search->search()); + + $this->_revertOptions(); + + // first scroll request + $this->next(); + } + + /** + * Save all search options manipulated by Scroll. + */ + protected function _saveOptions() + { + $query = $this->_search->getQuery(); + if ($query->hasParam('size')) { + $this->_options[3] = $query->getParam('size'); + } + + parent::_saveOptions(); + } + + /** + * Revert search options to previously saved state. + */ + protected function _revertOptions() + { + $this->_search->getQuery()->setSize($this->_options[3]); + + parent::_revertOptions(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Script.php b/vendor/ruflin/elastica/lib/Elastica/Script.php new file mode 100644 index 00000000..6df3d583 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Script.php @@ -0,0 +1,163 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; + +/** + * Script objects, containing script internals. + * + * @author avasilenko <aa.vasilenko@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html + */ +class Script extends AbstractUpdateAction +{ + const LANG_MVEL = 'mvel'; + const LANG_JS = 'js'; + const LANG_GROOVY = 'groovy'; + const LANG_PYTHON = 'python'; + const LANG_NATIVE = 'native'; + + /** + * @var string + */ + private $_script; + + /** + * @var string + */ + private $_lang; + + /** + * @param string $script + * @param array|null $params + * @param string|null $lang + */ + public function __construct($script, array $params = null, $lang = null, $id = null) + { + $this->setScript($script); + + if ($params) { + $this->setParams($params); + } + + if ($lang) { + $this->setLang($lang); + } + + if ($id) { + $this->setId($id); + } + } + + /** + * @param string $lang + * + * @return $this + */ + public function setLang($lang) + { + $this->_lang = $lang; + + return $this; + } + + /** + * @return string + */ + public function getLang() + { + return $this->_lang; + } + + /** + * @param string $script + * + * @return $this + */ + public function setScript($script) + { + $this->_script = $script; + + return $this; + } + + /** + * @return string + */ + public function getScript() + { + return $this->_script; + } + + /** + * @param string|array|\Elastica\Script $data + * + * @throws \Elastica\Exception\InvalidException + * + * @return self + */ + public static function create($data) + { + if ($data instanceof self) { + $script = $data; + } elseif (is_array($data)) { + $script = self::_createFromArray($data); + } elseif (is_string($data)) { + $script = new self($data); + } else { + throw new InvalidException('Failed to create script. Invalid data passed.'); + } + + return $script; + } + + /** + * @param array $data + * + * @throws \Elastica\Exception\InvalidException + * + * @return self + */ + protected static function _createFromArray(array $data) + { + if (!isset($data['script'])) { + throw new InvalidException("\$data['script'] is required"); + } + + $script = new self($data['script']); + + if (isset($data['lang'])) { + $script->setLang($data['lang']); + } + + if (isset($data['params'])) { + if (!is_array($data['params'])) { + throw new InvalidException("\$data['params'] should be array"); + } + $script->setParams($data['params']); + } + + return $script; + } + + /** + * @return array + */ + public function toArray() + { + $array = array( + 'script' => $this->_script, + ); + + if (!empty($this->_params)) { + $array['params'] = $this->_params; + } + + if ($this->_lang) { + $array['lang'] = $this->_lang; + } + + return $array; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/ScriptFields.php b/vendor/ruflin/elastica/lib/Elastica/ScriptFields.php new file mode 100644 index 00000000..41b5b913 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/ScriptFields.php @@ -0,0 +1,65 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; + +/** + * Container for scripts as fields. + * + * @author Sebastien Lavoie <github@lavoie.sl> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html + */ +class ScriptFields extends Param +{ + /** + * @param \Elastica\Script[]|array $scripts OPTIONAL + */ + public function __construct(array $scripts = array()) + { + if ($scripts) { + $this->setScripts($scripts); + } + } + + /** + * @param string $name Name of the Script field + * @param \Elastica\Script $script + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addScript($name, Script $script) + { + if (!is_string($name) || !strlen($name)) { + throw new InvalidException('The name of a Script is required and must be a string'); + } + $this->setParam($name, $script->toArray()); + + return $this; + } + + /** + * @param \Elastica\Script[]|array $scripts Associative array of string => Elastica\Script + * + * @return $this + */ + public function setScripts(array $scripts) + { + $this->_params = array(); + foreach ($scripts as $name => $script) { + $this->addScript($name, $script); + } + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + return $this->_params; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Scroll.php b/vendor/ruflin/elastica/lib/Elastica/Scroll.php new file mode 100644 index 00000000..44fa73e9 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Scroll.php @@ -0,0 +1,174 @@ +<?php +namespace Elastica; + +/** + * Scroll Iterator. + * + * @author Manuel Andreo Garcia <andreo.garcia@gmail.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html + */ +class Scroll implements \Iterator +{ + /** + * @var string + */ + public $expiryTime; + + /** + * @var Search + */ + protected $_search; + + /** + * @var null|string + */ + protected $_nextScrollId = null; + + /** + * @var null|ResultSet + */ + protected $_currentResultSet = null; + + /** + * 0: scroll<br> + * 1: scroll id<br> + * 2: search type. + * + * @var array + */ + protected $_options = array(null, null, null); + + /** + * Constructor. + * + * @param Search $search + * @param string $expiryTime + */ + public function __construct(Search $search, $expiryTime = '1m') + { + $this->_search = $search; + $this->expiryTime = $expiryTime; + } + + /** + * Returns current result set. + * + * @link http://php.net/manual/en/iterator.current.php + * + * @return ResultSet + */ + public function current() + { + return $this->_currentResultSet; + } + + /** + * Next scroll search. + * + * @link http://php.net/manual/en/iterator.next.php + */ + public function next() + { + $this->_saveOptions(); + + $this->_search->setOption(Search::OPTION_SCROLL, $this->expiryTime); + $this->_search->setOption(Search::OPTION_SCROLL_ID, $this->_nextScrollId); + $this->_search->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_SCROLL); + $this->_setScrollId($this->_search->search()); + + $this->_revertOptions(); + } + + /** + * Returns scroll id. + * + * @link http://php.net/manual/en/iterator.key.php + * + * @return string + */ + public function key() + { + return $this->_nextScrollId; + } + + /** + * Returns true if current result set contains at least one hit. + * + * @link http://php.net/manual/en/iterator.valid.php + * + * @return bool + */ + public function valid() + { + return + $this->_nextScrollId !== null + && $this->_currentResultSet !== null + && $this->_currentResultSet->count() > 0; + } + + /** + * Initial scroll search. + * + * @link http://php.net/manual/en/iterator.rewind.php + */ + public function rewind() + { + // reset state + $this->_nextScrollId = null; + $this->_options = array(null, null, null); + + // initial search + $this->_saveOptions(); + + $this->_search->setOption(Search::OPTION_SCROLL, $this->expiryTime); + $this->_search->setOption(Search::OPTION_SCROLL_ID, null); + $this->_search->setOption(Search::OPTION_SEARCH_TYPE, null); + $this->_setScrollId($this->_search->search()); + + $this->_revertOptions(); + } + + /** + * Prepares Scroll for next request. + * + * @param ResultSet $resultSet + */ + protected function _setScrollId(ResultSet $resultSet) + { + $this->_currentResultSet = $resultSet; + + $this->_nextScrollId = null; + if ($resultSet->getResponse()->isOk()) { + $this->_nextScrollId = $resultSet->getResponse()->getScrollId(); + } + } + + /** + * Save all search options manipulated by Scroll. + */ + protected function _saveOptions() + { + if ($this->_search->hasOption(Search::OPTION_SCROLL)) { + $this->_options[0] = $this->_search->getOption(Search::OPTION_SCROLL); + } + + if ($this->_search->hasOption(Search::OPTION_SCROLL_ID)) { + $this->_options[1] = $this->_search->getOption(Search::OPTION_SCROLL_ID); + } + + if ($this->_search->hasOption(Search::OPTION_SEARCH_TYPE)) { + $this->_options[2] = $this->_search->getOption(Search::OPTION_SEARCH_TYPE); + } + } + + /** + * Revert search options to previously saved state. + */ + protected function _revertOptions() + { + $this->_search->setOption(Search::OPTION_SCROLL, $this->_options[0]); + $this->_search->setOption(Search::OPTION_SCROLL_ID, $this->_options[1]); + $this->_search->setOption(Search::OPTION_SEARCH_TYPE, $this->_options[2]); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Search.php b/vendor/ruflin/elastica/lib/Elastica/Search.php new file mode 100644 index 00000000..7306eb75 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Search.php @@ -0,0 +1,553 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; + +/** + * Elastica search object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Search +{ + /* + * Options + */ + const OPTION_SEARCH_TYPE = 'search_type'; + const OPTION_ROUTING = 'routing'; + const OPTION_PREFERENCE = 'preference'; + const OPTION_VERSION = 'version'; + const OPTION_TIMEOUT = 'timeout'; + const OPTION_FROM = 'from'; + const OPTION_SIZE = 'size'; + const OPTION_SCROLL = 'scroll'; + const OPTION_SCROLL_ID = 'scroll_id'; + const OPTION_QUERY_CACHE = 'query_cache'; + + /* + * Search types + */ + const OPTION_SEARCH_TYPE_COUNT = 'count'; + const OPTION_SEARCH_TYPE_SCAN = 'scan'; + const OPTION_SEARCH_TYPE_DFS_QUERY_THEN_FETCH = 'dfs_query_then_fetch'; + const OPTION_SEARCH_TYPE_DFS_QUERY_AND_FETCH = 'dfs_query_and_fetch'; + const OPTION_SEARCH_TYPE_QUERY_THEN_FETCH = 'query_then_fetch'; + const OPTION_SEARCH_TYPE_QUERY_AND_FETCH = 'query_and_fetch'; + const OPTION_SEARCH_TYPE_SUGGEST = 'suggest'; + const OPTION_SEARCH_TYPE_SCROLL = 'scroll'; + const OPTION_SEARCH_IGNORE_UNAVAILABLE = 'ignore_unavailable'; + + /** + * Array of indices. + * + * @var array + */ + protected $_indices = array(); + + /** + * Array of types. + * + * @var array + */ + protected $_types = array(); + + /** + * @var \Elastica\Query + */ + protected $_query; + + /** + * @var array + */ + protected $_options = array(); + + /** + * Client object. + * + * @var \Elastica\Client + */ + protected $_client; + + /** + * Constructs search object. + * + * @param \Elastica\Client $client Client object + */ + public function __construct(Client $client) + { + $this->_client = $client; + } + + /** + * Adds a index to the list. + * + * @param \Elastica\Index|string $index Index object or string + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addIndex($index) + { + if ($index instanceof Index) { + $index = $index->getName(); + } + + if (!is_scalar($index)) { + throw new InvalidException('Invalid param type'); + } + + $this->_indices[] = (string) $index; + + return $this; + } + + /** + * Add array of indices at once. + * + * @param array $indices + * + * @return $this + */ + public function addIndices(array $indices = array()) + { + foreach ($indices as $index) { + $this->addIndex($index); + } + + return $this; + } + + /** + * Adds a type to the current search. + * + * @param \Elastica\Type|string $type Type name or object + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addType($type) + { + if ($type instanceof Type) { + $type = $type->getName(); + } + + if (!is_string($type)) { + throw new InvalidException('Invalid type type'); + } + + $this->_types[] = $type; + + return $this; + } + + /** + * Add array of types. + * + * @param array $types + * + * @return $this + */ + public function addTypes(array $types = array()) + { + foreach ($types as $type) { + $this->addType($type); + } + + return $this; + } + + /** + * @param string|array|\Elastica\Query|\Elastica\Suggest|\Elastica\Query\AbstractQuery|\Elastica\Filter\AbstractFilter $query| + * + * @return $this + */ + public function setQuery($query) + { + $this->_query = Query::create($query); + + return $this; + } + + /** + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function setOption($key, $value) + { + $this->_validateOption($key); + + $this->_options[$key] = $value; + + return $this; + } + + /** + * @param array $options + * + * @return $this + */ + public function setOptions(array $options) + { + $this->clearOptions(); + + foreach ($options as $key => $value) { + $this->setOption($key, $value); + } + + return $this; + } + + /** + * @return $this + */ + public function clearOptions() + { + $this->_options = array(); + + return $this; + } + + /** + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function addOption($key, $value) + { + $this->_validateOption($key); + + if (!isset($this->_options[$key])) { + $this->_options[$key] = array(); + } + + $this->_options[$key][] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return bool + */ + public function hasOption($key) + { + return isset($this->_options[$key]); + } + + /** + * @param string $key + * + * @throws \Elastica\Exception\InvalidException + * + * @return mixed + */ + public function getOption($key) + { + if (!$this->hasOption($key)) { + throw new InvalidException('Option '.$key.' does not exist'); + } + + return $this->_options[$key]; + } + + /** + * @return array + */ + public function getOptions() + { + return $this->_options; + } + + /** + * @param string $key + * + * @throws \Elastica\Exception\InvalidException + * + * @return bool + */ + protected function _validateOption($key) + { + switch ($key) { + case self::OPTION_SEARCH_TYPE: + case self::OPTION_ROUTING: + case self::OPTION_PREFERENCE: + case self::OPTION_VERSION: + case self::OPTION_TIMEOUT: + case self::OPTION_FROM: + case self::OPTION_SIZE: + case self::OPTION_SCROLL: + case self::OPTION_SCROLL_ID: + case self::OPTION_SEARCH_TYPE_SUGGEST: + case self::OPTION_SEARCH_IGNORE_UNAVAILABLE: + case self::OPTION_QUERY_CACHE: + return true; + } + + throw new InvalidException('Invalid option '.$key); + } + + /** + * Return client object. + * + * @return \Elastica\Client Client object + */ + public function getClient() + { + return $this->_client; + } + + /** + * Return array of indices. + * + * @return array List of index names + */ + public function getIndices() + { + return $this->_indices; + } + + /** + * @return bool + */ + public function hasIndices() + { + return count($this->_indices) > 0; + } + + /** + * @param Index|string $index + * + * @return bool + */ + public function hasIndex($index) + { + if ($index instanceof Index) { + $index = $index->getName(); + } + + return in_array($index, $this->_indices); + } + + /** + * Return array of types. + * + * @return array List of types + */ + public function getTypes() + { + return $this->_types; + } + + /** + * @return bool + */ + public function hasTypes() + { + return count($this->_types) > 0; + } + + /** + * @param \Elastica\Type|string $type + * + * @return bool + */ + public function hasType($type) + { + if ($type instanceof Type) { + $type = $type->getName(); + } + + return in_array($type, $this->_types); + } + + /** + * @return \Elastica\Query + */ + public function getQuery() + { + if (null === $this->_query) { + $this->_query = Query::create(''); + } + + return $this->_query; + } + + /** + * Creates new search object. + * + * @param \Elastica\SearchableInterface $searchObject + * + * @return Search + */ + public static function create(SearchableInterface $searchObject) + { + return $searchObject->createSearch(); + } + + /** + * Combines indices and types to the search request path. + * + * @return string Search path + */ + public function getPath() + { + if (isset($this->_options[self::OPTION_SCROLL_ID])) { + return '_search/scroll'; + } + + $indices = $this->getIndices(); + + $path = ''; + $types = $this->getTypes(); + + if (empty($indices)) { + if (!empty($types)) { + $path .= '_all'; + } + } else { + $path .= implode(',', $indices); + } + + if (!empty($types)) { + $path .= '/'.implode(',', $types); + } + + // Add full path based on indices and types -> could be all + return $path.'/_search'; + } + + /** + * Search in the set indices, types. + * + * @param mixed $query + * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\ResultSet + */ + public function search($query = '', $options = null) + { + $this->setOptionsAndQuery($options, $query); + + $query = $this->getQuery(); + $path = $this->getPath(); + + $params = $this->getOptions(); + + // Send scroll_id via raw HTTP body to handle cases of very large (> 4kb) ids. + if ('_search/scroll' == $path) { + $data = $params[self::OPTION_SCROLL_ID]; + unset($params[self::OPTION_SCROLL_ID]); + } else { + $data = $query->toArray(); + } + + $response = $this->getClient()->request( + $path, + Request::GET, + $data, + $params + ); + + return ResultSet::create($response, $query); + } + + /** + * @param mixed $query + * @param $fullResult (default = false) By default only the total hit count is returned. If set to true, the full ResultSet including aggregations is returned. + * + * @return int|ResultSet + */ + public function count($query = '', $fullResult = false) + { + $this->setOptionsAndQuery(null, $query); + + $query = $this->getQuery(); + $path = $this->getPath(); + + $response = $this->getClient()->request( + $path, + Request::GET, + $query->toArray(), + array(self::OPTION_SEARCH_TYPE => self::OPTION_SEARCH_TYPE_COUNT) + ); + $resultSet = ResultSet::create($response, $query); + + return $fullResult ? $resultSet : $resultSet->getTotalHits(); + } + + /** + * @param array|int $options + * @param string|array|\Elastica\Query $query + * + * @return $this + */ + public function setOptionsAndQuery($options = null, $query = '') + { + if ('' != $query) { + $this->setQuery($query); + } + + if (is_int($options)) { + $this->getQuery()->setSize($options); + } elseif (is_array($options)) { + if (isset($options['limit'])) { + $this->getQuery()->setSize($options['limit']); + unset($options['limit']); + } + if (isset($options['explain'])) { + $this->getQuery()->setExplain($options['explain']); + unset($options['explain']); + } + $this->setOptions($options); + } + + return $this; + } + + /** + * @param Suggest $suggest + * + * @return $this + */ + public function setSuggest(Suggest $suggest) + { + return $this->setOptionsAndQuery(array(self::OPTION_SEARCH_TYPE_SUGGEST => 'suggest'), $suggest); + } + + /** + * Returns the Scroll Iterator. + * + * @see Elastica\Scroll + * + * @param string $expiryTime + * + * @return Scroll + */ + public function scroll($expiryTime = '1m') + { + return new Scroll($this, $expiryTime); + } + + /** + * Returns the ScanAndScroll Iterator. + * + * @see Elastica\ScanAndScroll + * + * @param string $expiryTime + * @param int $sizePerShard + * + * @return ScanAndScroll + */ + public function scanAndScroll($expiryTime = '1m', $sizePerShard = 1000) + { + return new ScanAndScroll($this, $expiryTime, $sizePerShard); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/SearchableInterface.php b/vendor/ruflin/elastica/lib/Elastica/SearchableInterface.php new file mode 100644 index 00000000..abfacb85 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/SearchableInterface.php @@ -0,0 +1,52 @@ +<?php +namespace Elastica; + +/** + * Elastica searchable interface. + * + * @author Thibault Duplessis <thibault.duplessis@gmail.com> + */ +interface SearchableInterface +{ + /** + * Searches results for a query. + * + * TODO: Improve sample code + * { + * "from" : 0, + * "size" : 10, + * "sort" : { + * "postDate" : {"reverse" : true}, + * "user" : { }, + * "_score" : { } + * }, + * "query" : { + * "term" : { "user" : "kimchy" } + * } + * } + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * + * @return \Elastica\ResultSet ResultSet with all results inside + */ + public function search($query = '', $options = null); + + /** + * Counts results for a query. + * + * If no query is set, matchall query is created + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * + * @return int number of documents matching the query + */ + public function count($query = ''); + + /** + * @param \Elastica\Query $query + * @param array $options + * + * @return \Elastica\Search + */ + public function createSearch($query = '', $options = null); +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Snapshot.php b/vendor/ruflin/elastica/lib/Elastica/Snapshot.php new file mode 100644 index 00000000..80924b79 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Snapshot.php @@ -0,0 +1,176 @@ +<?php +namespace Elastica; + +use Elastica\Exception\NotFoundException; +use Elastica\Exception\ResponseException; + +/** + * Class Snapshot. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html + */ +class Snapshot +{ + /** + * @var Client + */ + protected $_client; + + /** + * @param Client $client + */ + public function __construct(Client $client) + { + $this->_client = $client; + } + + /** + * Register a snapshot repository. + * + * @param string $name the name of the repository + * @param string $type the repository type ("fs" for file system) + * @param array $settings Additional repository settings. If type "fs" is used, the "location" setting must be provided. + * + * @return Response + */ + public function registerRepository($name, $type, $settings = array()) + { + $data = array( + 'type' => $type, + 'settings' => $settings, + ); + + return $this->request($name, Request::PUT, $data); + } + + /** + * Retrieve a repository record by name. + * + * @param string $name the name of the desired repository + * + * @throws Exception\ResponseException + * @throws Exception\NotFoundException + * + * @return array + */ + public function getRepository($name) + { + try { + $response = $this->request($name); + } catch (ResponseException $e) { + if ($e->getResponse()->getStatus() == 404) { + throw new NotFoundException("Repository '".$name."' does not exist."); + } + throw $e; + } + $data = $response->getData(); + + return $data[$name]; + } + + /** + * Retrieve all repository records. + * + * @return array + */ + public function getAllRepositories() + { + return $this->request('_all')->getData(); + } + + /** + * Create a new snapshot. + * + * @param string $repository the name of the repository in which this snapshot should be stored + * @param string $name the name of this snapshot + * @param array $options optional settings for this snapshot + * @param bool $waitForCompletion if true, the request will not return until the snapshot operation is complete + * + * @return Response + */ + public function createSnapshot($repository, $name, $options = array(), $waitForCompletion = false) + { + return $this->request($repository.'/'.$name, Request::PUT, $options, array('wait_for_completion' => $waitForCompletion)); + } + + /** + * Retrieve data regarding a specific snapshot. + * + * @param string $repository the name of the repository from which to retrieve the snapshot + * @param string $name the name of the desired snapshot + * + * @throws Exception\ResponseException + * @throws Exception\NotFoundException + * + * @return array + */ + public function getSnapshot($repository, $name) + { + try { + $response = $this->request($repository.'/'.$name); + } catch (ResponseException $e) { + if ($e->getResponse()->getStatus() == 404) { + throw new NotFoundException("Snapshot '".$name."' does not exist in repository '".$repository."'."); + } + throw $e; + } + $data = $response->getData(); + + return $data['snapshots'][0]; + } + + /** + * Retrieve data regarding all snapshots in the given repository. + * + * @param string $repository the repository name + * + * @return array + */ + public function getAllSnapshots($repository) + { + return $this->request($repository.'/_all')->getData(); + } + + /** + * Delete a snapshot. + * + * @param string $repository the repository in which the snapshot resides + * @param string $name the name of the snapshot to be deleted + * + * @return Response + */ + public function deleteSnapshot($repository, $name) + { + return $this->request($repository.'/'.$name, Request::DELETE); + } + + /** + * Restore a snapshot. + * + * @param string $repository the name of the repository + * @param string $name the name of the snapshot + * @param array $options options for the restore operation + * @param bool $waitForCompletion if true, the request will not return until the restore operation is complete + * + * @return Response + */ + public function restoreSnapshot($repository, $name, $options = array(), $waitForCompletion = false) + { + return $this->request($repository.'/'.$name.'/_restore', Request::POST, $options, array('wait_for_completion' => $waitForCompletion)); + } + + /** + * Perform a snapshot request. + * + * @param string $path the URL + * @param string $method the HTTP method + * @param array $data request body data + * @param array $query query string parameters + * + * @return Response + */ + public function request($path, $method = Request::GET, $data = array(), array $query = array()) + { + return $this->_client->request('/_snapshot/'.$path, $method, $data, $query); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Status.php b/vendor/ruflin/elastica/lib/Elastica/Status.php new file mode 100644 index 00000000..c22a5f61 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Status.php @@ -0,0 +1,177 @@ +<?php +namespace Elastica; + +use Elastica\Exception\ResponseException; +use Elastica\Index\Status as IndexStatus; + +/** + * Elastica general status. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-status.html + */ +class Status +{ + /** + * Contains all status infos. + * + * @var \Elastica\Response Response object + */ + protected $_response = null; + + /** + * Data. + * + * @var array Data + */ + protected $_data = array(); + + /** + * Client object. + * + * @var \Elastica\Client Client object + */ + protected $_client = null; + + /** + * Constructs Status object. + * + * @param \Elastica\Client $client Client object + */ + public function __construct(Client $client) + { + $this->_client = $client; + $this->refresh(); + } + + /** + * Returns status data. + * + * @return array Status data + */ + public function getData() + { + return $this->_data; + } + + /** + * Returns status objects of all indices. + * + * @return array|\Elastica\Index\Status[] List of Elastica\Client\Index objects + */ + public function getIndexStatuses() + { + $statuses = array(); + foreach ($this->getIndexNames() as $name) { + $index = new Index($this->_client, $name); + $statuses[] = new IndexStatus($index); + } + + return $statuses; + } + + /** + * Returns a list of the existing index names. + * + * @return array Index names list + */ + public function getIndexNames() + { + return array_keys($this->_data['indices']); + } + + /** + * Checks if the given index exists. + * + * @param string $name Index name to check + * + * @return bool True if index exists + */ + public function indexExists($name) + { + return in_array($name, $this->getIndexNames()); + } + + /** + * Checks if the given alias exists. + * + * @param string $name Alias name + * + * @return bool True if alias exists + */ + public function aliasExists($name) + { + return count($this->getIndicesWithAlias($name)) > 0; + } + + /** + * Returns an array with all indices that the given alias name points to. + * + * @param string $alias Alias name + * + * @return array|\Elastica\Index[] List of Elastica\Index + */ + public function getIndicesWithAlias($alias) + { + $response = null; + try { + $response = $this->_client->request('/_alias/'.$alias); + } catch (ResponseException $e) { + $transferInfo = $e->getResponse()->getTransferInfo(); + // 404 means the index alias doesn't exist which means no indexes have it. + if ($transferInfo['http_code'] === 404) { + return array(); + } + // If we don't have a 404 then this is still unexpected so rethrow the exception. + throw $e; + } + $indices = array(); + foreach ($response->getData() as $name => $unused) { + $indices[] = new Index($this->_client, $name); + } + + return $indices; + } + + /** + * Returns response object. + * + * @return \Elastica\Response Response object + */ + public function getResponse() + { + return $this->_response; + } + + /** + * Return shards info. + * + * @return array Shards info + */ + public function getShards() + { + return $this->_data['shards']; + } + + /** + * Refresh status object. + */ + public function refresh() + { + $path = '_status'; + $this->_response = $this->_client->request($path, Request::GET); + $this->_data = $this->getResponse()->getData(); + } + + /** + * Refresh serverStatus object. + */ + public function getServerStatus() + { + $path = ''; + $response = $this->_client->request($path, Request::GET); + + return $response->getData(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Suggest.php b/vendor/ruflin/elastica/lib/Elastica/Suggest.php new file mode 100644 index 00000000..73b1ea36 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Suggest.php @@ -0,0 +1,65 @@ +<?php +namespace Elastica; + +use Elastica\Exception\NotImplementedException; +use Elastica\Suggest\AbstractSuggest; + +/** + * Class Suggest. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html + */ +class Suggest extends Param +{ + /** + * @param AbstractSuggest $suggestion + */ + public function __construct(AbstractSuggest $suggestion = null) + { + if (!is_null($suggestion)) { + $this->addSuggestion($suggestion); + } + } + + /** + * Set the global text for this suggester. + * + * @param string $text + * + * @return $this + */ + public function setGlobalText($text) + { + return $this->setParam('text', $text); + } + + /** + * Add a suggestion to this suggest clause. + * + * @param AbstractSuggest $suggestion + * + * @return $this + */ + public function addSuggestion(AbstractSuggest $suggestion) + { + return $this->setParam($suggestion->getName(), $suggestion->toArray()); + } + + /** + * @param Suggest|AbstractSuggest $suggestion + * + * @throws Exception\NotImplementedException + * + * @return self + */ + public static function create($suggestion) + { + switch (true) { + case $suggestion instanceof self: + return $suggestion; + case $suggestion instanceof AbstractSuggest: + return new self($suggestion); + } + throw new NotImplementedException(); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Suggest/AbstractSuggest.php b/vendor/ruflin/elastica/lib/Elastica/Suggest/AbstractSuggest.php new file mode 100644 index 00000000..00f21e44 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Suggest/AbstractSuggest.php @@ -0,0 +1,97 @@ +<?php +namespace Elastica\Suggest; + +use Elastica\Param; + +/** + * Class AbstractSuggestion. + */ +abstract class AbstractSuggest extends Param +{ + /** + * @var string the name of this suggestion + */ + protected $_name; + + /** + * @var string the text for this suggestion + */ + protected $_text; + + /** + * @param string $name + * @param string $field + */ + public function __construct($name, $field) + { + $this->_name = $name; + $this->setField($field); + } + + /** + * Suggest text must be set either globally or per suggestion. + * + * @param string $text + * + * @return $this + */ + public function setText($text) + { + $this->_text = $text; + + return $this; + } + + /** + * @param string $field + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * @param int $size + * + * @return $this + */ + public function setSize($size) + { + return $this->setParam('size', $size); + } + + /** + * @param int $size maximum number of suggestions to be retrieved from each shard + * + * @return $this + */ + public function setShardSize($size) + { + return $this->setParam('shard_size', $size); + } + + /** + * Retrieve the name of this suggestion. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * @return array + */ + public function toArray() + { + $array = parent::toArray(); + if (isset($this->_text)) { + $array['text'] = $this->_text; + } + + return $array; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/AbstractCandidateGenerator.php b/vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/AbstractCandidateGenerator.php new file mode 100644 index 00000000..6fba49db --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/AbstractCandidateGenerator.php @@ -0,0 +1,8 @@ +<?php +namespace Elastica\Suggest\CandidateGenerator; + +use Elastica\Param; + +class AbstractCandidateGenerator extends Param +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/DirectGenerator.php b/vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/DirectGenerator.php new file mode 100644 index 00000000..54ac7649 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/DirectGenerator.php @@ -0,0 +1,140 @@ +<?php +namespace Elastica\Suggest\CandidateGenerator; + +/** + * Class DirectGenerator. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-phrase.html#_direct_generators + */ +class DirectGenerator extends AbstractCandidateGenerator +{ + const SUGGEST_MODE_MISSING = 'missing'; + const SUGGEST_MODE_POPULAR = 'popular'; + const SUGGEST_MODE_ALWAYS = 'always'; + + /** + * @param string $field + */ + public function __construct($field) + { + $this->setField($field); + } + + /** + * Set the field name from which to fetch candidate suggestions. + * + * @param string $field + * + * @return $this + */ + public function setField($field) + { + return $this->setParam('field', $field); + } + + /** + * Set the maximum corrections to be returned per suggest text token. + * + * @param int $size + * + * @return $this + */ + public function setSize($size) + { + return $this->setParam('size', $size); + } + + /** + * @param string $mode see SUGGEST_MODE_* constants for options + * + * @return $this + */ + public function setSuggestMode($mode) + { + return $this->setParam('suggest_mode', $mode); + } + + /** + * @param int $max can only be a value between 1 and 2. Defaults to 2. + * + * @return $this + */ + public function setMaxEdits($max) + { + return $this->setParam('max_edits', $max); + } + + /** + * @param int $length defaults to 1 + * + * @return $this + */ + public function setPrefixLength($length) + { + return $this->setParam('prefix_len', $length); + } + + /** + * @param int $min defaults to 4 + * + * @return $this + */ + public function setMinWordLength($min) + { + return $this->setParam('min_word_len', $min); + } + + /** + * @param int $max + * + * @return $this + */ + public function setMaxInspections($max) + { + return $this->setParam('max_inspections', $max); + } + + /** + * @param float $min + * + * @return $this + */ + public function setMinDocFrequency($min) + { + return $this->setParam('min_doc_freq', $min); + } + + /** + * @param float $max + * + * @return $this + */ + public function setMaxTermFrequency($max) + { + return $this->setParam('max_term_freq', $max); + } + + /** + * Set an analyzer to be applied to the original token prior to candidate generation. + * + * @param string $pre an analyzer + * + * @return $this + */ + public function setPreFilter($pre) + { + return $this->setParam('pre_filter', $pre); + } + + /** + * Set an analyzer to be applied to generated tokens before they are passed to the phrase scorer. + * + * @param string $post + * + * @return $this + */ + public function setPostFilter($post) + { + return $this->setParam('post_filter', $post); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Suggest/Completion.php b/vendor/ruflin/elastica/lib/Elastica/Suggest/Completion.php new file mode 100644 index 00000000..0f0b3e61 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Suggest/Completion.php @@ -0,0 +1,26 @@ +<?php +namespace Elastica\Suggest; + +/** + * Comletion suggester. + * + * @author Igor Denisenko <im.denisenko@yahoo.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html + */ +class Completion extends AbstractSuggest +{ + /** + * Set fuzzy parameter. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html#fuzzy + * + * @param array $fuzzy + * + * @return $this + */ + public function setFuzzy(array $fuzzy) + { + return $this->setParam('fuzzy', $fuzzy); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Suggest/Phrase.php b/vendor/ruflin/elastica/lib/Elastica/Suggest/Phrase.php new file mode 100644 index 00000000..544f3678 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Suggest/Phrase.php @@ -0,0 +1,164 @@ +<?php +namespace Elastica\Suggest; + +use Elastica\Suggest\CandidateGenerator\AbstractCandidateGenerator; + +/** + * Class Phrase. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-phrase.html + */ +class Phrase extends AbstractSuggest +{ + /** + * @param string $analyzer + * + * @return $this + */ + public function setAnalyzer($analyzer) + { + return $this->setParam('analyzer', $analyzer); + } + + /** + * Set the max size of the n-grams (shingles) in the field. + * + * @param int $size + * + * @return $this + */ + public function setGramSize($size) + { + return $this->setParam('gram_size', $size); + } + + /** + * Set the likelihood of a term being misspelled even if the term exists in the dictionary. + * + * @param float $likelihood Defaults to 0.95, meaning 5% of the words are misspelled. + * + * @return $this + */ + public function setRealWordErrorLikelihood($likelihood) + { + return $this->setParam('real_word_error_likelihood', $likelihood); + } + + /** + * Set the factor applied to the input phrases score to be used as a threshold for other suggestion candidates. + * Only candidates which score higher than this threshold will be included in the result. + * + * @param float $confidence Defaults to 1.0. + * + * @return $this + */ + public function setConfidence($confidence) + { + return $this->setParam('confidence', $confidence); + } + + /** + * Set the maximum percentage of the terms considered to be misspellings in order to form a correction. + * + * @param float $max + * + * @return $this + */ + public function setMaxErrors($max) + { + return $this->setParam('max_errors', $max); + } + + /** + * @param string $separator + * + * @return $this + */ + public function setSeparator($separator) + { + return $this->setParam('separator', $separator); + } + + /** + * Set suggestion highlighting. + * + * @param string $preTag + * @param string $postTag + * + * @return $this + */ + public function setHighlight($preTag, $postTag) + { + return $this->setParam('highlight', array( + 'pre_tag' => $preTag, + 'post_tag' => $postTag, + )); + } + + /** + * @param float $discount + * + * @return $this + */ + public function setStupidBackoffSmoothing($discount = 0.4) + { + return $this->setSmoothingModel('stupid_backoff', array( + 'discount' => $discount, + )); + } + + /** + * @param float $alpha + * + * @return $this + */ + public function setLaplaceSmoothing($alpha = 0.5) + { + return $this->setSmoothingModel('laplace', array( + 'alpha' => $alpha, + )); + } + + /** + * @param float $trigramLambda + * @param float $bigramLambda + * @param float $unigramLambda + * + * @return $this + */ + public function setLinearInterpolationSmoothing($trigramLambda, $bigramLambda, $unigramLambda) + { + return $this->setSmoothingModel('linear_interpolation', array( + 'trigram_lambda' => $trigramLambda, + 'bigram_lambda' => $bigramLambda, + 'unigram_lambda' => $unigramLambda, + )); + } + + /** + * @param string $model the name of the smoothing model + * @param array $params + * + * @return $this + */ + public function setSmoothingModel($model, array $params) + { + return $this->setParam('smoothing', array( + $model => $params, + )); + } + + /** + * @param AbstractCandidateGenerator $generator + * + * @return $this + */ + public function addCandidateGenerator(AbstractCandidateGenerator $generator) + { + $generator = $generator->toArray(); + $keys = array_keys($generator); + $values = array_values($generator); + + return $this->addParam($keys[0], $values[0]); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Suggest/Term.php b/vendor/ruflin/elastica/lib/Elastica/Suggest/Term.php new file mode 100644 index 00000000..9f082873 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Suggest/Term.php @@ -0,0 +1,129 @@ +<?php +namespace Elastica\Suggest; + +/** + * Class Term. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-term.html + */ +class Term extends AbstractSuggest +{ + const SORT_SCORE = 'score'; + const SORT_FREQUENCY = 'frequency'; + + const SUGGEST_MODE_MISSING = 'missing'; + const SUGGEST_MODE_POPULAR = 'popular'; + const SUGGEST_MODE_ALWAYS = 'always'; + + /** + * @param string $analyzer + * + * @return $this + */ + public function setAnalyzer($analyzer) + { + return $this->setParam('analyzer', $analyzer); + } + + /** + * @param string $sort see SORT_* constants for options + * + * @return $this + */ + public function setSort($sort) + { + return $this->setParam('sort', $sort); + } + + /** + * @param string $mode see SUGGEST_MODE_* constants for options + * + * @return $this + */ + public function setSuggestMode($mode) + { + return $this->setParam('suggest_mode', $mode); + } + + /** + * If true, suggest terms will be lower cased after text analysis. + * + * @param bool $lowercase + * + * @return $this + */ + public function setLowercaseTerms($lowercase = true) + { + return $this->setParam('lowercase_terms', (bool) $lowercase); + } + + /** + * Set the maximum edit distance candidate suggestions can have in order to be considered as a suggestion. + * + * @param int $max Either 1 or 2. Any other value will result in an error. + * + * @return $this + */ + public function setMaxEdits($max) + { + return $this->setParam('max_edits', (int) $max); + } + + /** + * The number of minimum prefix characters that must match in order to be a suggestion candidate. + * + * @param int $length Defaults to 1. + * + * @return $this + */ + public function setPrefixLength($length) + { + return $this->setParam('prefix_len', (int) $length); + } + + /** + * The minimum length a suggest text term must have in order to be included. + * + * @param int $length Defaults to 4. + * + * @return $this + */ + public function setMinWordLength($length) + { + return $this->setParam('min_word_len', (int) $length); + } + + /** + * @param int $max Defaults to 5. + * + * @return $this + */ + public function setMaxInspections($max) + { + return $this->setParam('max_inspections', $max); + } + + /** + * Set the minimum number of documents in which a suggestion should appear. + * + * @param int|float $min Defaults to 0. If the value is greater than 1, it must be a whole number. + * + * @return $this + */ + public function setMinDocFrequency($min) + { + return $this->setParam('min_doc_freq', $min); + } + + /** + * Set the maximum number of documents in which a suggest text token can exist in order to be included. + * + * @param float $max + * + * @return $this + */ + public function setMaxTermFrequency($max) + { + return $this->setParam('max_term_freq', $max); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Tool/CrossIndex.php b/vendor/ruflin/elastica/lib/Elastica/Tool/CrossIndex.php new file mode 100644 index 00000000..89fc0532 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Tool/CrossIndex.php @@ -0,0 +1,160 @@ +<?php +namespace Elastica\Tool; + +use Elastica\Bulk; +use Elastica\Index; +use Elastica\Query\MatchAll; +use Elastica\ScanAndScroll; +use Elastica\Search; +use Elastica\Type; + +/** + * Functions to move documents and types between indices. + * + * @author Manuel Andreo Garcia <andreo.garcia@gmail.com> + */ +class CrossIndex +{ + /** + * Type option. + * + * type: string | string[] | \Elastica\Type | \Elastica\Type[] | null + * default: null (means all types) + */ + const OPTION_TYPE = 'type'; + + /** + * Query option. + * + * type: see \Elastica\Query::create() + * default: Elastica\Query\MatchAll + */ + const OPTION_QUERY = 'query'; + + /** + * Expiry time option. + * + * type: string (see Elastica\ScanAndScroll) + * default: '1m' + */ + const OPTION_EXPIRY_TIME = 'expiryTime'; + + /** + * Size per shard option. + * + * type: int (see Elastica\ScanAndScroll) + * default: 1000 + */ + const OPTION_SIZE_PER_SHARD = 'sizePerShard'; + + /** + * Reindex documents from an old index to a new index. + * + * @link https://www.elastic.co/guide/en/elasticsearch/guide/master/reindex.html + * + * @param \Elastica\Index $oldIndex + * @param \Elastica\Index $newIndex + * @param array $options keys: CrossIndex::OPTION_* constants + * + * @return \Elastica\Index The new index object + */ + public static function reindex( + Index $oldIndex, + Index $newIndex, + array $options = array() + ) { + // prepare search + $search = new Search($oldIndex->getClient()); + + $options = array_merge( + array( + self::OPTION_TYPE => null, + self::OPTION_QUERY => new MatchAll(), + self::OPTION_EXPIRY_TIME => '1m', + self::OPTION_SIZE_PER_SHARD => 1000, + ), + $options + ); + + $search->addIndex($oldIndex); + if (isset($options[self::OPTION_TYPE])) { + $type = $options[self::OPTION_TYPE]; + $search->addTypes(is_array($type) ? $type : array($type)); + } + $search->setQuery($options[self::OPTION_QUERY]); + + // search on old index and bulk insert in new index + $scanAndScroll = new ScanAndScroll( + $search, + $options[self::OPTION_EXPIRY_TIME], + $options[self::OPTION_SIZE_PER_SHARD] + ); + foreach ($scanAndScroll as $resultSet) { + $bulk = new Bulk($newIndex->getClient()); + $bulk->setIndex($newIndex); + + foreach ($resultSet as $result) { + $action = new Bulk\Action(); + $action->setType($result->getType()); + $action->setId($result->getId()); + $action->setSource($result->getData()); + + $bulk->addAction($action); + } + + $bulk->send(); + } + + $newIndex->refresh(); + + return $newIndex; + } + + /** + * Copies type mappings and documents from an old index to a new index. + * + * @see \Elastica\Tool\CrossIndex::reindex() + * + * @param \Elastica\Index $oldIndex + * @param \Elastica\Index $newIndex + * @param array $options keys: CrossIndex::OPTION_* constants + * + * @return \Elastica\Index The new index object + */ + public static function copy( + Index $oldIndex, + Index $newIndex, + array $options = array() + ) { + // normalize types to array of string + $types = array(); + if (isset($options[self::OPTION_TYPE])) { + $types = $options[self::OPTION_TYPE]; + $types = is_array($types) ? $types : array($types); + + $types = array_map( + function ($type) { + if ($type instanceof Type) { + $type = $type->getName(); + } + + return (string) $type; + }, + $types + ); + } + + // copy mapping + foreach ($oldIndex->getMapping() as $type => $mapping) { + if (!empty($types) && !in_array($type, $types, true)) { + continue; + } + + $type = new Type($newIndex, $type); + $type->setMapping($mapping['properties']); + } + + // copy documents + return self::reindex($oldIndex, $newIndex, $options); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/AbstractTransport.php b/vendor/ruflin/elastica/lib/Elastica/Transport/AbstractTransport.php new file mode 100644 index 00000000..c40b5107 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/AbstractTransport.php @@ -0,0 +1,113 @@ +<?php +namespace Elastica\Transport; + +use Elastica\Connection; +use Elastica\Exception\InvalidException; +use Elastica\Param; +use Elastica\Request; + +/** + * Elastica Abstract Transport object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +abstract class AbstractTransport extends Param +{ + /** + * @var \Elastica\Connection + */ + protected $_connection; + + /** + * Construct transport. + * + * @param \Elastica\Connection $connection Connection object + */ + public function __construct(Connection $connection = null) + { + if ($connection) { + $this->setConnection($connection); + } + } + + /** + * @return \Elastica\Connection Connection object + */ + public function getConnection() + { + return $this->_connection; + } + + /** + * @param \Elastica\Connection $connection Connection object + * + * @return $this + */ + public function setConnection(Connection $connection) + { + $this->_connection = $connection; + + return $this; + } + + /** + * Executes the transport request. + * + * @param \Elastica\Request $request Request object + * @param array $params Hostname, port, path, ... + * + * @return \Elastica\Response Response object + */ + abstract public function exec(Request $request, array $params); + + /** + * Create a transport. + * + * The $transport parameter can be one of the following values: + * + * * string: The short name of a transport. For instance "Http", "Memcache" or "Thrift" + * * object: An already instantiated instance of a transport + * * array: An array with a "type" key which must be set to one of the two options. All other + * keys in the array will be set as parameters in the transport instance + * + * @param mixed $transport A transport definition + * @param \Elastica\Connection $connection A connection instance + * @param array $params Parameters for the transport class + * + * @throws \Elastica\Exception\InvalidException + * + * @return AbstractTransport + */ + public static function create($transport, Connection $connection, array $params = array()) + { + if (is_array($transport) && isset($transport['type'])) { + $transportParams = $transport; + unset($transportParams['type']); + + $params = array_replace($params, $transportParams); + $transport = $transport['type']; + } + + if (is_string($transport)) { + $className = 'Elastica\\Transport\\'.$transport; + + if (!class_exists($className)) { + throw new InvalidException('Invalid transport'); + } + + $transport = new $className(); + } + + if ($transport instanceof self) { + $transport->setConnection($connection); + + foreach ($params as $key => $value) { + $transport->setParam($key, $value); + } + } else { + throw new InvalidException('Invalid transport'); + } + + return $transport; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/Guzzle.php b/vendor/ruflin/elastica/lib/Elastica/Transport/Guzzle.php new file mode 100644 index 00000000..5c98d83b --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/Guzzle.php @@ -0,0 +1,179 @@ +<?php +namespace Elastica\Transport; + +use Elastica\Connection; +use Elastica\Exception\Connection\GuzzleException; +use Elastica\Exception\PartialShardFailureException; +use Elastica\Exception\ResponseException; +use Elastica\JSON; +use Elastica\Request; +use Elastica\Response; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\TransferException; +use GuzzleHttp\Stream\Stream; + +/** + * Elastica Guzzle Transport object. + * + * @author Milan Magudia <milan@magudia.com> + */ +class Guzzle extends AbstractTransport +{ + /** + * Http scheme. + * + * @var string Http scheme + */ + protected $_scheme = 'http'; + + /** + * Curl resource to reuse. + * + * @var resource Guzzle resource to reuse + */ + protected static $_guzzleClientConnection = null; + + /** + * Makes calls to the elasticsearch server. + * + * All calls that are made to the server are done through this function + * + * @param \Elastica\Request $request + * @param array $params Host, Port, ... + * + * @throws \Elastica\Exception\ConnectionException + * @throws \Elastica\Exception\ResponseException + * @throws \Elastica\Exception\Connection\HttpException + * + * @return \Elastica\Response Response object + */ + public function exec(Request $request, array $params) + { + $connection = $this->getConnection(); + + $client = $this->_getGuzzleClient($this->_getBaseUrl($connection), $connection->isPersistent()); + + $options = array( + 'exceptions' => false, // 4xx and 5xx is expected and NOT an exceptions in this context + ); + if ($connection->getTimeout()) { + $options['timeout'] = $connection->getTimeout(); + } + + $proxy = $connection->getProxy(); + + // See: https://github.com/facebook/hhvm/issues/4875 + if (is_null($proxy) && defined('HHVM_VERSION')) { + $proxy = getenv('http_proxy') ?: null; + } + + if (!is_null($proxy)) { + $options['proxy'] = $proxy; + } + + $req = $client->createRequest($request->getMethod(), $this->_getActionPath($request), $options); + $req->setHeaders($connection->hasConfig('headers') ? $connection->getConfig('headers') : array()); + + $data = $request->getData(); + if (!empty($data) || '0' === $data) { + if ($req->getMethod() == Request::GET) { + $req->setMethod(Request::POST); + } + + if ($this->hasParam('postWithRequestBody') && $this->getParam('postWithRequestBody') == true) { + $request->setMethod(Request::POST); + $req->setMethod(Request::POST); + } + + if (is_array($data)) { + $content = JSON::stringify($data, 'JSON_ELASTICSEARCH'); + } else { + $content = $data; + } + $req->setBody(Stream::factory($content)); + } + + try { + $start = microtime(true); + $res = $client->send($req); + $end = microtime(true); + } catch (TransferException $ex) { + throw new GuzzleException($ex, $request, new Response($ex->getMessage())); + } + + $response = new Response((string) $res->getBody(), $res->getStatusCode()); + $response->setQueryTime($end - $start); + + $response->setTransferInfo( + array( + 'request_header' => $request->getMethod(), + 'http_code' => $res->getStatusCode(), + ) + ); + + if ($response->hasError()) { + throw new ResponseException($request, $response); + } + + if ($response->hasFailedShards()) { + throw new PartialShardFailureException($request, $response); + } + + return $response; + } + + /** + * Return Guzzle resource. + * + * @param bool $persistent False if not persistent connection + * + * @return resource Connection resource + */ + protected function _getGuzzleClient($baseUrl, $persistent = true) + { + if (!$persistent || !self::$_guzzleClientConnection) { + self::$_guzzleClientConnection = new Client(array('base_url' => $baseUrl)); + } + + return self::$_guzzleClientConnection; + } + + /** + * Builds the base url for the guzzle connection. + * + * @param \Elastica\Connection $connection + */ + protected function _getBaseUrl(Connection $connection) + { + // If url is set, url is taken. Otherwise port, host and path + $url = $connection->hasConfig('url') ? $connection->getConfig('url') : ''; + + if (!empty($url)) { + $baseUri = $url; + } else { + $baseUri = $this->_scheme.'://'.$connection->getHost().':'.$connection->getPort().'/'.$connection->getPath(); + } + + return rtrim($baseUri, '/'); + } + + /** + * Builds the action path url for each request. + * + * @param \Elastica\Request $request + */ + protected function _getActionPath(Request $request) + { + $action = $request->getPath(); + if ($action) { + $action = '/'.ltrim($action, '/'); + } + $query = $request->getQuery(); + + if (!empty($query)) { + $action .= '?'.http_build_query($query); + } + + return $action; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/Http.php b/vendor/ruflin/elastica/lib/Elastica/Transport/Http.php new file mode 100644 index 00000000..1a33c0a6 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/Http.php @@ -0,0 +1,190 @@ +<?php +namespace Elastica\Transport; + +use Elastica\Exception\Connection\HttpException; +use Elastica\Exception\PartialShardFailureException; +use Elastica\Exception\ResponseException; +use Elastica\JSON; +use Elastica\Request; +use Elastica\Response; + +/** + * Elastica Http Transport object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Http extends AbstractTransport +{ + /** + * Http scheme. + * + * @var string Http scheme + */ + protected $_scheme = 'http'; + + /** + * Curl resource to reuse. + * + * @var resource Curl resource to reuse + */ + protected static $_curlConnection = null; + + /** + * Makes calls to the elasticsearch server. + * + * All calls that are made to the server are done through this function + * + * @param \Elastica\Request $request + * @param array $params Host, Port, ... + * + * @throws \Elastica\Exception\ConnectionException + * @throws \Elastica\Exception\ResponseException + * @throws \Elastica\Exception\Connection\HttpException + * + * @return \Elastica\Response Response object + */ + public function exec(Request $request, array $params) + { + $connection = $this->getConnection(); + + $conn = $this->_getConnection($connection->isPersistent()); + + // If url is set, url is taken. Otherwise port, host and path + $url = $connection->hasConfig('url') ? $connection->getConfig('url') : ''; + + if (!empty($url)) { + $baseUri = $url; + } else { + $baseUri = $this->_scheme.'://'.$connection->getHost().':'.$connection->getPort().'/'.$connection->getPath(); + } + + $baseUri .= $request->getPath(); + + $query = $request->getQuery(); + + if (!empty($query)) { + $baseUri .= '?'.http_build_query($query); + } + + curl_setopt($conn, CURLOPT_URL, $baseUri); + curl_setopt($conn, CURLOPT_TIMEOUT, $connection->getTimeout()); + curl_setopt($conn, CURLOPT_FORBID_REUSE, 0); + + /* @see Connection::setConnectTimeout() */ + $connectTimeout = $connection->getConnectTimeout(); + if ($connectTimeout > 0) { + curl_setopt($conn, CURLOPT_CONNECTTIMEOUT, $connectTimeout); + } + + $proxy = $connection->getProxy(); + + // See: https://github.com/facebook/hhvm/issues/4875 + if (is_null($proxy) && defined('HHVM_VERSION')) { + $proxy = getenv('http_proxy') ?: null; + } + + if (!is_null($proxy)) { + curl_setopt($conn, CURLOPT_PROXY, $proxy); + } + + $this->_setupCurl($conn); + + $headersConfig = $connection->hasConfig('headers') ? $connection->getConfig('headers') : array(); + + if (!empty($headersConfig)) { + $headers = array(); + while (list($header, $headerValue) = each($headersConfig)) { + array_push($headers, $header.': '.$headerValue); + } + + curl_setopt($conn, CURLOPT_HTTPHEADER, $headers); + } + + // TODO: REFACTOR + $data = $request->getData(); + $httpMethod = $request->getMethod(); + + if (!empty($data) || '0' === $data) { + if ($this->hasParam('postWithRequestBody') && $this->getParam('postWithRequestBody') == true) { + $httpMethod = Request::POST; + } + + if (is_array($data)) { + $content = JSON::stringify($data, 'JSON_ELASTICSEARCH'); + } else { + $content = $data; + } + + // Escaping of / not necessary. Causes problems in base64 encoding of files + $content = str_replace('\/', '/', $content); + + curl_setopt($conn, CURLOPT_POSTFIELDS, $content); + } else { + curl_setopt($conn, CURLOPT_POSTFIELDS, ''); + } + + curl_setopt($conn, CURLOPT_NOBODY, $httpMethod == 'HEAD'); + + curl_setopt($conn, CURLOPT_CUSTOMREQUEST, $httpMethod); + + $start = microtime(true); + + // cURL opt returntransfer leaks memory, therefore OB instead. + ob_start(); + curl_exec($conn); + $responseString = ob_get_clean(); + + $end = microtime(true); + + // Checks if error exists + $errorNumber = curl_errno($conn); + + $response = new Response($responseString, curl_getinfo($conn, CURLINFO_HTTP_CODE)); + $response->setQueryTime($end - $start); + $response->setTransferInfo(curl_getinfo($conn)); + + if ($response->hasError()) { + throw new ResponseException($request, $response); + } + + if ($response->hasFailedShards()) { + throw new PartialShardFailureException($request, $response); + } + + if ($errorNumber > 0) { + throw new HttpException($errorNumber, $request, $response); + } + + return $response; + } + + /** + * Called to add additional curl params. + * + * @param resource $curlConnection Curl connection + */ + protected function _setupCurl($curlConnection) + { + if ($this->getConnection()->hasConfig('curl')) { + foreach ($this->getConnection()->getConfig('curl') as $key => $param) { + curl_setopt($curlConnection, $key, $param); + } + } + } + + /** + * Return Curl resource. + * + * @param bool $persistent False if not persistent connection + * + * @return resource Connection resource + */ + protected function _getConnection($persistent = true) + { + if (!$persistent || !self::$_curlConnection) { + self::$_curlConnection = curl_init(); + } + + return self::$_curlConnection; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/HttpAdapter.php b/vendor/ruflin/elastica/lib/Elastica/Transport/HttpAdapter.php new file mode 100644 index 00000000..efc27ab5 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/HttpAdapter.php @@ -0,0 +1,156 @@ +<?php +namespace Elastica\Transport; + +use Elastica\Connection; +use Elastica\Exception\PartialShardFailureException; +use Elastica\Exception\ResponseException; +use Elastica\JSON; +use Elastica\Request as ElasticaRequest; +use Elastica\Response as ElasticaResponse; +use Ivory\HttpAdapter\HttpAdapterInterface; +use Ivory\HttpAdapter\Message\Request as HttpAdapterRequest; +use Ivory\HttpAdapter\Message\Response as HttpAdapterResponse; +use Ivory\HttpAdapter\Message\Stream\StringStream; + +class HttpAdapter extends AbstractTransport +{ + /** + * @var HttpAdapterInterface + */ + private $httpAdapter; + + /** + * @var string + */ + private $_scheme = 'http'; + + /** + * Construct transport. + */ + public function __construct(Connection $connection = null, HttpAdapterInterface $httpAdapter) + { + parent::__construct($connection); + $this->httpAdapter = $httpAdapter; + } + + /** + * Makes calls to the elasticsearch server. + * + * All calls that are made to the server are done through this function + * + * @param \Elastica\Request $elasticaRequest + * @param array $params Host, Port, ... + * + * @throws \Elastica\Exception\ConnectionException + * @throws \Elastica\Exception\ResponseException + * @throws \Elastica\Exception\Connection\HttpException + * + * @return \Elastica\Response Response object + */ + public function exec(ElasticaRequest $elasticaRequest, array $params) + { + $connection = $this->getConnection(); + + if ($timeout = $connection->getTimeout()) { + $this->httpAdapter->getConfiguration()->setTimeout($timeout); + } + + $httpAdapterRequest = $this->_createHttpAdapterRequest($elasticaRequest, $connection); + + $start = microtime(true); + $httpAdapterResponse = $this->httpAdapter->sendRequest($httpAdapterRequest); + $end = microtime(true); + + $elasticaResponse = $this->_createElasticaResponse($httpAdapterResponse, $connection); + $elasticaResponse->setQueryTime($end - $start); + + $elasticaResponse->setTransferInfo( + array( + 'request_header' => $httpAdapterRequest->getMethod(), + 'http_code' => $httpAdapterResponse->getStatusCode(), + ) + ); + + if ($elasticaResponse->hasError()) { + throw new ResponseException($elasticaRequest, $elasticaResponse); + } + + if ($elasticaResponse->hasFailedShards()) { + throw new PartialShardFailureException($elasticaRequest, $elasticaResponse); + } + + return $elasticaResponse; + } + + /** + * @param HttpAdapterResponse $httpAdapterResponse + * + * @return ElasticaResponse + */ + protected function _createElasticaResponse(HttpAdapterResponse $httpAdapterResponse) + { + return new ElasticaResponse((string) $httpAdapterResponse->getBody(), $httpAdapterResponse->getStatusCode()); + } + + /** + * @param ElasticaRequest $elasticaRequest + * @param Connection $connection + * + * @return HttpAdapterRequest + */ + protected function _createHttpAdapterRequest(ElasticaRequest $elasticaRequest, Connection $connection) + { + $data = $elasticaRequest->getData(); + $body = null; + $method = $elasticaRequest->getMethod(); + $headers = $connection->hasConfig('headers') ?: array(); + if (!empty($data) || '0' === $data) { + if ($method == ElasticaRequest::GET) { + $method = ElasticaRequest::POST; + } + + if ($this->hasParam('postWithRequestBody') && $this->getParam('postWithRequestBody') == true) { + $elasticaRequest->setMethod(ElasticaRequest::POST); + $method = ElasticaRequest::POST; + } + + if (is_array($data)) { + $body = JSON::stringify($data, 'JSON_ELASTICSEARCH'); + } else { + $body = $data; + } + } + + $url = $this->_getUri($elasticaRequest, $connection); + $streamBody = new StringStream($body); + + return new HttpAdapterRequest($url, $method, HttpAdapterRequest::PROTOCOL_VERSION_1_1, $headers, $streamBody); + } + + /** + * @param ElasticaRequest $request + * @param \Elastica\Connection $connection + * + * @return string + */ + protected function _getUri(ElasticaRequest $request, Connection $connection) + { + $url = $connection->hasConfig('url') ? $connection->getConfig('url') : ''; + + if (!empty($url)) { + $baseUri = $url; + } else { + $baseUri = $this->_scheme.'://'.$connection->getHost().':'.$connection->getPort().'/'.$connection->getPath(); + } + + $baseUri .= $request->getPath(); + + $query = $request->getQuery(); + + if (!empty($query)) { + $baseUri .= '?'.http_build_query($query); + } + + return $baseUri; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/Https.php b/vendor/ruflin/elastica/lib/Elastica/Transport/Https.php new file mode 100644 index 00000000..b2b489dd --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/Https.php @@ -0,0 +1,27 @@ +<?php +namespace Elastica\Transport; + +/** + * Elastica Http Transport object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Https extends Http +{ + /** + * Https scheme. + * + * @var string https scheme + */ + protected $_scheme = 'https'; + + /** + * Overloads setupCurl to set SSL params. + * + * @param resource $connection Curl connection resource + */ + protected function _setupCurl($connection) + { + parent::_setupCurl($connection); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/Memcache.php b/vendor/ruflin/elastica/lib/Elastica/Transport/Memcache.php new file mode 100644 index 00000000..fb56cdf4 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/Memcache.php @@ -0,0 +1,109 @@ +<?php +namespace Elastica\Transport; + +use Elastica\Exception\Connection\MemcacheException; +use Elastica\Exception\InvalidException; +use Elastica\Exception\PartialShardFailureException; +use Elastica\Exception\ResponseException; +use Elastica\JSON; +use Elastica\Request; +use Elastica\Response; + +/** + * Elastica Memcache Transport object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @deprecated The memcached transport is deprecated as of ES 1.5, and will be removed in ES 2.0 + */ +class Memcache extends AbstractTransport +{ + const MAX_KEY_LENGTH = 250; + + /** + * Makes calls to the elasticsearch server. + * + * @param \Elastica\Request $request + * @param array $params Host, Port, ... + * + * @throws \Elastica\Exception\ResponseException + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\Response Response object + */ + public function exec(Request $request, array $params) + { + $memcache = new \Memcache(); + $memcache->connect($this->getConnection()->getHost(), $this->getConnection()->getPort()); + + $data = $request->getData(); + + $content = ''; + + if (!empty($data) || '0' === $data) { + if (is_array($data)) { + $content = JSON::stringify($data); + } else { + $content = $data; + } + + // Escaping of / not necessary. Causes problems in base64 encoding of files + $content = str_replace('\/', '/', $content); + } + + $responseString = ''; + + $start = microtime(true); + + switch ($request->getMethod()) { + case Request::POST: + case Request::PUT: + $key = $request->getPath(); + $this->_checkKeyLength($key); + $memcache->set($key, $content); + break; + case Request::GET: + $key = $request->getPath().'?source='.$content; + $this->_checkKeyLength($key); + $responseString = $memcache->get($key); + break; + case Request::DELETE: + $key = $request->getPath().'?source='.$content; + $this->_checkKeyLength($key); + $responseString = $memcache->delete($key); + break; + default: + case Request::HEAD: + throw new InvalidException('Method '.$request->getMethod().' is not supported in memcache transport'); + } + + $end = microtime(true); + + $response = new Response($responseString); + $response->setQueryTime($end - $start); + + if ($response->hasError()) { + throw new ResponseException($request, $response); + } + + if ($response->hasFailedShards()) { + throw new PartialShardFailureException($request, $response); + } + + return $response; + } + + /** + * Check if key that will be used dont exceed 250 symbols. + * + * @param string $key + * + * @throws Elastica\Exception\Connection\MemcacheException If key is too long + */ + private function _checkKeyLength($key) + { + if (strlen($key) >= self::MAX_KEY_LENGTH) { + throw new MemcacheException('Memcache key is too long'); + } + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/Null.php b/vendor/ruflin/elastica/lib/Elastica/Transport/Null.php new file mode 100644 index 00000000..70dd9af1 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/Null.php @@ -0,0 +1,13 @@ +<?php +namespace Elastica\Transport; + +/** + * Elastica Null Transport object. + * + * This class is for backward compatibility reason for all php < 7 versions. For PHP 7 and above use NullTransport as Null is reserved. + * + * @author James Boehmer <james.boehmer@jamesboehmer.com> + */ +class Null extends NullTransport +{ +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/NullTransport.php b/vendor/ruflin/elastica/lib/Elastica/Transport/NullTransport.php new file mode 100644 index 00000000..d24f2110 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/NullTransport.php @@ -0,0 +1,46 @@ +<?php +namespace Elastica\Transport; + +use Elastica\JSON; +use Elastica\Request; +use Elastica\Response; + +/** + * Elastica Null Transport object. + * + * This is used in case you just need a test transport that doesn't do any connection to an elasticsearch + * host but still returns a valid response object + * + * @author James Boehmer <james.boehmer@jamesboehmer.com> + */ +class NullTransport extends AbstractTransport +{ + /** + * Null transport. + * + * @param \Elastica\Request $request + * @param array $params Hostname, port, path, ... + * + * @return \Elastica\Response Response empty object + */ + public function exec(Request $request, array $params) + { + $response = array( + 'took' => 0, + 'timed_out' => false, + '_shards' => array( + 'total' => 0, + 'successful' => 0, + 'failed' => 0, + ), + 'hits' => array( + 'total' => 0, + 'max_score' => null, + 'hits' => array(), + ), + 'params' => $params, + ); + + return new Response(JSON::stringify($response)); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Transport/Thrift.php b/vendor/ruflin/elastica/lib/Elastica/Transport/Thrift.php new file mode 100644 index 00000000..5790f665 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Transport/Thrift.php @@ -0,0 +1,176 @@ +<?php +namespace Elastica\Transport; + +use Elastica\Connection; +use Elastica\Exception\Connection\ThriftException; +use Elastica\Exception\PartialShardFailureException; +use Elastica\Exception\ResponseException; +use Elastica\Exception\RuntimeException; +use Elastica\JSON; +use Elastica\Request; +use Elastica\Response; +use Elasticsearch\Method; +use Elasticsearch\RestClient; +use Elasticsearch\RestRequest; +use Elasticsearch\RestResponse; +use Thrift\Exception\TException; +use Thrift\Protocol\TBinaryProtocolAccelerated; +use Thrift\Transport\TBufferedTransport; +use Thrift\Transport\TFramedTransport; +use Thrift\Transport\TSocket; + +/** + * Elastica Thrift Transport object. + * + * @author Mikhail Shamin <munk13@gmail.com> + * + * @deprecated The thrift transport is deprecated as of ES 1.5, and will be removed in ES 2.0 + */ +class Thrift extends AbstractTransport +{ + /** + * @var RestClient[] + */ + protected $_clients = array(); + + /** + * Construct transport. + * + * @param \Elastica\Connection $connection Connection object + * + * @throws \Elastica\Exception\RuntimeException + */ + public function __construct(Connection $connection = null) + { + parent::__construct($connection); + if (!class_exists('Elasticsearch\\RestClient')) { + throw new RuntimeException('Elasticsearch\\RestClient class not found. Check that suggested package munkie/elasticsearch-thrift-php is required in composer.json'); + } + } + + /** + * @param string $host + * @param int $port + * @param int $sendTimeout msec + * @param int $recvTimeout msec + * @param bool $framedTransport + * + * @return \Elasticsearch\RestClient + */ + protected function _createClient($host, $port, $sendTimeout = null, $recvTimeout = null, $framedTransport = false) + { + $socket = new TSocket($host, $port, true); + + if (null !== $sendTimeout) { + $socket->setSendTimeout($sendTimeout); + } + + if (null !== $recvTimeout) { + $socket->setRecvTimeout($recvTimeout); + } + + if ($framedTransport) { + $transport = new TFramedTransport($socket); + } else { + $transport = new TBufferedTransport($socket); + } + $protocol = new TBinaryProtocolAccelerated($transport); + + $client = new RestClient($protocol); + + $transport->open(); + + return $client; + } + + /** + * @param string $host + * @param int $port + * @param int $sendTimeout + * @param int $recvTimeout + * @param bool $framedTransport + * + * @return \Elasticsearch\RestClient + */ + protected function _getClient($host, $port, $sendTimeout = null, $recvTimeout = null, $framedTransport = false) + { + $key = $host.':'.$port; + if (!isset($this->_clients[$key])) { + $this->_clients[$key] = $this->_createClient($host, $port, $sendTimeout, $recvTimeout, $framedTransport); + } + + return $this->_clients[$key]; + } + + /** + * Makes calls to the elasticsearch server. + * + * @param \Elastica\Request $request + * @param array $params Host, Port, ... + * + * @throws \Elastica\Exception\Connection\ThriftException + * @throws \Elastica\Exception\ResponseException + * + * @return \Elastica\Response Response object + */ + public function exec(Request $request, array $params) + { + $connection = $this->getConnection(); + + $sendTimeout = $connection->hasConfig('sendTimeout') ? $connection->getConfig('sendTimeout') : null; + $recvTimeout = $connection->hasConfig('recvTimeout') ? $connection->getConfig('recvTimeout') : null; + $framedTransport = $connection->hasConfig('framedTransport') ? (bool) $connection->getConfig('framedTransport') : false; + + try { + $client = $this->_getClient( + $connection->getHost(), + $connection->getPort(), + $sendTimeout, + $recvTimeout, + $framedTransport + ); + + $restRequest = new RestRequest(); + $restRequest->method = array_search($request->getMethod(), Method::$__names); + $restRequest->uri = $request->getPath(); + + $query = $request->getQuery(); + if (!empty($query)) { + $restRequest->parameters = $query; + } + + $data = $request->getData(); + if (!empty($data) || '0' === $data) { + if (is_array($data)) { + $content = JSON::stringify($data); + } else { + $content = $data; + } + $restRequest->body = $content; + } + + /* @var $result RestResponse */ + $start = microtime(true); + + $result = $client->execute($restRequest); + $response = new Response($result->body); + + $end = microtime(true); + } catch (TException $e) { + $response = new Response(''); + throw new ThriftException($e, $request, $response); + } + + $response->setQueryTime($end - $start); + + if ($response->hasError()) { + throw new ResponseException($request, $response); + } + + if ($response->hasFailedShards()) { + throw new PartialShardFailureException($request, $response); + } + + return $response; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Type.php b/vendor/ruflin/elastica/lib/Elastica/Type.php new file mode 100644 index 00000000..8abec330 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Type.php @@ -0,0 +1,572 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; +use Elastica\Exception\NotFoundException; +use Elastica\Exception\RuntimeException; +use Elastica\Type\Mapping; + +/** + * Elastica type object. + * + * elasticsearch has for every types as a substructure. This object + * represents a type inside a context + * The hierarchy is as following: client -> index -> type -> document + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Type implements SearchableInterface +{ + /** + * Index. + * + * @var \Elastica\Index Index object + */ + protected $_index = null; + + /** + * Type name. + * + * @var string Type name + */ + protected $_name = ''; + + /** + * @var array|string A callable that serializes an object passed to it + */ + protected $_serializer; + + /** + * Creates a new type object inside the given index. + * + * @param \Elastica\Index $index Index Object + * @param string $name Type name + */ + public function __construct(Index $index, $name) + { + $this->_index = $index; + $this->_name = $name; + } + + /** + * Adds the given document to the search index. + * + * @param \Elastica\Document $doc Document with data + * + * @return \Elastica\Response + */ + public function addDocument(Document $doc) + { + $path = urlencode($doc->getId()); + + $type = Request::PUT; + + // If id is empty, POST has to be used to automatically create id + if (empty($path)) { + $type = Request::POST; + } + + $options = $doc->getOptions( + array( + 'version', + 'version_type', + 'routing', + 'percolate', + 'parent', + 'ttl', + 'timestamp', + 'op_type', + 'consistency', + 'replication', + 'refresh', + 'timeout', + ) + ); + + $response = $this->request($path, $type, $doc->getData(), $options); + + $data = $response->getData(); + // set autogenerated id to document + if (($doc->isAutoPopulate() + || $this->getIndex()->getClient()->getConfigValue(array('document', 'autoPopulate'), false)) + && $response->isOk() + ) { + if (!$doc->hasId()) { + if (isset($data['_id'])) { + $doc->setId($data['_id']); + } + } + if (isset($data['_version'])) { + $doc->setVersion($data['_version']); + } + } + + return $response; + } + + /** + * @param $object + * @param Document $doc + * + * @throws Exception\RuntimeException + * + * @return Response + */ + public function addObject($object, Document $doc = null) + { + if (!isset($this->_serializer)) { + throw new RuntimeException('No serializer defined'); + } + + $data = call_user_func($this->_serializer, $object); + if (!$doc) { + $doc = new Document(); + } + $doc->setData($data); + + return $this->addDocument($doc); + } + + /** + * Update document, using update script. Requires elasticsearch >= 0.19.0. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html + * + * @param \Elastica\Document|\Elastica\Script $data Document with update data + * @param array $options array of query params to use for query. For possible options check es api + * + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\Response + */ + public function updateDocument($data, array $options = array()) + { + if (!($data instanceof Document) && !($data instanceof Script)) { + throw new \InvalidArgumentException('Data should be a Document or Script'); + } + + if (!$data->hasId()) { + throw new InvalidException('Document or Script id is not set'); + } + + $id = urlencode($data->getId()); + + return $this->getIndex()->getClient()->updateDocument( + $id, + $data, + $this->getIndex()->getName(), + $this->getName(), + $options + ); + } + + /** + * Uses _bulk to send documents to the server. + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @return \Elastica\Bulk\ResponseSet + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + */ + public function updateDocuments(array $docs) + { + foreach ($docs as $doc) { + $doc->setType($this->getName()); + } + + return $this->getIndex()->updateDocuments($docs); + } + + /** + * Uses _bulk to send documents to the server. + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @return \Elastica\Bulk\ResponseSet + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + */ + public function addDocuments(array $docs) + { + foreach ($docs as $doc) { + $doc->setType($this->getName()); + } + + return $this->getIndex()->addDocuments($docs); + } + + /** + * Uses _bulk to send documents to the server. + * + * @param objects[] $objects + * + * @return \Elastica\Bulk\ResponseSet + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + */ + public function addObjects(array $objects) + { + if (!isset($this->_serializer)) { + throw new RuntimeException('No serializer defined'); + } + + $docs = array(); + foreach ($objects as $object) { + $data = call_user_func($this->_serializer, $object); + $doc = new Document(); + $doc->setData($data); + $doc->setType($this->getName()); + $docs[] = $doc; + } + + return $this->getIndex()->addDocuments($docs); + } + + /** + * Get the document from search index. + * + * @param string $id Document id + * @param array $options Options for the get request. + * + * @throws \Elastica\Exception\NotFoundException + * @throws \Elastica\Exception\ResponseException + * + * @return \Elastica\Document + */ + public function getDocument($id, $options = array()) + { + $path = urlencode($id); + + $response = $this->request($path, Request::GET, array(), $options); + $result = $response->getData(); + + if (!isset($result['found']) || $result['found'] === false) { + throw new NotFoundException('doc id '.$id.' not found'); + } + + if (isset($result['fields'])) { + $data = $result['fields']; + } elseif (isset($result['_source'])) { + $data = $result['_source']; + } else { + $data = array(); + } + + $document = new Document($id, $data, $this->getName(), $this->getIndex()); + $document->setVersion($result['_version']); + + return $document; + } + + /** + * @param string $id + * @param array|string $data + * + * @return Document + */ + public function createDocument($id = '', $data = array()) + { + $document = new Document($id, $data); + $document->setType($this); + + return $document; + } + + /** + * Returns the type name. + * + * @return string Type name + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets value type mapping for this type. + * + * @param \Elastica\Type\Mapping|array $mapping Elastica\Type\MappingType object or property array with all mappings + * + * @return \Elastica\Response + */ + public function setMapping($mapping) + { + $mapping = Mapping::create($mapping); + $mapping->setType($this); + + return $mapping->send(); + } + + /** + * Returns current mapping for the given type. + * + * @return array Current mapping + */ + public function getMapping() + { + $path = '_mapping'; + + $response = $this->request($path, Request::GET); + $data = $response->getData(); + + $mapping = array_shift($data); + if (isset($mapping['mappings'])) { + return $mapping['mappings']; + } + + return array(); + } + + /** + * Create search object. + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * + * @return \Elastica\Search + */ + public function createSearch($query = '', $options = null) + { + $search = new Search($this->getIndex()->getClient()); + $search->addIndex($this->getIndex()); + $search->addType($this); + $search->setOptionsAndQuery($options, $query); + + return $search; + } + + /** + * Do a search on this type. + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * + * @return \Elastica\ResultSet ResultSet with all results inside + * + * @see \Elastica\SearchableInterface::search + */ + public function search($query = '', $options = null) + { + $search = $this->createSearch($query, $options); + + return $search->search(); + } + + /** + * Count docs by query. + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * + * @return int number of documents matching the query + * + * @see \Elastica\SearchableInterface::count + */ + public function count($query = '') + { + $search = $this->createSearch($query); + + return $search->count(); + } + + /** + * Returns index client. + * + * @return \Elastica\Index Index object + */ + public function getIndex() + { + return $this->_index; + } + + /** + * @param \Elastica\Document $document + * + * @return \Elastica\Response + */ + public function deleteDocument(Document $document) + { + $options = $document->getOptions( + array( + 'version', + 'version_type', + 'routing', + 'parent', + 'replication', + 'consistency', + 'refresh', + 'timeout', + ) + ); + + return $this->deleteById($document->getId(), $options); + } + + /** + * Uses _bulk to delete documents from the server. + * + * @param array|\Elastica\Document[] $docs Array of Elastica\Document + * + * @return \Elastica\Bulk\ResponseSet + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html + */ + public function deleteDocuments(array $docs) + { + foreach ($docs as $doc) { + $doc->setType($this->getName()); + } + + return $this->getIndex()->deleteDocuments($docs); + } + + /** + * Deletes an entry by its unique identifier. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html + * + * @param int|string $id Document id + * @param array $options + * + * @throws \InvalidArgumentException + * @throws \Elastica\Exception\NotFoundException + * + * @return \Elastica\Response Response object + */ + public function deleteById($id, array $options = array()) + { + if (empty($id) || !trim($id)) { + throw new \InvalidArgumentException(); + } + + $id = urlencode($id); + + $response = $this->request($id, Request::DELETE, array(), $options); + + $responseData = $response->getData(); + + if (isset($responseData['found']) && false == $responseData['found']) { + throw new NotFoundException('Doc id '.$id.' not found and can not be deleted'); + } + + return $response; + } + + /** + * Deletes the given list of ids from this type. + * + * @param array $ids + * @param string|false $routing Optional routing key for all ids + * + * @return \Elastica\Response Response object + */ + public function deleteIds(array $ids, $routing = false) + { + return $this->getIndex()->getClient()->deleteIds($ids, $this->getIndex(), $this, $routing); + } + + /** + * Deletes entries in the db based on a query. + * + * @param \Elastica\Query|string $query Query object + * @param array $options Optional params + * + * @return \Elastica\Response + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html + */ + public function deleteByQuery($query, array $options = array()) + { + if (is_string($query)) { + // query_string queries are not supported for delete by query operations + $options['q'] = $query; + + return $this->request('_query', Request::DELETE, array(), $options); + } + $query = Query::create($query); + + return $this->request('_query', Request::DELETE, array('query' => $query->getQuery()), $options); + } + + /** + * Deletes the index type. + * + * @return \Elastica\Response + */ + public function delete() + { + $response = $this->request('', Request::DELETE); + + return $response; + } + + /** + * More like this query based on the given object. + * + * The id in the given object has to be set + * + * @param \Elastica\Document $doc Document to query for similar objects + * @param array $params OPTIONAL Additional arguments for the query + * @param string|array|\Elastica\Query $query OPTIONAL Query to filter the moreLikeThis results + * + * @return \Elastica\ResultSet ResultSet with all results inside + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-more-like-this.html + */ + public function moreLikeThis(Document $doc, $params = array(), $query = array()) + { + $path = $doc->getId().'/_mlt'; + + $query = Query::create($query); + + $response = $this->request($path, Request::GET, $query->toArray(), $params); + + return ResultSet::create($response, $query); + } + + /** + * Makes calls to the elasticsearch server based on this type. + * + * @param string $path Path to call + * @param string $method Rest method to use (GET, POST, DELETE, PUT) + * @param array $data OPTIONAL Arguments as array + * @param array $query OPTIONAL Query params + * + * @return \Elastica\Response Response object + */ + public function request($path, $method, $data = array(), array $query = array()) + { + $path = $this->getName().'/'.$path; + + return $this->getIndex()->request($path, $method, $data, $query); + } + + /** + * Sets the serializer callable used in addObject. + * + * @see \Elastica\Type::addObject + * + * @param array|string $serializer @see \Elastica\Type::_serializer + * + * @return $this + */ + public function setSerializer($serializer) + { + $this->_serializer = $serializer; + + return $this; + } + + /** + * Checks if the given type exists in Index. + * + * @return bool True if type exists + */ + public function exists() + { + $response = $this->getIndex()->request($this->getName(), Request::HEAD); + $info = $response->getTransferInfo(); + + return (bool) ($info['http_code'] == 200); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Type/AbstractType.php b/vendor/ruflin/elastica/lib/Elastica/Type/AbstractType.php new file mode 100644 index 00000000..648102d2 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Type/AbstractType.php @@ -0,0 +1,205 @@ +<?php +namespace Elastica\Type; + +use Elastica\Client; +use Elastica\Exception\InvalidException; +use Elastica\Index; +use Elastica\SearchableInterface; +use Elastica\Type as BaseType; +use Elastica\Util; + +/** + * Abstract helper class to implement search indices based on models. + * + * This abstract model should help creating search index and a subtype + * with some easy config entries that are overloaded. + * + * The following variables have to be set: + * - $_indexName + * - $_typeName + * + * The following variables can be set for additional configuration + * - $_mapping: Value type mapping for the given type + * - $_indexParams: Parameters for the index + * + * @todo Add some settings examples to code + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +abstract class AbstractType implements SearchableInterface +{ + const MAX_DOCS_PER_REQUEST = 1000; + + /** + * Index name. + * + * @var string Index name + */ + protected $_indexName = ''; + + /** + * Index name. + * + * @var string Index name + */ + protected $_typeName = ''; + + /** + * Client. + * + * @var \Elastica\Client Client object + */ + protected $_client = null; + + /** + * Index. + * + * @var \Elastica\Index Index object + */ + protected $_index = null; + + /** + * Type. + * + * @var \Elastica\Type Type object + */ + protected $_type = null; + + /** + * Mapping. + * + * @var array Mapping + */ + protected $_mapping = array(); + + /** + * Index params. + * + * @var array Index params + */ + protected $_indexParams = array(); + + /** + * Source. + * + * @var bool Source + */ + protected $_source = true; + + /** + * Creates index object with client connection. + * + * Reads index and type name from protected vars _indexName and _typeName. + * Has to be set in child class + * + * @param \Elastica\Client $client OPTIONAL Client object + * + * @throws \Elastica\Exception\InvalidException + */ + public function __construct(Client $client = null) + { + if (!$client) { + $client = new Client(); + } + + if (empty($this->_indexName)) { + throw new InvalidException('Index name has to be set'); + } + + if (empty($this->_typeName)) { + throw new InvalidException('Type name has to be set'); + } + + $this->_client = $client; + $this->_index = new Index($this->_client, $this->_indexName); + $this->_type = new BaseType($this->_index, $this->_typeName); + } + + /** + * Creates the index and sets the mapping for this type. + * + * @param bool $recreate OPTIONAL Recreates the index if true (default = false) + */ + public function create($recreate = false) + { + $this->getIndex()->create($this->_indexParams, $recreate); + + $mapping = new Mapping($this->getType()); + $mapping->setProperties($this->_mapping); + $mapping->setSource(array('enabled' => $this->_source)); + $mapping->send(); + } + + /** + * @param \Elastica\Query $query + * @param array|int $options + * + * @return \Elastica\Search + */ + public function createSearch($query = '', $options = null) + { + return $this->getType()->createSearch($query, $options); + } + + /** + * Search on the type. + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * + * @return \Elastica\ResultSet ResultSet with all results inside + * + * @see \Elastica\SearchableInterface::search + */ + public function search($query = '', $options = null) + { + return $this->getType()->search($query, $options = null); + } + + /** + * Count docs in the type based on query. + * + * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object + * + * @return int number of documents matching the query + * + * @see \Elastica\SearchableInterface::count + */ + public function count($query = '') + { + return $this->getType()->count($query); + } + + /** + * Returns the search index. + * + * @return \Elastica\Index Index object + */ + public function getIndex() + { + return $this->_index; + } + + /** + * Returns type object. + * + * @return \Elastica\Type Type object + */ + public function getType() + { + return $this->_type; + } + + /** + * Converts given time to format: 1995-12-31T23:59:59Z. + * + * This is the lucene date format + * + * @param int $date Date input (could be string etc.) -> must be supported by strtotime + * + * @return string Converted date string + */ + public function convertDate($date) + { + return Util::convertDate($date); + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Type/Mapping.php b/vendor/ruflin/elastica/lib/Elastica/Type/Mapping.php new file mode 100644 index 00000000..509f0ce2 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Type/Mapping.php @@ -0,0 +1,297 @@ +<?php +namespace Elastica\Type; + +use Elastica\Exception\InvalidException; +use Elastica\Request; +use Elastica\Type; + +/** + * Elastica Mapping object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html + */ +class Mapping +{ + /** + * Mapping. + * + * @var array Mapping + */ + protected $_mapping = array(); + + /** + * Type. + * + * @var \Elastica\Type Type object + */ + protected $_type = null; + + /** + * Construct Mapping. + * + * @param \Elastica\Type $type OPTIONAL Type object + * @param array $properties OPTIONAL Properties + */ + public function __construct(Type $type = null, array $properties = array()) + { + if ($type) { + $this->setType($type); + } + + if (!empty($properties)) { + $this->setProperties($properties); + } + } + + /** + * Sets the mapping type + * Enter description here ... + * + * @param \Elastica\Type $type Type object + * + * @return $this + */ + public function setType(Type $type) + { + $this->_type = $type; + + return $this; + } + + /** + * Sets the mapping properties. + * + * @param array $properties Properties + * + * @return $this + */ + public function setProperties(array $properties) + { + return $this->setParam('properties', $properties); + } + + /** + * Gets the mapping properties. + * + * @return array $properties Properties + */ + public function getProperties() + { + return $this->getParam('properties'); + } + + /** + * Sets the mapping _meta. + * + * @param array $meta metadata + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-meta.html + */ + public function setMeta(array $meta) + { + return $this->setParam('_meta', $meta); + } + + /** + * Returns mapping type. + * + * @return \Elastica\Type Type + */ + public function getType() + { + return $this->_type; + } + + /** + * Sets source values. + * + * To disable source, argument is + * array('enabled' => false) + * + * @param array $source Source array + * + * @return $this + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html + */ + public function setSource(array $source) + { + return $this->setParam('_source', $source); + } + + /** + * Disables the source in the index. + * + * Param can be set to true to enable again + * + * @param bool $enabled OPTIONAL (default = false) + * + * @return $this + */ + public function disableSource($enabled = false) + { + return $this->setSource(array('enabled' => $enabled)); + } + + /** + * Sets raw parameters. + * + * Possible options: + * _uid + * _id + * _type + * _source + * _all + * _analyzer + * _boost + * _parent + * _routing + * _index + * _size + * properties + * + * @param string $key Key name + * @param mixed $value Key value + * + * @return $this + */ + public function setParam($key, $value) + { + $this->_mapping[$key] = $value; + + return $this; + } + + /** + * Get raw parameters. + * + * @see setParam + * + * @param string $key Key name + * + * @return mixed $value Key value + */ + public function getParam($key) + { + return isset($this->_mapping[$key]) ? $this->_mapping[$key] : null; + } + + /** + * Sets params for the "_all" field. + * + * @param array $params _all Params (enabled, store, term_vector, analyzer) + * + * @return $this + */ + public function setAllField(array $params) + { + return $this->setParam('_all', $params); + } + + /** + * Enables the "_all" field. + * + * @param bool $enabled OPTIONAL (default = true) + * + * @return $this + */ + public function enableAllField($enabled = true) + { + return $this->setAllField(array('enabled' => $enabled)); + } + + /** + * Set TTL. + * + * @param array $params TTL Params (enabled, default, ...) + * + * @return $this + */ + public function setTtl(array $params) + { + return $this->setParam('_ttl', $params); + } + + /** + * Enables TTL for all documents in this type. + * + * @param bool $enabled OPTIONAL (default = true) + * + * @return $this + */ + public function enableTtl($enabled = true) + { + return $this->setTTL(array('enabled' => $enabled)); + } + + /** + * Set parent type. + * + * @param string $type Parent type + * + * @return $this + */ + public function setParent($type) + { + return $this->setParam('_parent', array('type' => $type)); + } + + /** + * Converts the mapping to an array. + * + * @throws \Elastica\Exception\InvalidException + * + * @return array Mapping as array + */ + public function toArray() + { + $type = $this->getType(); + + if (empty($type)) { + throw new InvalidException('Type has to be set'); + } + + return array($type->getName() => $this->_mapping); + } + + /** + * Submits the mapping and sends it to the server. + * + * @return \Elastica\Response Response object + */ + public function send() + { + $path = '_mapping'; + + return $this->getType()->request($path, Request::PUT, $this->toArray()); + } + + /** + * Creates a mapping object. + * + * @param array|\Elastica\Type\Mapping $mapping Mapping object or properties array + * + * @throws \Elastica\Exception\InvalidException If invalid type + * + * @return self + */ + public static function create($mapping) + { + if (is_array($mapping)) { + $mappingObject = new self(); + $mappingObject->setProperties($mapping); + } else { + $mappingObject = $mapping; + } + + if (!$mappingObject instanceof self) { + throw new InvalidException('Invalid object type'); + } + + return $mappingObject; + } +} diff --git a/vendor/ruflin/elastica/lib/Elastica/Util.php b/vendor/ruflin/elastica/lib/Elastica/Util.php new file mode 100644 index 00000000..a49f2d78 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Util.php @@ -0,0 +1,194 @@ +<?php +namespace Elastica; + +/** + * Elastica tools. + * + * @author Nicolas Ruflin <spam@ruflin.com> + * @author Thibault Duplessis <thibault.duplessis@gmail.com> + * @author Oleg Zinchenko <olegz@default-value.com> + * @author Roberto Nygaard <roberto@nygaard.es> + */ +class Util +{ + /** + * Replace the following reserved words: AND OR NOT + * and + * escapes the following terms: + - && || ! ( ) { } [ ] ^ " ~ * ? : \. + * + * @link http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Boolean%20operators + * @link http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Escaping%20Special%20Characters + * + * @param string $term Query term to replace and escape + * + * @return string Replaced and escaped query term + */ + public static function replaceBooleanWordsAndEscapeTerm($term) + { + $result = $term; + $result = self::replaceBooleanWords($result); + $result = self::escapeTerm($result); + + return $result; + } + + /** + * Escapes the following terms (because part of the query language) + * + - && || ! ( ) { } [ ] ^ " ~ * ? : \ < >. + * + * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#_reserved_characters + * + * @param string $term Query term to escape + * + * @return string Escaped query term + */ + public static function escapeTerm($term) + { + $result = $term; + // \ escaping has to be first, otherwise escaped later once again + $chars = array('\\', '+', '-', '&&', '||', '!', '(', ')', '{', '}', '[', ']', '^', '"', '~', '*', '?', ':', '/', '<', '>'); + + foreach ($chars as $char) { + $result = str_replace($char, '\\'.$char, $result); + } + + return $result; + } + + /** + * Replace the following reserved words (because part of the query language) + * AND OR NOT. + * + * @link http://lucene.apache.org/java/2_4_0/queryparsersyntax.html#Boolean%20operators + * + * @param string $term Query term to replace + * + * @return string Replaced query term + */ + public static function replaceBooleanWords($term) + { + $replacementMap = array(' AND ' => ' && ', ' OR ' => ' || ', ' NOT ' => ' !'); + $result = strtr($term, $replacementMap); + + return $result; + } + + /** + * Converts a snake_case string to CamelCase. + * + * For example: hello_world to HelloWorld + * + * @param string $string snake_case string + * + * @return string CamelCase string + */ + public static function toCamelCase($string) + { + return str_replace(' ', '', ucwords(str_replace('_', ' ', $string))); + } + + /** + * Converts a CamelCase string to snake_case. + * + * For Example HelloWorld to hello_world + * + * @param string $string CamelCase String to Convert + * + * @return string SnakeCase string + */ + public static function toSnakeCase($string) + { + $string = preg_replace('/([A-Z])/', '_$1', $string); + + return strtolower(substr($string, 1)); + } + + /** + * Converts given time to format: 1995-12-31T23:59:59Z. + * + * This is the lucene date format + * + * @param int $date Date input (could be string etc.) -> must be supported by strtotime + * + * @return string Converted date string + */ + public static function convertDate($date) + { + if (is_int($date)) { + $timestamp = $date; + } else { + $timestamp = strtotime($date); + } + $string = date('Y-m-d\TH:i:s\Z', $timestamp); + + return $string; + } + + /** + * Convert a \DateTime object to format: 1995-12-31T23:59:59Z+02:00. + * + * Converts it to the lucene format, including the appropriate TimeZone + * + * @param \DateTime $dateTime + * @param bool $includeTimezone + * + * @return string + */ + public static function convertDateTimeObject(\DateTime $dateTime, $includeTimezone = true) + { + $formatString = 'Y-m-d\TH:i:s'.($includeTimezone === true ? 'P' : '\Z'); + $string = $dateTime->format($formatString); + + return $string; + } + + /** + * Tries to guess the name of the param, based on its class + * Example: \Elastica\Filter\HasChildFilter => has_child. + * + * @param string|object Class or Class name + * + * @return string parameter name + */ + public static function getParamName($class) + { + if (is_object($class)) { + $class = get_class($class); + } + + $parts = explode('\\', $class); + $last = array_pop($parts); + $last = preg_replace('/(Facet|Query|Filter)$/', '', $last); + $name = self::toSnakeCase($last); + + return $name; + } + + /** + * Converts Request to Curl console command. + * + * @param Request $request + * + * @return string + */ + public static function convertRequestToCurlCommand(Request $request) + { + $message = 'curl -X'.strtoupper($request->getMethod()).' '; + $message .= '\'http://'.$request->getConnection()->getHost().':'.$request->getConnection()->getPort().'/'; + $message .= $request->getPath(); + + $query = $request->getQuery(); + if (!empty($query)) { + $message .= '?'.http_build_query($query); + } + + $message .= '\''; + + $data = $request->getData(); + if (!empty($data)) { + $message .= ' -d \''.JSON::stringify($data).'\''; + } + + return $message; + } +} |