summaryrefslogtreecommitdiff
path: root/vendor/ruflin/elastica
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2016-05-01 15:32:59 -0400
committerLuke Shumaker <lukeshu@sbcglobal.net>2016-05-01 15:32:59 -0400
commit6dc1997577fab2c366781fd7048144935afa0012 (patch)
tree8918d28c7ab4342f0738985e37af1dfc42d0e93a /vendor/ruflin/elastica
parent150f94f051128f367bc89f6b7e5f57eb2a69fc62 (diff)
parentfa89acd685cb09cdbe1c64cbb721ec64975bbbc1 (diff)
Merge commit 'fa89acd'
# Conflicts: # .gitignore # extensions/ArchInterWiki.sql
Diffstat (limited to 'vendor/ruflin/elastica')
-rw-r--r--vendor/ruflin/elastica/CHANGELOG.md1038
-rw-r--r--vendor/ruflin/elastica/CONTRIBUTING.md75
-rw-r--r--vendor/ruflin/elastica/Dockerfile58
-rw-r--r--vendor/ruflin/elastica/LICENSE.txt21
-rw-r--r--vendor/ruflin/elastica/Makefile108
-rw-r--r--vendor/ruflin/elastica/README.md31
-rw-r--r--vendor/ruflin/elastica/Vagrantfile18
-rw-r--r--vendor/ruflin/elastica/ansible/es-playbook.yml20
-rwxr-xr-xvendor/ruflin/elastica/ansible/provision.sh63
-rw-r--r--vendor/ruflin/elastica/ansible/roles/base/tasks/main.yml13
-rw-r--r--vendor/ruflin/elastica/ansible/roles/elasticsearch/handlers/main.yml6
-rw-r--r--vendor/ruflin/elastica/ansible/roles/elasticsearch/tasks/main.yml101
-rw-r--r--vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-0.yml10
-rw-r--r--vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-1.yml10
-rw-r--r--vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-default.yml40
-rwxr-xr-xvendor/ruflin/elastica/ansible/roles/elasticsearch/templates/elasticsearch.service229
-rw-r--r--vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/logging.yml56
-rw-r--r--vendor/ruflin/elastica/ansible/roles/nginx/handlers/main.yml6
-rw-r--r--vendor/ruflin/elastica/ansible/roles/nginx/tasks/main.yml26
-rw-r--r--vendor/ruflin/elastica/ansible/roles/nginx/templates/mime.types.j2109
-rw-r--r--vendor/ruflin/elastica/ansible/roles/nginx/templates/nginx.conf.j235
-rw-r--r--vendor/ruflin/elastica/ansible/roles/php/tasks/main.yml43
-rw-r--r--vendor/ruflin/elastica/composer.json43
-rw-r--r--vendor/ruflin/elastica/docker-compose.yml27
-rw-r--r--vendor/ruflin/elastica/env/elasticsearch/Dockerfile26
-rw-r--r--vendor/ruflin/elastica/env/elasticsearch/elasticsearch.yml39
-rw-r--r--vendor/ruflin/elastica/env/elasticsearch/logging.yml56
-rw-r--r--vendor/ruflin/elastica/env/nginx/mime.types109
-rw-r--r--vendor/ruflin/elastica/env/nginx/nginx.conf38
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/AbstractUpdateAction.php568
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractAggregation.php97
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractSimpleAggregation.php37
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/AbstractTermsAggregation.php97
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Avg.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Cardinality.php38
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/DateHistogram.php130
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/DateRange.php22
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/ExtendedStats.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Filter.php53
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Filters.php59
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/GeoDistance.php104
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/GeohashGrid.php68
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/GlobalAggregation.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Histogram.php59
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/IpRange.php72
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Max.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Min.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Missing.php32
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Nested.php32
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Percentiles.php59
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Range.php58
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/ReverseNested.php49
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/ScriptedMetric.php82
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/SignificantTerms.php27
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Stats.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Sum.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/Terms.php23
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/TopHits.php156
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Aggregation/ValueCount.php32
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk.php442
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/Action.php228
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/Action/AbstractDocument.php166
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/Action/CreateDocument.php10
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/Action/DeleteDocument.php33
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/Action/IndexDocument.php53
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/Action/UpdateDocument.php65
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/Response.php46
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Bulk/ResponseSet.php141
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Client.php719
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Cluster.php192
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Cluster/Health.php185
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Index.php137
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Cluster/Health/Shard.php102
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Cluster/Settings.php202
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Connection.php320
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Connection/ConnectionPool.php122
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/CallbackStrategy.php51
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/RoundRobin.php24
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/Simple.php30
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyFactory.php45
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Connection/Strategy/StrategyInterface.php17
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Document.php356
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/Response/ActionException.php65
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/ResponseException.php98
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/Bulk/UdpException.php8
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/BulkException.php6
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/ClientException.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/Connection/GuzzleException.php50
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/Connection/HttpException.php86
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/Connection/MemcacheException.php13
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/Connection/ThriftException.php49
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/ConnectionException.php58
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/ElasticsearchException.php91
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/ExceptionInterface.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/InvalidException.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/JSONParseException.php9
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/NotFoundException.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/NotImplementedException.php13
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/PartialShardFailureException.php28
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/QueryBuilderException.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/ResponseException.php70
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Exception/RuntimeException.php11
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/AbstractFacet.php145
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/DateHistogram.php58
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/Filter.php27
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/GeoCluster.php66
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/GeoDistance.php69
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/Histogram.php96
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/Query.php27
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/Range.php143
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/Statistical.php64
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/Terms.php137
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Facet/TermsStats.php107
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/AbstractFilter.php59
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoDistance.php198
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/AbstractGeoShape.php52
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/AbstractMulti.php89
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Bool.php15
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/BoolAnd.php20
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/BoolFilter.php133
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/BoolNot.php42
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/BoolOr.php20
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Exists.php34
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/GeoBoundingBox.php49
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistance.php76
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/GeoDistanceRange.php103
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/GeoPolygon.php56
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapePreIndexed.php84
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/GeoShapeProvided.php73
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/GeohashCell.php47
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/HasChild.php95
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/HasParent.php69
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Ids.php94
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Indices.php78
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Limit.php34
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/MatchAll.php20
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Missing.php60
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Nested.php62
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/NumericRange.php13
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Prefix.php80
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Query.php91
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Range.php73
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Regexp.php112
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Script.php47
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Term.php47
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Terms.php149
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Filter/Type.php59
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Index.php515
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Index/Settings.php366
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Index/Stats.php108
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Index/Status.php150
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/JSON.php67
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Log.php81
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Multi/ResultSet.php205
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Multi/Search.php203
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Node.php161
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Node/Info.php220
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Node/Stats.php113
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Param.php167
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Percolator.php194
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query.php488
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/AbstractQuery.php13
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Bool.php15
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/BoolQuery.php111
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Boosting.php50
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Builder.php935
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Common.php172
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/ConstantScore.php70
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/DisMax.php62
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Filtered.php97
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/FunctionScore.php260
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Fuzzy.php87
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/FuzzyLikeThis.php217
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/HasChild.php65
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/HasParent.php63
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Ids.php121
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Image.php187
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Match.php222
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/MatchAll.php20
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrase.php13
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/MatchPhrasePrefix.php13
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/MoreLikeThis.php198
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/MultiMatch.php191
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Nested.php48
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Prefix.php47
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/QueryString.php282
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Range.php38
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Regexp.php40
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Simple.php54
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/SimpleQueryString.php83
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Term.php49
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Terms.php107
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/TopChildren.php53
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Query/Wildcard.php40
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder.php114
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL.php22
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Aggregation.php470
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Filter.php480
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Query.php586
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/DSL/Suggest.php83
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Facade.php64
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version.php101
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version090.php97
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version100.php123
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version110.php131
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version120.php137
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version130.php142
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version140.php145
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/QueryBuilder/Version/Version150.php14
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Request.php204
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Rescore/AbstractRescore.php36
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Rescore/Query.php91
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Response.php308
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Result.php217
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/ResultSet.php433
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/ScanAndScroll.php80
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Script.php163
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/ScriptFields.php65
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Scroll.php174
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Search.php553
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/SearchableInterface.php52
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Snapshot.php176
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Status.php177
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Suggest.php65
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Suggest/AbstractSuggest.php97
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/AbstractCandidateGenerator.php8
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Suggest/CandidateGenerator/DirectGenerator.php140
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Suggest/Completion.php26
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Suggest/Phrase.php164
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Suggest/Term.php129
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Tool/CrossIndex.php160
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/AbstractTransport.php113
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/Guzzle.php179
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/Http.php190
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/HttpAdapter.php156
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/Https.php27
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/Memcache.php109
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/Null.php13
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/NullTransport.php46
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Transport/Thrift.php176
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Type.php572
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Type/AbstractType.php205
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Type/Mapping.php297
-rw-r--r--vendor/ruflin/elastica/lib/Elastica/Util.php194
-rw-r--r--vendor/ruflin/elastica/phpdoc.dist.xml13
-rw-r--r--vendor/ruflin/elastica/test/bootstrap.php5
-rw-r--r--vendor/ruflin/elastica/test/data/test.docbin0 -> 22016 bytes
-rw-r--r--vendor/ruflin/elastica/test/data/test.docxbin0 -> 25890 bytes
-rw-r--r--vendor/ruflin/elastica/test/data/test.jpgbin0 -> 4459 bytes
-rw-r--r--vendor/ruflin/elastica/test/data/test.pdfbin0 -> 16107 bytes
-rw-r--r--vendor/ruflin/elastica/test/data/test.txt1
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/AvgTest.php39
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/BaseAggregationTest.php8
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/CardinalityTest.php132
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateHistogramTest.php103
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateRangeTest.php52
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ExtendedStatsTest.php45
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FilterTest.php113
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FiltersTest.php120
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeoDistanceTest.php46
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeohashGridTest.php46
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GlobalAggregationTest.php27
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/HistogramTest.php47
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/IpRangeTest.php57
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MaxTest.php79
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MinTest.php40
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MissingTest.php39
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/NestedTest.php63
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/PercentilesTest.php125
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/RangeTest.php78
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php134
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptTest.php87
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptedMetricTest.php50
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SignificantTermsTest.php72
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/StatsTest.php44
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SumTest.php40
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TermsTest.php41
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TopHitsTest.php385
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ValueCountTest.php40
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Base.php142
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ActionTest.php66
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ResponseSetTest.php200
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/BulkTest.php792
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ClientTest.php1160
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/IndexTest.php144
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/ShardTest.php85
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/HealthTest.php147
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/SettingsTest.php117
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ClusterTest.php83
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/ConnectionPoolTest.php112
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTest.php97
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTestHelper.php20
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/EmptyStrategy.php17
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/RoundRobinTest.php128
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/SimpleTest.php113
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/StrategyFactoryTest.php84
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ConnectionTest.php121
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/DocumentTest.php349
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ExampleTest.php61
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/AbstractExceptionTest.php31
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/Response/ActionExceptionTest.php8
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/ResponseExceptionTest.php8
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/UdpExceptionTest.php8
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/BulkExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ClientExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/GuzzleExceptionTest.php14
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/HttpExceptionTest.php8
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/MemcacheExceptionTest.php8
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/ThriftExceptionTest.php14
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ConnectionExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ElasticsearchExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/InvalidExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/JSONParseExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotFoundExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotImplementedExceptionTest.php19
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/PartialShardFailureExceptionTest.php54
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/QueryBuilderExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ResponseExceptionTest.php65
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/RuntimeExceptionTest.php6
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/DateHistogramTest.php106
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/FilterTest.php42
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/GeoClusterTest.php57
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/QueryTest.php42
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/StatisticalTest.php82
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsStatsTest.php113
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsTest.php74
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/AbstractTest.php81
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolAndTest.php86
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolFilterTest.php200
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolNotTest.php27
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolOrTest.php90
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ExistsTest.php36
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoBoundingBoxTest.php55
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceRangeTest.php220
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceTest.php141
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoPolygonTest.php65
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapePreIndexedTest.php102
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapeProvidedTest.php103
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeohashCellTest.php68
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasChildTest.php213
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasParentTest.php153
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IdsTest.php244
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IndicesTest.php125
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/LimitTest.php34
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MatchAllTest.php20
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MissingTest.php78
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MultiTest.php109
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedFilterWithSetFilterTest.php110
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedTest.php127
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NumericRangeTest.php37
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/PrefixTest.php138
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/QueryTest.php51
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RangeTest.php61
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RegexpTest.php162
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ScriptTest.php57
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermTest.php24
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermsTest.php129
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TypeTest.php32
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Index/SettingsTest.php338
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatsTest.php24
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatusTest.php74
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/IndexTest.php901
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/LogTest.php196
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Multi/SearchTest.php575
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Node/InfoTest.php79
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/NodeTest.php75
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ParamTest.php115
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/PercolatorTest.php328
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoolQueryTest.php171
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoostingTest.php89
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BuilderTest.php273
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/CommonTest.php63
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ConstantScoreTest.php162
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/DisMaxTest.php84
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/EscapeStringTest.php36
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FilteredTest.php124
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FunctionScoreTest.php324
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyLikeThisTest.php300
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyTest.php136
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasChildTest.php117
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasParentTest.php108
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HighlightTest.php48
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/IdsTest.php187
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ImageTest.php159
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchAllTest.php49
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchTest.php339
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MoreLikeThisTest.php240
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MultiMatchTest.php214
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/NestedTest.php30
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PostFilterTest.php64
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PrefixTest.php27
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/QueryStringTest.php189
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RangeTest.php79
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RegexpTest.php31
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RescoreTest.php236
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleQueryStringTest.php103
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleTest.php19
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermTest.php27
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermsTest.php65
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Query/WildcardTest.php106
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AbstractDSLTest.php97
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AggregationTest.php58
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/FilterTest.php58
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/QueryTest.php85
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/SuggestTest.php32
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/VersionTest.php67
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilderTest.php88
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/QueryTest.php458
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/RequestTest.php95
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ResponseTest.php205
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ResultSetTest.php95
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ResultTest.php131
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ScanAndScrollTest.php78
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptFieldsTest.php93
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptTest.php169
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ScrollTest.php105
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/SearchTest.php647
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/ShutdownTest.php74
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/SnapshotTest.php109
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/StatusTest.php133
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/CompletionTest.php140
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/PhraseTest.php82
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/TermTest.php105
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Tool/CrossIndexTest.php135
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/AbstractTransportTest.php80
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/GuzzleTest.php180
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/HttpTest.php246
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/MemcacheTest.php176
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/NullTransportTest.php96
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/ThriftTest.php135
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/TransportBenchmarkTest.php261
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/Type/MappingTest.php331
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/TypeTest.php968
-rw-r--r--vendor/ruflin/elastica/test/lib/Elastica/Test/UtilTest.php139
-rw-r--r--vendor/ruflin/elastica/test/phpunit.xhprof.xml39
-rw-r--r--vendor/ruflin/elastica/test/phpunit.xml.dist27
436 files changed, 50833 insertions, 0 deletions
diff --git a/vendor/ruflin/elastica/CHANGELOG.md b/vendor/ruflin/elastica/CHANGELOG.md
new file mode 100644
index 00000000..1ea98234
--- /dev/null
+++ b/vendor/ruflin/elastica/CHANGELOG.md
@@ -0,0 +1,1038 @@
+# Change Log
+All notable changes to this project will be documented in this file based on the [Keep a Changelog](http://keepachangelog.com/) Standard. This project adheres to [Semantic Versioning](http://semver.org/).
+
+## [Unreleased](https://github.com/ruflin/Elastica/compare/2.2.0...HEAD)
+
+### Backward Compatibility Breaks
+
+### Bugfixes
+
+### Added
+
+### Improvements
+
+### Deprecated
+
+
+## [2.2.0](https://github.com/ruflin/Elastica/releases/tag/2.2.0) - 2015-07-08
+
+
+### Backward Compatibility Breaks
+- Usage of constant DEBUG and method Elastica\Util::debugEnabled is removed. [#868](https://github.com/ruflin/Elastica/pull/868)
+- Elastica\Response::getTransferInfo will not return "request_header" by default. [#868](https://github.com/ruflin/Elastica/pull/868)
+- The Image Plugin is currently not compatible with Elasticearch 1.6.0
+
+### Bugfixes
+- Fixed segmentation fault in PHP7 [#868](https://github.com/ruflin/Elastica/pull/868)
+- Removed deprecation for Elastica\Type::deleteByQuery [#875](https://github.com/ruflin/Elastica/pull/875)
+
+### Improvements
+- `CallbackStrategy` now will accept any `callable` as callback, not only instance of `Closure`. [#871](https://github.com/ruflin/Elastica/pull/871)
+- `StrategyFactory` now will try to find predefined strategy before looking to global namespace. [#877](https://github.com/ruflin/Elastica/pull/877)
+- Update elasticsearch dependency to elasticsearch 1.6.0 https://www.elastic.co/downloads/past-releases/elasticsearch-1-6-0
+- All elasticsearch plugin dependencies were updated to the newest version.
+- Methods of classes in `QueryBuilder\DSL` namespace now have exact same signatures as corresponding constructors. [#878](https://github.com/ruflin/Elastica/pull/878)
+- Constructor of `Aggregation\Filter` now accepts filter as second parameter [#878](https://github.com/ruflin/Elastica/pull/878)
+- Constructor of `Filter\AbstractMulti` (`BoolAnd`, `BooldOr`) now accepts array of filters as parameter [#878](https://github.com/ruflin/Elastica/pull/878)
+- Constructor of `Query\Match` now accepts arguments [#878](https://github.com/ruflin/Elastica/pull/878)
+- Coverage Reporting improved with Codecov [#888](https://github.com/ruflin/Elastica/pull/888)
+- Added 'query_cache' option for search [#886](https://github.com/ruflin/Elastica/pull/886)
+
+## [2.1.0](https://github.com/ruflin/Elastica/releases/tag/2.1.0) - 2015-06-01
+
+### Added
+- Multiple rescore query [#820](https://github.com/ruflin/Elastica/issues/820/)
+- Support for a custom connection timeout through a connectTimeout parameter. [#841](https://github.com/ruflin/Elastica/issues/841/)
+- SignificantTerms Aggregation [#847](https://github.com/ruflin/Elastica/issues/847/)
+- Support for 'precision_threshold' and 'rehash' options for the Cardinality Aggregation [#851]
+- Support for retrieving id node #852
+- Scroll Iterator [#842](https://github.com/ruflin/Elastica/issues/842/)
+- Gitter Elastica Chat Room add for Elastica discussions: https://gitter.im/ruflin/Elastica
+- Introduce PHP7 compatibility and tests. #837
+- `Tool\CrossIndex` for reindexing and copying data and mapping between indices [#853](https://github.com/ruflin/Elastica/pull/853)
+- CONTIRUBTING.md file added for contributor guidelines. #854
+
+### Improvements
+- Introduction of Changelog standard based on http://keepachangelog.com/. changes.txt moved to CHANGELOG.md [#844](https://github.com/ruflin/Elastica/issues/844/)
+- Make host for all tests dynamic to prepare it for a more dynamic test environment #846
+- Node information is retrieved based on id instead of name as multiple nodes can have the same name. #852
+- Guzzle Http dependency updated to 5.3.*
+- Remove NO_DEV builds from travis build matrix to speed up building. All builds include no dev packages.
+- Introduction of benchmark test group to make it easy to run benchmark tests.
+- Make the docker images directly [available](https://hub.docker.com/u/ruflin/) on the docker registry. This speeds up fetching of the images and automates the build of the images.
+
+### Backward Compatibility Breaks
+- `Elastica\ScanAndScroll::$_lastScrollId` removed: `key()` now always returns the next scroll id [#842](https://github.com/ruflin/Elastica/issues/842/)
+
+
+### Deprecated
+- Facets are deprecated. You are encouraged to migrate to aggregations instead. [#855](https://github.com/ruflin/Elastica/pull/855/)
+- Elastica\Query\Builder is deprecated. Use new Elastica\QueryBuilder instead. [#855](https://github.com/ruflin/Elastica/pull/855/)
+- For PHP 7 compatibility Elastica\Query\Bool was renamed to *\BoolQuery, Elastica\Filter\Bool was renamed to BoolFilter, Elastica\Transport\Null was renamed to NullTransport as Null and Bool are reserved phrases in PHP 7. Proxy objects for all three exist to keep backward compatibility. It is recommended to start using the new objects as the proxy classes will be deprecated as soon as PHP 7 is stable. #837
+
+
+
+## [2.0.0](https://github.com/ruflin/Elastica/releases/tag/2.0.0) - 2015-05-11
+
+
+### Backward Compatibility Breaks
+- Elastica\Query\QueryString::setLowercaseExpandedTerms removed [#813](https://github.com/ruflin/Elastica/issues/813/)
+- Update elasticsearch dependency to elasticsearch 1.5.2 https://www.elastic.co/downloads/past-releases/elasticsearch-1-5-2 [#834](https://github.com/ruflin/Elastica/issues/834/)
+- Added deprecation notice to Elastica\Transport\Thrift, Elastica\Transport\Memcached and Elastica\Type::deleteByQuery [#817](https://github.com/ruflin/Elastica/issues/817/)
+- Escape new symbols in Util::escapeTerm [#795](https://github.com/ruflin/Elastica/issues/795/)
+
+### Bugfixes
+- Fix empty bool query to act as match all query [#817](https://github.com/ruflin/Elastica/issues/817/)
+- Fixed short match construction in query DSL [#796](https://github.com/ruflin/Elastica/issues/796/)
+- Index optimize method to return Response object. [#797](https://github.com/ruflin/Elastica/issues/797/)
+- Fix fluent interface inconsistency [#788](https://github.com/ruflin/Elastica/issues/788/)
+
+
+### Improvements
+- Add testing on PHP 7 on Travis [#826](https://github.com/ruflin/Elastica/issues/826/)
+- Allow bool in Query::setSource function [#818](https://github.com/ruflin/Elastica/issues/818/) http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
+- deleteByQuery() implemented in Elastica\Index [#816](https://github.com/ruflin/Elastica/issues/816/)
+- Add MLT query against documents [#814](https://github.com/ruflin/Elastica/issues/814/)
+- Added Elastica\Query\SimpleQueryString::setMinimumShouldMatch [#813](https://github.com/ruflin/Elastica/issues/813/)
+- Added Elastica\Query\FunctionScore::setMinScore [#813](https://github.com/ruflin/Elastica/issues/813/)
+- Added Elastica\Query\MoreLikeThis::setMinimumShouldMatch [#813](https://github.com/ruflin/Elastica/issues/813/)
+- Added new methods to Elastica\Aggregation\DateHistogram: setOffset, setTimezone [#813](https://github.com/ruflin/Elastica/issues/813/)
+- Following methods in Elastica\Aggregation\DateHistogram marked as deprecated: setPreOffset, setPostOffset, setPreZone, setPostZone, setPreZoneAdjustLargeInterval [#813](https://github.com/ruflin/Elastica/issues/813/)
+- Add Elastica\Facet\DateHistogram::setFactor() [#806](https://github.com/ruflin/Elastica/issues/806/)
+- Added Elastica\Query\QueryString::setTimezone [#813](https://github.com/ruflin/Elastica/issues/813/)
+- Add .editorconfig [#807](https://github.com/ruflin/Elastica/issues/807/)
+- Added Elastica\Suggest\Completion [#808](https://github.com/ruflin/Elastica/issues/808/)
+- Fix elasticsearch links to elastic domain [#809](https://github.com/ruflin/Elastica/issues/809/)
+- Added Elastica\Query\Image [#787](https://github.com/ruflin/Elastica/issues/787/)
+- Add Scrutinizer Code Quality status badge
+- Added support for percentiles aggregation [#786](https://github.com/ruflin/Elastica/issues/786/)
+
+
+
+## Changelog before 2.0.0
+The changelog before version 2.0.0 was organised by date. All changes can be found below.
+
+2015-02-17
+- Release v1.4.3.0
+- Added Elastica\Query\MatchPhrase [#599](https://github.com/ruflin/Elastica/issues/599/)
+- Added Elastica\Query\MatchPhrasePrefix [#599](https://github.com/ruflin/Elastica/issues/599/)
+
+2015-02-04
+- Reset PHP 5.3 tests and enable compatibility for PHP 5.3 again
+
+2015-02-16
+- Update elasticsearch compatibility to 1.4.3 [#782](https://github.com/ruflin/Elastica/issues/782/)
+- Add support for scripted metric aggrations [#780](https://github.com/ruflin/Elastica/issues/780/)
+
+2015-02-14
+- Added availability to specify regexp options in \Elastica\Filters\Regexp [#583](https://github.com/ruflin/Elastica/issues/583/) [#777](https://github.com/ruflin/Elastica/issues/777/)
+- Add HHVM as build in travis [#649](https://github.com/ruflin/Elastica/issues/649/)
+
+2015-02-11
+- Fixed issue with OutOfMemory exception in travis builds [#775](https://github.com/ruflin/Elastica/issues/775/)
+- Add support for filters aggregation [#773](https://github.com/ruflin/Elastica/issues/773/)
+
+2015-01-27
+- Housekeeping, coding standard [#764](https://github.com/ruflin/Elastica/issues/764/)
+- Exception\ElasticsearchException now can be catched like all other exceptions as Exception\ExceptionInterface [#762](https://github.com/ruflin/Elastica/issues/762/)
+
+2015-01-25
+- Release v1.4.2.0
+
+2015-01-23
+- Added Elastica\Query\Regexp [#757](https://github.com/ruflin/Elastica/issues/757/)
+
+2015-01-19
+- Update to elasticsearch 1.4.2 [#378](https://github.com/ruflin/Elastica/issues/378/)
+- Remove support for PHP 5.3
+
+2015-01-14
+- added @return annotation to top_hits aggregation DSL method [#752](https://github.com/ruflin/Elastica/issues/752/)
+
+2015-01-07
+- Added Elastica\Aggregation\TopHits [#718](https://github.com/ruflin/Elastica/issues/718/)
+
+2015-01-05
+- Vagrantfile updated [#742](https://github.com/ruflin/Elastica/issues/742/)
+- Plugins updated to ES 1.3.4
+- Since new version of thrift plugin is compatible with ES 1.3.4, plugin added back to test environment
+
+2014-12-30
+- Added: Filter\Range::setExecution, Filter\Terms::setExecution, Filter\Missing::setExistence, Filter\Missing::setNullValue, Filter\HasChild::setMinumumChildrenCount, Filter\HasChild::Filter\HasChild::setMaximumChildrenCount, Filter\Indices::addIndex
+- Filter\HasChild::setType, Filter\HasParent::setType now support Type instance as argument
+- Filter\Indices::setIndices, Filter\Indices::addIndex now support Index instance as argument
+- (BC break) Removed as added by mistake: Filter\HasChild::setScope, Filter\HasParent::setScope, Filter\Nested::setScoreMode, Filter\Bool::setBoost
+
+2014-12-23
+- Additional Request Body Options for Percolator [#737](https://github.com/ruflin/Elastica/issues/737/)
+
+2014-12-19
+- making sure id is urlencoded when using updateDocument [#734](https://github.com/ruflin/Elastica/issues/734/)
+- Implement the `weight` in the function score query [#735](https://github.com/ruflin/Elastica/issues/735/)
+
+2014-12-09
+- Changed setRealWorldErrorLikelihood to setRealWordErrorLikelihood [#729](https://github.com/ruflin/Elastica/issues/729/)
+
+2014-11-23
+- allow to customize the key on a range aggregation [#728](https://github.com/ruflin/Elastica/issues/728/)
+
+2014-12-14
+- Added fluent interface to Elastica\Query::setRescore [#733](https://github.com/ruflin/Elastica/issues/733/)
+
+2014-11-30
+- Added transport to support egeloen/http-adapter [#727](https://github.com/ruflin/Elastica/issues/727/)
+
+2014-11-20
+- add cache control parameters support to Elastica\Filter\Bool [#725](https://github.com/ruflin/Elastica/issues/725/)
+
+2014-11-19
+- Avoid remove previously added params when adding a suggest to the query [#726](https://github.com/ruflin/Elastica/issues/726/)
+
+2014-11-16
+- Added Elastica\QueryBuilder [#724](https://github.com/ruflin/Elastica/issues/724/)
+- Update to elasticsearch 1.4.0
+- Disable official support for PHP 5.3
+
+2014-11-13
+- fixed reserved words in queries which composed of upper case letters (Util::replaceBooleanWords) [#722](https://github.com/ruflin/Elastica/issues/722/)
+
+2014-10-31
+- Adding PSR-4 autoloading support [#714](https://github.com/ruflin/Elastica/issues/714/)
+
+2014-10-29
+- Updated Type::getDocument() exception handling. \Elastica\Exception\ResponseException will be thrown instead of \Elastica\Exception\NotFoundException if the ES response contains any error (i.e: Missing index) (BC break) [#687](https://github.com/ruflin/Elastica/issues/687/)
+
+2014-10-22
+- Added Util::convertDateTimeObject to Util class to easily convert \DateTime objects to required format [#709](https://github.com/ruflin/Elastica/issues/709/)
+
+2014-10-15
+- Remove ResponseException catch in Type::getDocument() [#704](https://github.com/ruflin/Elastica/issues/704/)
+
+2014-10-10
+- Fixed Response::isOk() to work better with bulk update api [#702](https://github.com/ruflin/Elastica/issues/702/)
+- Adding magic __call() [#700](https://github.com/ruflin/Elastica/issues/700/)
+
+2014-10-05
+- ResultSet creation moved to static ResultSet::create() method [#690](https://github.com/ruflin/Elastica/issues/690/)
+- Accept an options array at Type::updateDocument() [#686](https://github.com/ruflin/Elastica/issues/686/)
+- Improve exception handling in Type::getDocument() [#693](https://github.com/ruflin/Elastica/issues/693/)
+
+2014-10-04
+- Release v1.3.4.0
+- Update to elasticsearch 1.3.4 [#691](https://github.com/ruflin/Elastica/issues/691/)
+
+2014-09-22
+- Update the branch alias in composer.json to match the library version [#683](https://github.com/ruflin/Elastica/issues/683/)
+
+2014-09-16
+- Update license in composer.json to match project [#681](https://github.com/ruflin/Elastica/issues/681/)
+
+2014-09-08
+- Delete execution permission from non-executable files [#677](https://github.com/ruflin/Elastica/issues/677/)
+
+2014-08-25
+- Top-level filter parameter in search has been renamed to post_filter [#669](https://github.com/ruflin/Elastica/issues/669/) [#670](https://github.com/ruflin/Elastica/issues/670/)
+- Deprecated: Elastica\Query::setFilter() is deprecated. Use Elastica\Query::setPostFilter() instead. [#669](https://github.com/ruflin/Elastica/issues/669/)
+- Deprecated: Elastica\Query::setPostFilter() passing filter as array is deprecated. Pass instance of AbstractFilter instead. [#669](https://github.com/ruflin/Elastica/issues/669/)
+
+2014-08-22
+- Fixed escaping of / character in Elastica\Util::escapeTerm(), removed usage of JSON_UNESCAPED_SLASHES in Elastica\JSON [#660](https://github.com/ruflin/Elastica/issues/660/)
+
+2014-08-06
+- Add connection pool and connection strategy
+
+2014-07-26
+- Release v1.3.0.0
+- Prepare Elastica Release v1.3.0.0
+
+2014-07-25
+- Update to elasticsearch version 1.3.0 https://www.elastic.co/downloads/past-releases/1-3-0
+
+2014-07-14
+ - Add setQuery() method to Elastica\Query\ConstantScore [#653](https://github.com/ruflin/Elastica/issues/653/)
+
+2014-07-12
+ - Be able to configure ES host/port via ENV var in test env [#652](https://github.com/ruflin/Elastica/issues/652/)
+
+2014-07-07
+ - Fix FunstionScore Query random_score without seed bug. [#647](https://github.com/ruflin/Elastica/issues/647/)
+
+2014-07-02
+- Add setPostFilter method to Elastica\Query (http://www.elastic.co/guide/en/elasticsearch/guide/current/_post_filter.html) [#645](https://github.com/ruflin/Elastica/issues/645/)
+
+2014-06-30
+- Add Reverse Nested aggregation (http://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-reverse-nested-aggregation.html). [#642](https://github.com/ruflin/Elastica/issues/642/)
+
+2014-06-14
+- Release v1.2.1.0
+- Removed the requirement to set arguments filter and/or query in Filtered, according to the documentation: http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html [#616](https://github.com/ruflin/Elastica/issues/616/)
+
+2014-06-13
+- Stop ClientTest->testDeleteIdsIdxStringTypeString from failing 1/3 of the time [#634](https://github.com/ruflin/Elastica/issues/634/)
+- Stop ScanAndScrollTest->testQuerySizeOverride from failing frequently for no reason [#635](https://github.com/ruflin/Elastica/issues/635/)
+- rework Document and Script so they can share some infrastructure allowing scripts to specify things like _retry_on_conflict and _routing [#629](https://github.com/ruflin/Elastica/issues/629/)
+
+2014-06-11
+- Allow bulk API deletes to be routed [#631](https://github.com/ruflin/Elastica/issues/631/)
+
+2014-06-10
+- Update travis to elasticsearch 1.2.1, disable Thrift plugin as not compatible and fix incompatible tests
+
+2014-06-04
+- Implement Boosting Query (http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-boosting-query.html) [#625](https://github.com/ruflin/Elastica/issues/625/)
+
+2014-06-02
+- add retry_on_conflict support to bulk [#623](https://github.com/ruflin/Elastica/issues/623/)
+
+2014-06-01
+- toString updated to consider doc_as_upsert if sent an array source [#622](https://github.com/ruflin/Elastica/issues/622/)
+
+2014-05-27
+- Fix Aggragations/Filter to work with es v1.2.0 [#619](https://github.com/ruflin/Elastica/issues/619/)
+
+2014-05-25
+- Added Guzzle transport as an alternative to the default Http transport [#618](https://github.com/ruflin/Elastica/issues/618/)
+- Added Elastica\ScanAndScroll Iterator (http://www.elastic.co/guide/en/elasticsearch/guide/current/scan-scroll.html) [#617](https://github.com/ruflin/Elastica/issues/617/)
+
+2014-05-13
+- Add JSON compat library; Elasticsearch JSON flags and nicer error handling [#614](https://github.com/ruflin/Elastica/issues/614/)
+
+2014-05-12
+- Update dev builds to phpunit 4.1.*
+
+2014-05-11
+- Set processIsolation and backupGlobals to false to speed up tests. processIsolation was very slow with phpunit 4.0.19.
+
+2014-05-05
+- Fix get settings on alaised index [#608](https://github.com/ruflin/Elastica/issues/608/)
+- Added named function for source filtering [#605](https://github.com/ruflin/Elastica/issues/605/)
+- Scroll type constant to Elastica\Search added [#607](https://github.com/ruflin/Elastica/issues/607/)
+
+2014-04-28
+- Added setAnalyzer method to Query\FuzzyLikeThis Class and fixed issue with params not being merged [#611](https://github.com/ruflin/Elastica/issues/611/)
+- Typo fixes [#600](https://github.com/ruflin/Elastica/issues/600/), [#602](https://github.com/ruflin/Elastica/issues/602/)
+- Remove unreachable return statement [#598](https://github.com/ruflin/Elastica/issues/598/)
+
+2014-04-27
+- Release v1.1.1.1
+- Fix missing use in TermsStats->setOrder() [#597](https://github.com/ruflin/Elastica/issues/597/)
+- Replace all instances of ElasticSearch with Elasticsearch [#597](https://github.com/ruflin/Elastica/issues/597/)
+
+2014-04-24
+- Fixing the Bool filter with Bool filter children bug [#594](https://github.com/ruflin/Elastica/issues/594/)
+
+2014-04-22
+- Remove useless echo in the Memcache Transport object [#595](https://github.com/ruflin/Elastica/issues/595/)
+
+2014-04-21
+- escape \ by \\ [#592](https://github.com/ruflin/Elastica/issues/592/)
+
+2014-04-20
+- Handling of HasChild type parsing bug [#585](https://github.com/ruflin/Elastica/issues/585/)
+- Consolidate Index getMapping tests [#591](https://github.com/ruflin/Elastica/issues/591/)
+- Fix Type::getMapping when using an aliased index [#588](https://github.com/ruflin/Elastica/issues/588/)
+
+2014-04-19
+- Release v1.1.1.0
+- Update to elasticsearch 1.1.1 https://www.elastic.co/downloads/past-releases/1-1-1
+- Remove CustomFiltersScore and CustomScore query as removed in elasticsearch 1.1.0 https://github.com/elasticsearch/elasticsearch/pull/5076/files
+- Update Node Info to use plugins instead of plugin (https://github.com/elasticsearch/elasticsearch/pull/5072)
+- Fix mapping issue for aliases [#588](https://github.com/ruflin/Elastica/issues/588/)
+
+2014-04-17
+- Only trap real JSON parse errors in Response class [#586](https://github.com/ruflin/Elastica/issues/586/)
+
+2014-04-09
+- Added Cardinality aggregation [#581](https://github.com/ruflin/Elastica/issues/581/)
+
+2014-04-07
+- Support for Terms filter lookup options [#579](https://github.com/ruflin/Elastica/issues/579/)
+
+2014-03-29
+- Update to elasticsearch 1.1.0 https://www.elastic.co/downloads/past-releases/1-1-0
+
+2014-03-26
+- Fixed Query\Match Fuzziness parameter type [#576](https://github.com/ruflin/Elastica/issues/576/)
+
+2014-03-24
+- Release v1.0.1.2
+- Added Filter\Indices [#574](https://github.com/ruflin/Elastica/issues/574/)
+
+2014-03-25
+- Allow json string as data srouce for Bulk\Action on update [#575](https://github.com/ruflin/Elastica/issues/575/)
+
+2014-03-20
+- Allow for request params in delete by query calls [#573](https://github.com/ruflin/Elastica/issues/573/)
+
+2014-03-17
+- Added filters: AbstractGeoShape, GeoShapePreIndexed, GeoShapeProvided [#568](https://github.com/ruflin/Elastica/issues/568/)
+
+2014-03-15
+- Percolate existing documents and add percolate options ([#570](https://github.com/ruflin/Elastica/issues/570/))
+
+2014-03-14
+- Added Query\Rescore [#441](https://github.com/ruflin/Elastica/issues/441/)
+
+2014-03-13
+- Added missing query options for MultiMatch (operator, minimum_should_match, zero_terms_query, cutoff_frequency, type, fuzziness, prefix_length, max_expansions, analyzer) [#569](https://github.com/ruflin/Elastica/issues/569/)
+- Added missing query options for Match (zero_terms_query, cutoff_frequency) [#569](https://github.com/ruflin/Elastica/issues/569/)
+
+2014-03-11
+- Fixed request body reuse in http transport [#567](https://github.com/ruflin/Elastica/issues/567/)
+
+2014-03-08
+- Release v1.0.1.1
+- Enable goecluster-facet again as now compatible with elasticsearch 1.0 on travis
+- Run elasticsearch in the background to not have log output in travis build
+- Set memache php version as environment variable
+- Update to memcache 3.0.8 for travis
+
+2014-03-07
+- Add snapshot / restore functionality (Elastica\Snapshot) [#566](https://github.com/ruflin/Elastica/issues/566/)
+
+2014-03-04
+- Add PHP 5.6 to travis test environment
+- Improve performance of Elastica/Status->getIndicesWithAlias and aliasExists on clusters with many indices [#563](https://github.com/ruflin/Elastica/issues/563/)
+
+2014-03-02
+- Release v1.0.1.0
+- Fixed Type->deleteByQuery() not working with Query objects [#554](https://github.com/ruflin/Elastica/issues/554/)
+
+2014-02-27
+- Update to elasticsearch 1.0.1. Update Thrift and Geocluster plugin.
+
+2014-02-25
+- Add JSON_UNESCAPED_UNICODE and JSON_UNESCAPED_SLASHES options in Elastica/Transport/Http, Elastica/Bulk/Action [#559](https://github.com/ruflin/Elastica/issues/559/)
+
+2014-02-20
+- Fixed unregister percolator (still used _percolator instead of .percolator). removed duplicate slash from register percolator route. [#558](https://github.com/ruflin/Elastica/issues/558/)
+
+2014-02-17
+- Throw PartialShardFailureException if response has failed shards
+- Elastica/Aggregations/GlobalAggragation not allowed as sub aggragation [#555](https://github.com/ruflin/Elastica/issues/555/)
+
+2014-02-14
+- Add methods setSize, setShardSize to Elastica/Aggregation/Terms
+- Elastica/Aggregation/GlobalAggregationTest fixed bug where JSON returned [] instead of {}
+- Elastica/ResultSet added method hasAggregations
+
+2014-02-13
+- Moved from Apache License to MIT license
+
+2014-02-12
+- Release v1.0.0.0
+- Updated to elasticsearch 1.0: https://www.elastic.co/blog/1-0-0-released/
+
+2014-02-11
+- Add aggregations
+
+2014-02-08
+- Setting shard timeout doesn't work [#547](https://github.com/ruflin/Elastica/issues/547/)
+
+2014-02-04
+- Remove Elastica\Query\Field and Elastica\Query\Text, which are not supported in ES 1.0.0.RC1
+- Minor tweaking of request and result handling classes to adjust for changes in ES 1.0.0.RC1
+- Update mapper-attachments plugin to version 2.0.0.RC1 in .travis.yml
+- Adjust tests to account for changes in ES 1.0.0.RC1
+- Prevent the geocluster-facet plugin from being installed in test/bin/run_elasticsearch.sh as the plugin has not yet been updated for ES 1.0.0.RC1
+
+2014-01-06
+- Update to elasticsearch v1.0.0.RC2
+
+2014-01-02
+- Added Elastica\Query\DisMax
+- Update to elasticsearch v1.0.0.RC1
+
+2014-01-02
+- Release v0.90.10
+
+2014-01-31
+- Fix _bulk delete proxy methods if type or index not explicitly defined.
+
+2014-01-28
+- Add _bulk delete proxy methods to Index and Type for consistency.
+- Use the HTTP response code of GET requests (getDocument), instead of extists/found json property.
+
+2014-01-22
+- Add getParam & getProperties methods to Elastica\Type\Mapping
+
+2014-01-21
+- Code coverage generation for coveralls.io added: https://coveralls.io/r/ruflin/Elastica
+- Add support for shard timeout to the Bulk api.
+
+2014-01-17
+- Fix typo in constant name: Elastica\Query\FunctionScore::DECAY_GUASS becomes DECAY_GAUSS
+
+2014-01-13
+- Add support for _bulk update
+
+2014-01-14
+- added \Elastica\Exception\ResponseException::getElasticsearchException()
+- Changed logger default log level to debug from info
+
+2014-01-13
+- Update to elasticsearch 0.90.10
+- Add Elastica\Facet\TermsStats::setOrder()
+
+2014-01-08
+- Adding analyze function to Index to expose the _analyze API
+
+2014-01-07
+- Document::setDocAsUpsert() now returns the Document
+
+2013-12-18
+- Update to Elasticsearch 0.90.8
+- Add support for simple_query_string query
+
+2013-12-15
+- Add support for filter inside HasChild filter
+- Add support for filter inside HasParent filter
+
+2013-12-12
+- Always send scroll_id via HTTP body instead of as a query param
+- Fix the manner in which suggestion results are returned in \Elastica\ResultSet and adjust associated tests to account for the fix.
+- Add \Elastica\Resultset::hasSuggests()
+
+2013-12-11
+- Pass arguments to optimize as query
+- Add refreshAll on Client
+
+2013-12-07
+- Added Result::hasFields() and Result::hasParam() methods for consistency with Document
+
+2013-12-07
+- Escape slash in Util::escapeTerm, as it is used for regexp from Elastic 0.90
+
+2013-12-05
+- Add *.iml to .gitignore
+- Refactor suggest implementation (\Elastica\Suggest, \Elastica\Suggest\AbstractSuggest, and \Elastica\Suggest\Term) to more closely resemble query implementation. (BC break)
+- \Elastica\Search::addSuggest() has been renamed to \Elastica\Search::setSuggest()
+- \Elastica\Query::addSuggest() has been renamed to \Elastica\Query::setSuggest()
+- Add \Elastica\Suggest\Phrase, \Elastica\Suggest\CandidateGenerator\AbstractCandidateGenerator, and \Elastica\Suggest\CandidateGenerator\DirectGenerator
+ (see http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-phrase.html)
+
+2013-12-04
+- Remove boost from FunctionScore::addFunction because this is not supported by elasticsearch
+
+2013-12-02
+- Issue [#491](https://github.com/ruflin/Elastica/issues/491/) resolved
+
+2013-12-01
+- Issue [#501](https://github.com/ruflin/Elastica/issues/501/) resolved
+- satooshi/php-coveralls package added for coverall.io
+- Multiple badges for downloads and latest stable release added
+
+2013-11-30
+- Remove facets param from query if is empty array
+- Add size param to API for TermsStats
+
+2013-11-23
+- Release v0.90.7.0
+
+2013-11-19
+- Updated geocluster-facet to 0.0.9
+
+2013-11-18
+- Added \Elastica\Filter\Regexp
+
+2013-11-16
+- Remove wrong documentation for "no limit" [#496](https://github.com/ruflin/Elastica/issues/496/)
+- Update to elasticsearch 0.90.7
+
+2013-11-03
+- Issue [#490](https://github.com/ruflin/Elastica/issues/490/): Set Elastica\Query\FunctionScore::DECAY_EXPONENTIAL to "exp" instead of "exponential"
+
+2013-10-29
+- Elastica_Type::exists() added
+ See http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-types-exists.html#indices-types-exists
+
+2013-10-27
+- Adapted possible values (not only in) for minimum_should_match param based on elasticsearch documetnation http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-minimum-should-match.html
+
+2013-10-27
+- Release v0.90.5.0
+
+2013-10-26
+- Update to elasticsearch 0.90.5
+
+2013-10-21
+- Fix \Elastica\Filter\HasParent usage of \Elastica\Query as to not collide with \Elastica\Filter\Query, bring \Elasitca\Filter\HasChild into line
+
+2013-10-01
+- Also pass the current client object to the failure callback in \Elastica\Client.
+
+2013-09-20
+- Update to geocluster-facet 0.0.8
+- Add support for term suggest API
+ See http://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-term.html
+
+2013-09-18
+- Fix \Elastica\Filter\HasChild usage of \Elastica\Query as to not collide with \Elastica\Filter\Query namespace
+
+2013-09-17
+- Update to elasticsearch 0.90.4
+- Add support for function_score query
+- Skip geocluster-facet test if the plugin is not installed
+- Correct \Elastica\Test\ClientTest to catch the proper exception type on connection failure
+- Fix unit test errors
+
+2013-09-14
+- Nested filter supports now the setFilter method
+
+2013-09-03
+- Support isset() calls on Result objects
+
+2013-08-27
+- Add \ArrayAccess on the ResultSet object
+
+2013-08-25
+- Update to elasticsearch 0.90.3
+
+2013-08-25
+- Release v0.90.2.0
+
+2013-08-20
+- Support for "proxy" param for http connections
+
+2013-08-17
+- Add support for fields parameter in Elastica_Type::getDocument()
+
+2013-08-13
+- Add a getQuery method on the FilteredQuery object
+
+2013-08-01
+- Second param to \Elastica\Search.php:count($query = '', $fullResult = false) added. If second param is set to true, full ResultSet is returned including facets.
+
+2013-07-16
+- Plugin geocluster-facet support added
+
+2013-07-02
+- Add Query\Common
+- Can now create a query by passing an array to Type::search()
+
+2013-07-01
+- Add Filter\GeohashCell
+
+2013-06-30
+- Revamped upsert so that Scripts are now first class citizens. (BC break)
+ See http://elastica.io/migration/0.90.2/upsert.html
+- Implemented doc_as_upsert.
+
+2013-06-29
+- Update to elasticsearch 0.90.2
+- Enabled ES_WAIT_ON_MAPPING_CHANGE for travis builds
+
+2013-06-25
+- Added upsert support when updating a document with a partial document or a script.
+
+2013-06-23
+- Add filtered queries to the percolator API.
+
+2013-06-21
+- Correct class name for TermTest unit test
+- Implement terms lookup feature for terms filter
+
+2013-06-14
+- Fix support for making scroll queries once the scroll has been started.
+
+2013-06-07
+- Release 0.90.1.0
+
+2013-06-05
+- Changed package name to lowercase to prevent potential issues with case sensitive file systems and to refelect the package name from packagist.org.
+ If you are requiring elastica in your project you might want to change the name in the require to lowercase, although it will still work if written in uppercase.
+ The composer autoloader will handle the package correctly and you will not notice any difference.
+ If you are requiring or including a file by hand with require() or include() from the composer vendor folder, pay attention that the package name in
+ the path will change to lowercase.
+- Add Bulk\Action\UpdateDocument.
+- Update Bulk\Action\AbstractDocument and Bulk\Action to enable use of OP_TYPE_UPDATE.
+- Update .travis.yml to use Elasticsearch version 0.9.1, as bulk update is a new feature in 0.9.1.
+
+2013-06-04
+- Elastica\Client::_configureParams() changed to _prepareConnectionParams(), which now takes the config array as an argument
+
+2013-06-03
+- Add getPlugins and hasPlugin methods to Node\Info
+
+2013-05-30
+- Update Index\Status::getAliases() to use new API
+- Update Index\Status::getSettings() to use new API
+
+2013-05-29
+- Add _meta to mapping. [#330](https://github.com/ruflin/Elastica/issues/330/)
+
+2013-05-27
+- Added parameters to implement scroll
+
+2013-05-23
+- add support PSR-3(https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+- Elastica\Log implement LoggerInterface(extends Psr\Log\AbstractLogger)
+ if you want use logging need install https://github.com/php-fig/log for example (composer require psr/log:dev-master)
+ if use Elastica\Log inside Elastica\Client nothing more is needed
+ if use Elastica\Log outside we need use as(https://github.com/php-fig/log) for example Elastica\Log::info($message) or Elastica\Log::log(LogLevel::INFO,$message)
+- Elastica\Client add setLogger for setting custom Logger for example Monolog(https://github.com/Seldaek/monolog)
+
+2013-05-18
+- Elastica\Index::exists fixed for 0.90.0. HEAD request method introduced
+- Elastica\Filter\AbstractMulti::getFilters() added
+- Implement Elastica\Type\Mapping::enableAllField
+- Refresh for Elastica\Index::flush implemented [#316](https://github.com/ruflin/Elastica/issues/316/)
+- Added optional parameter to filter result while percolate [#384](https://github.com/ruflin/Elastica/issues/384/)
+
+2013-05-07
+- Added EXPERIMENTAL DocumentObjectInterface to be used with Type::addObject()/addObjects()
+
+2013-04-23
+- Removed Elastica\Exception\AbstractException
+- All Exceptions now implement Elastica\Exception\ExceptionInterface
+
+2013-04-17
+- Query\Fuzzy to comply with DSL spec. Multi-field queries now throw an exception. Implemented: Query\Fuzzy::setField, Query\Fuzzy::setFieldOption.
+- Query\Fuzzy::addField has been deprecated.
+
+2013-04-12
+- Adding max score information in ResultSet
+- Adding test for the ResultSet class
+
+2013-03-20
+- Removal of unsupported minimum_number_should_match for Boolean Filter
+
+2013-02-25
+- Added Elastica\Bulk class responsible for performing bulk requests. New bulk requests implemented: Client::deleteDocuments(), Bulk::sendUdp()
+
+2013-02-20
+- Release candidate 0.20.5.0.RC1
+
+2013-02-14
+- Added factory for transports that is used by the Connection class
+- The transport instances now has support for parameters that can be injected by specifying an array as a transport when creating the Elastica client
+
+2013-02-08
+- Terms->setScript() Added, namespace Elastica\Facet
+
+2013-01-31
+- Removed deprecated method Type::getType()
+- Removed deprecated old constructor call in Filter\GeoDistance::__construct()
+- Removed deprecated method Filter\Script::setQuery()
+- Removed deprecated methods Query\QueryString::setTieBraker() and Query\QueryString::setQueryString()
+- Removed deprecated methods Query\Builder::minimumShouldMatch() and Query\Builder::tieBreaker()
+
+2013-01-25
+- Add get/set/has/remove methods to Document
+- Add magic methods __get/__set/__isset/__unset to Document
+- Document::add method became deprecated, use set instead
+- Populate document id created by elasticsearch on addDocument()/addDocuments() call if no document id was set
+- Populate updated fields in document on Client::updateDocument() call if fields options is set
+
+2013-01-24
+- Added serialization support. Objects can be added to elastica directly when a serializer callable is configured on \Elastica\Type
+
+2013-01-21
+- Added Thrift transport. Ir requires installing munkie/elasticsearch-thrift-php package and elasticsearch-tranport-thrift plugin should be installed in elastcisearch
+
+2013-01-13
+- Add version option to Elastica_Search::search
+- Remove compatibility for PHP 5.2
+- Changed all syntax using namespaces, in compliance with PSR-2.
+- Usage of composer for lib and test autoloading
+- Added PHPUnit as a dev dependency in composer.json
+- All tests were rewritten for new syntax.
+- All tests where moved in Elastica\Test namespace
+- All tests now inherit from Elastica\Test\Base
+- Removed all executable flags on files where not needed.
+- Update to elasticsearch 0.20.2
+- Refactored Elastica_Script and added it support in Elastica_Query_CustomFiltersScore, Elastica_Query_CustomScore and Elastica_Filter_Script
+- Refactored Elastica_Client::updateDocument() method to support partial document update. $data can be Elastic_Script, Elastic_Document or array.
+- Elastica_Type::updateDocument() now takes Elastica_Document instead of Elastica_Script (BC break). Script can be set to document to perform script update.
+
+2012-12-23
+- Elastica_Client config param "servers" to "connections" renamed. "headers" and "curl" are now a config param inside "connections"
+- Elastica_Connection added to allow connection management (enabled / disable)
+- Refactoring of Elastica_Request. Takes Elastica_Connection in constructor instead of Elastica_Client
+- Elastica_Transport refactored
+- Elastica_Log refactored
+- Renamed Elastica_Exception_Client to Elastica_Exception_Connection
+- Use Elastica_Connection for the following constants: DEFAULT_PORT, DEFAULT_HOST, DEFAULT_TRANSPORT, TIMEOUT
+
+2012-11-28
+- Added Elastica_Filter_GeoDistanceRange filter
+
+2012-11-23
+- Simplified Elastica_Document data handling by extending Elastica_Param
+
+2012-11-10
+- Added Elastica_Cluster_Health, Elastica_Cluster_Health_Index and Elastica_Cluster_Health_Shard which wrap the _cluster/health endpoint.
+- Added Elastica_Document::setId()
+- Added options parameter to Elastica_Type::getDocument()
+- Added Elastica_Query_Filtered::getFilter()
+
+2012-10-30
+- Elastica_Search implement Elastica_Searchable interface
+
+2012-10-28
+- Add Elastica_Filter_HasParent and Elastic_Query_HasParent
+
+2012-08-11
+- Release v0.19.8.0
+- Elastica_Query_Prefix added
+
+2012-07-26
+- Change Elastica_Filter_GeoDistance::__construct(), accepts geohash parameter (BC break, before: ($key, $latitude, $longitude, $distance), after: ($key, $location, $distance) where $location is array('lat' => $latitude, 'lon' => $longitude) or a geohash)
+
+2012-07-17
+- Changed naming for several methods to camelCase
+- Enforced PSR1 code style, as per https://github.com/pmjones/fig-standards/blob/psr-1-style-guide/proposed/PSR-1-basic.md
+- Added Elastica_Script::toArray
+- Added Elastica_ScriptFields
+- Elastica_Query::setScriptFields now takes Elastica_ScriptFields or associative array as argument, the old implementation was bogus.
+
+2012-06-24
+- Simplify Elastica_Type::search and Elastica_Index::search by using Elastica_Search
+- Implement Elastica_Filter_Abstract::setCache and Elastica_Filter_Abstract::setCacheKey
+- Add Elastica_Param::hasParam
+- Remove unsupported use of minimum number should match for Boolean Filter
+- Remove old style path creation through params in Elastica_Index::create and Elastica_Search::search
+
+2012-06-22
+- Add Elastica_Filter_Limit
+- Add getters+setters for Index Setting blocks 'read', 'write' and 'metadata'
+- Add Elastica_Filter_MatchAll
+
+2012-06-20
+- Facet scope added
+
+2012-06-09
+- Change $_parent to null to also support 0 for an id
+- Fix Elasitca_Document->toArray()
+
+2012-05-01
+- Release v0.19.3.0
+- MoreLikeThis Query in Elastica_Document
+- Add query param for request (allows GET params)
+
+2012-03-04
+- Node info call update. The receive os info and more, param is needed. By default, only basics are returned
+- Release v0.19.0.0 which is compatible with ES 0.19.0 https://www.elastic.co/downloads/past-releases/0-19-0
+
+2012-02-21
+- Allow percolate queries in bulk requests
+- Fix memory leak in curl requests
+
+2012-01-23
+- Packagist added http://packagist.org/
+
+2012-01-15
+- Vagrantfile for vagrant environment with elasticsearch added. Run: vagrant up
+
+2012-01-08
+- Allow to set curl params over client config [#106](https://github.com/ruflin/Elastica/issues/106/) [#107](https://github.com/ruflin/Elastica/issues/107/)
+- Add the possiblity to add path or url in config for a request [#120](https://github.com/ruflin/Elastica/issues/120/)
+
+2012-01-04
+- Elastica_Index::exists() and Elastica_Cluster::getIndexNames() added
+
+2012-01-01
+- Elastica_Cluster_Settings added
+- Read only feature for cluster and index added. This feature is elasticsearch >0.19.0 only. ES 0.19.0 release is not out yet
+
+2011-12-29
+- Elastica_Type::deleteByQuery implemented
+
+2011-12-20
+- Release v0.18.6.0
+
+2011-12-19
+- Percolator for Type and Documents added
+
+2011-12-06
+- Elastica_Percolator added. See tests for more details
+
+2011-12-02
+- Rename Elastica_Type::getType() to Elastica_Type::getName(), getType() is now deprecated
+
+2011-12-01
+- Elastica_Filter_Term::addTerm renamed to setTerm, Elastica_Filter_Term::setTerm renamed to setRawTerm
+- Elastica_Query_Term::addTerm renamed to setTerm, Elastica_Query_Term::setTerm renamed to setRawTerm
+
+2011-11-30
+- Release v0.18.5.0
+
+2011-11-28
+- Elastica_Filter_Nested added
+
+2011-11-26
+- Elastica_Search::addIndices(), Elastica_Search::addTypes() added
+
+2011-11-20
+- Release v0.18.4.1
+- Elastica_Log added for logging. Has to be passed as client config to enable
+- Elastica blogging introduced: http://ruflin.com/en/elastica
+
+2011-11-17
+- Release v0.18.4.0
+- Support for Travis CI added: http://travis-ci.org/ruflin/Elastica
+
+2011-11-07
+- Elastica_Index_Stats added
+
+2011-11-05
+- Elastica_Query_Nested added
+
+2011-10-29
+- TTL for document and mapping added
+
+2011-10-28
+- Refactored Elastica_Query_CustomScore::addCSParam to ::addParams
+- Rename Elastica_Query_CustomScore::addParam to ::addCSParam
+- Release v0.18.1.0
+
+2011-10-20
+- Release v0.17.9.0
+- Elastica_Filter_Type added
+
+2011-10-19
+- Elastica_Query_CustomFilterScore added
+
+2011-10-15
+- API Documentation changed to DocBlox
+
+2011-10-10
+- Bug fixing
+- Release v0.17.8.0 added
+
+2011-09-19
+- Release v0.17.7.0 added
+- Release v0.17.6.1 added
+
+2011-09-18
+- Elastica_Exception_ExpectedFieldNotFound renamed to Elastica_Exception_NotFound
+
+2011-08-25
+- Https transport layer added
+
+2011-08-22
+- Typo in Terms query fixed (issue [#74](https://github.com/ruflin/Elastica/issues/74/))
+
+2011-08-15
+- Refactoring HTTP connection to keep alive connection -> speed improvement during using the same client
+- Release v0.17.6.0 added
+
+2011-08-09
+- Automatic creation of id for documents added. This was more a bug
+- Release v0.17.4.0 added
+
+2011-08-08
+- Elastica_Query_Text added
+- Params (constructor) of Elastica_Filter_GeoBoundingBox changed (array instead of single params)
+
+2011-08-07
+- Elastica_Query_MoreLikeThis added by @juneym. Still work under progress
+- Refactoring Queries and Filters to use Elastica_Param. Adding tests
+
+2011-08-05
+- Elastica_Filter_Abstract enhanced for more general usage (set/get/addParam(s)) added
+
+2011-08-04
+- Release v0.17.3.0 added
+- Elastica_Index_Settings::set/get response updated. get('...') does not require 'index.' in front anymore
+- Nodes and Cluster shutdown added
+- Elastica_Node::getIp() and getPort() added
+
+2011-07-30
+- Readd merge_factor to settings. Now working as expected. Index has to be closed first.
+
+2011-07-29
+- Release tag v0.17.2.0 added. Elastica is compatible with elasticsearch 0.17.2
+
+2011-07-22
+- Elastica_Index_Settings::getMergePolicyMergeFactor and set removed because of enhanced merge policy implementation in ES 0.17.0 https://github.com/elasticsearch/elasticsearch/issues/998
+- Release tav v0.17.1.0 added
+
+2011-07-21
+- Elastica_Query_HasChild and _parent feature added by fabian
+- Elastica_Filter_GeoBoundingBox added by fabian
+
+2011-07-20
+- Elastica_Query_Builder added by chrisdegrim
+
+2011-07-19
+- Release tag v0.17.0.0 added. Elastica is compatible with elasticsearch 0.17.0
+
+2011-07-18
+- ResultSet::hasFacets added
+- QueryString useDisMax added
+
+2011-07-15
+- Facet/DateHistogram and Facet/Historgram added
+- Documentation pages added unter http://ruflin.github.com/Elastica
+- Release tag v0.16.4.0 added
+
+2011-06-19
+- Add support for multiple servers to Elastica_Client (issue [#39](https://github.com/ruflin/Elastica/issues/39/))
+
+2011-06-16
+- Support for multiple index, type queries and _all queries added through Elastica_Search object
+- Elastica_Index::clearCache added to clean cache
+- Elastica_Index::flush added
+
+2011-06-07
+- Elastica_Index::setNumberOfShards removed as not supported after creating index
+
+2011-05-11
+- Refactor client constructor. Elastica_Client::__construct(array $config) now takes a config array instead of host and port
+
+2011-05-08
+- Elastica_Query_QueryString::escapeTerm move to Elastica_Util::escapeTerm
+
+2011-04-29
+- Added getParam to Elastica_Result that more values can be retrieved from the hit array
+- Elastica_Filter_Ids added http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-filter.html
+- getMergePolicyMergeFactor and getRefreshInterval to Elastica_Type_Settings added. If no value is set, default values are returned
+
+2011-04-28
+- Release of version 0.16.0.0 (see new version naming structure in README)
+
+2011-04-27
+- Refactoring of Elastica_Type::setMapping. No source parameter anymore.
+- Elastica_Type_Mapping object introduced to set more fine grained mapping
+
+2011-04-17
+- Elastica_Filter_Exists added
+
+2011-04-14
+- Elastica_Type getCount replace by count()
+- Count has now optional query parametere
+
+2011-04-01
+- Renaming of functions in Elastica_Query_Terms and Ela-stica_Query_Filter to fit new naming convention. setTerms, addTerm have different API now!
+
+2011-03-31
+- Deprecated code removed
+- Break backward compatibility to 0.15.1 (versions introduced by wlp1979)
+
+2011-03-30
+- Filtered query introduced
+- setRawArguments in Elastica_Query is now setParam
+- open / close for index added
+- Remove Elastica_Filter and Elastica_Facets because not needed anymore
+
+2011-03-29
+- Renaming Elastica_Filter->addQuery, addFilter to setQuery, setFilter
+- Add parts of Facets API
+- Add facet Terms
+- Renaming Elastica_Query->addFilter to setFilter
+
+2011-03-24
+- Renaming of Elastica_Status_Index to Elastica_Index_Status => API Change!
+- IndexSettings added for improved bulk updating http://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
+
+2011-03-21
+- Node object added
+- Node_Info and Node_Stats added
+- Refactoring of Cluster object
+
+2011-03-13
+- changes.txt introduced
+- getResponse in Elastica_Response renamed to getData. getResponse now deprecated
+- Index status objects added
+- getIndexName in Elastica_Index renamed to getName. getIndexName is deprecated
diff --git a/vendor/ruflin/elastica/CONTRIBUTING.md b/vendor/ruflin/elastica/CONTRIBUTING.md
new file mode 100644
index 00000000..aff25716
--- /dev/null
+++ b/vendor/ruflin/elastica/CONTRIBUTING.md
@@ -0,0 +1,75 @@
+Contributing
+============
+Help is very welcomed. Code contributions must be done in respect of [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md).
+More details on how to contribute and guidelines for [pull requests](http://elastica.io/contribute/pull-request.html) can be found [here](http://elastica.io/contribute/).
+
+See [Coding guidelines](http://elastica.io/contribute/coding-guidelines.html) for tips on how to do so.
+All changes must be documented in the [CHANGELOG.md](https://github.com/ruflin/Elastica/blob/master/CHANGELOG.md).
+
+
+Issues
+------
+* Bugs & Feature requests: If you found a bug, open an issue on [Github](https://github.com/ruflin/Elastica/issues). Please search for already reported similary issues before opening a new one. You should include code examples (with dependencies if needed) and your Elastica version to the issue description.
+* Questions & Problems: If you have questions or a specific problem, use the [Elastica Gitter](https://gitter.im/ruflin/Elastica) Chat or open an issue on [Stackoverflow](http://stackoverflow.com/questions/tagged/elastica). Make sure to assign the tag Elastica.
+
+
+Setup
+-----
+Elastica currently allows two setups for development. Either through vagrant or docker-compose. To use the vagrant environment, run `vagrant up`. To use the docker environment, check out the Makefile for the necessary commands.
+* Run your changes / tests in the virtual environment to make sure it is reproducible.
+* Run the tests before creating the pull request using vagrant or docker-compose locally.
+
+Commands
+--------
+To run the commands below, you must have docker-compose [installed](https://docs.docker.com/compose/install/). The first time the commands are run it takes some time to download all the partial images. Form then on the commands should run very fast. The advantage in using the commands below is that no local tools and libraries have to be installed and it is guaranteed that everytone is using the same tools.
+
+## Run Tests
+
+To run all tests inside the docker environment, run the following command:
+
+```
+make run RUN="make phpunit"
+```
+
+If you want to run just a specific test or a one specific file, run the following command by replacing your file with the existingpath:
+
+```
+ make run RUN="phpunit -c ./test lib/Elastica/Test/SearchTest.php"
+```
+
+## Check style of your code
+This command will call php-cs-fixer with the predefined settings for the elastica project. No local setup of the tools is needed as everything will happen directly in the container.
+```
+make run RUN="make lint"
+```
+
+
+
+
+Coding
+------
+
+### Rules
+* Pull requests are made to master. Changes are never pushed directly (without pull request) into master.
+* We use the Forking Workflow. https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow
+* Follow the coding guidelines.
+* Use a feature branch for every pull request. Don't open a pull request from your master branch.
+
+### Pull Requests
+* One change per pull requests: Keep your pull requests as small as possible. Only one change should happen per pull request. This makes it easier to review and provided feedback. If you have a large pull request, try to split it up in multiple smaller requests.
+* Commit messages: Make sure that your commit messages have meaning and provide an understanding on what was changed without looking at the code.
+* Pull requests should be opened as early as possible as pull requests are also here for communication / discussing changes. Add a comment when your pull request is ready to be merged.
+* Tests: Your addition / change must be tested and the builds must be green. Test your changes locally. Add unit tests and if possible functional tests. Don't forget to add the group to your tests. The 4 available groups are @functional, @unit, @shutdown, @benchmark
+* Update the CHANGELOG.md file with your changes
+* Backward Compatibility breaks: In case you break backward compatibility, provide details on why this is needed.
+* Merge: No one should ever merge his own pull request
+
+
+### Name Spaces & Classes
+Most name spaces and classes are self explanotary and use cases can be taken from classes which already exist.
+
+#### Tool Namespace
+The namespace Tool is used for making more complex functionality of Elastica available to the users. In general it maps existing functionality of Elastica and offers simplified functions.
+
+#### Util Class
+The util class is used for all static functions which are used in the Elastica library but don't access the library itself.
diff --git a/vendor/ruflin/elastica/Dockerfile b/vendor/ruflin/elastica/Dockerfile
new file mode 100644
index 00000000..c5055c5e
--- /dev/null
+++ b/vendor/ruflin/elastica/Dockerfile
@@ -0,0 +1,58 @@
+# PHP 6 Docker file with Composer installed
+FROM composer/composer
+
+RUN apt-get update
+RUN apt-get upgrade -y
+RUN apt-get install -y nano
+RUN apt-get install -y cloc
+
+# XSL and Graphviz for PhpDocumentor
+RUN apt-get install -y php5-xsl
+# TODO: Debian is putting the xsl extension in a different directory, should be in: /usr/local/lib/php/extensions/no-debug-non-zts-20131226
+RUN echo "extension=/usr/lib/php5/20131226/xsl.so" >> /usr/local/etc/php/conf.d/xsl.ini
+RUN apt-get install -y graphviz
+
+
+RUN echo "date.timezone=UTC" >> /usr/local/etc/php/conf.d/timezone.ini
+
+# Xdebug for coverage report
+RUN apt-get install -y php5-xdebug
+RUN echo "zend_extension=/usr/lib/php5/20131226/xdebug.so" >> /usr/local/etc/php/conf.d/xdebug.ini
+
+# Memcache
+RUN apt-get install -y php5-memcache
+RUN echo "extension=/usr/lib/php5/20131226/memcache.so" >> /usr/local/etc/php/conf.d/memcache.ini
+
+# Add composer bin to the environment
+ENV PATH=/root/composer/vendor/bin:$PATH
+
+# Overcome github access limits. GITHUB_OAUTH_TOKEN environment variable must be set with private token
+RUN composer self-update
+
+# Install development tools
+RUN composer global require "phpunit/phpunit=~4.7"
+RUN composer global require "pdepend/pdepend=~2.0"
+RUN composer global require "phpmd/phpmd=~2.2"
+RUN composer global require "mayflower/php-codebrowser=~1.1"
+RUN composer global require "sebastian/phpcpd=~2.0"
+RUN composer global require "squizlabs/php_codesniffer=~2.3"
+RUN composer global require "phploc/phploc=~2.1"
+RUN composer global require "fabpot/php-cs-fixer=1.8.1"
+
+
+# Documentor dependencies
+RUN composer global require "phpdocumentor/template-zend=~1.3"
+RUN composer global require "phpdocumentor/phpdocumentor=~2.8"
+
+# Install depdencies
+WORKDIR /app
+COPY composer.json /app/
+RUN composer install
+
+# Guzzle is not included composer.json because of PHP 5.3
+RUN composer require "guzzlehttp/guzzle=~6.0"
+
+ENTRYPOINT []
+
+ENV ES_HOST elasticsearch
+ENV PROXY_HOST nginx
diff --git a/vendor/ruflin/elastica/LICENSE.txt b/vendor/ruflin/elastica/LICENSE.txt
new file mode 100644
index 00000000..21580de7
--- /dev/null
+++ b/vendor/ruflin/elastica/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Nicolas Ruflin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE. \ No newline at end of file
diff --git a/vendor/ruflin/elastica/Makefile b/vendor/ruflin/elastica/Makefile
new file mode 100644
index 00000000..c033784b
--- /dev/null
+++ b/vendor/ruflin/elastica/Makefile
@@ -0,0 +1,108 @@
+#/bin/bash
+
+BASEDIR = $(shell pwd)
+SOURCE = "${BASEDIR}/lib"
+IMAGE = "elastica"
+
+
+### Setups around project sources. These commands should run ###
+init: prepare
+ composer install
+
+prepare:
+ mkdir -p ${BASEDIR}/build/api
+ mkdir -p ${BASEDIR}/build/code-browser
+ mkdir -p ${BASEDIR}/build/coverage
+ mkdir -p ${BASEDIR}/build/logs
+ mkdir -p ${BASEDIR}/build/docs
+ mkdir -p ${BASEDIR}/build/pdepend
+
+update: init
+
+clean:
+ rm -r -f ${BASEDIR}/build
+ #rm ${BASEDIR}/cache.properties
+
+
+# Handling virtual environment
+
+build:
+ docker-compose build
+
+setup: build
+ docker-compose scale elasticsearch=3
+
+start:
+ docker-compose up
+
+stop:
+ docker-compose stop
+
+destroy: clean
+ docker-compose kill
+ docker-compose rm
+
+# Runs commands inside virtual environemnt. Example usage inside docker: make run RUN="make phpunit"
+run:
+ docker-compose run elastica $(RUN)
+
+
+### Quality checks / development tools ###
+
+checkstyle:
+ phpcs --standard=PSR2 ${SOURCE}
+
+checkstyle-ci: prepare
+ phpcs --report=checkstyle --report-file=${BASEDIR}/build/logs/checkstyle.xml --standard=PSR2 ${SOURCE} > /dev/null
+
+code-browser: prepare
+ phpcb --log ${BASEDIR}/build/logs --source ${SOURCE} --output ${BASEDIR}/build/code-browser
+
+# Copy paste detector
+cpd: prepare
+ phpcpd --log-pmd ${BASEDIR}/build/logs/pmd-cpd.xml ${SOURCE}
+
+messdetector: prepare
+ phpmd ${SOURCE} text codesize,unusedcode,naming,design ${BASEDIR}/build/phpmd.xml
+
+messdetector-ci: prepare
+ phpmd ${SOURCE} xml codesize,unusedcode,naming,design --reportfile ${BASEDIR}/build/logs/pmd.xml
+
+dependencies: prepare
+ pdepend --jdepend-xml=${BASEDIR}/build/logs/jdepend.xml \
+ --jdepend-chart=${BASEDIR}/build/pdepend/dependencies.svg \
+ --overview-pyramid=${BASEDIR}/build/pdepend/overview-pyramid.svg \
+ ${SOURCE}
+
+phpunit: prepare
+ phpunit -c test/ --coverage-clover build/coverage/unit-coverage.xml --group unit
+ phpunit -c test/ --coverage-clover build/coverage/functional-coverage.xml --group functional
+ phpunit -c test/ --coverage-clover build/coverage/shutdown-coverage.xml --group shutdown
+
+doc: prepare
+ phpdoc run -d lib/ -t build/docs
+
+# Uses the preconfigured standards in .php_cs
+lint:
+ php-cs-fixer fix
+
+syntax-check:
+ php -lf ${SOURCE} **/*.php
+ php -lf ${BASEDIR}/test **/*.php
+
+
+loc:
+ cloc --by-file --xml --exclude-dir=build -out=build/cloc.xml .
+
+phploc:
+ phploc --log-csv $(BASEDIR)/build/logs/phploc.csv $(SOURCE)
+
+
+
+# Visualise repo
+gource:
+ gource --log-format git \
+ --seconds-per-day 0.1 \
+ --title 'Elastica (https://github.com/ruflin/Elastica)' \
+ --user-scale 1 \
+ --max-user-speed 50
diff --git a/vendor/ruflin/elastica/README.md b/vendor/ruflin/elastica/README.md
new file mode 100644
index 00000000..b6cf5376
--- /dev/null
+++ b/vendor/ruflin/elastica/README.md
@@ -0,0 +1,31 @@
+Elastica: elasticsearch PHP Client
+==================================
+
+[![Latest Stable Version](https://poser.pugx.org/ruflin/Elastica/v/stable.png)](https://packagist.org/packages/ruflin/elastica)
+[![Build Status](https://secure.travis-ci.org/ruflin/Elastica.png?branch=master)](http://travis-ci.org/ruflin/Elastica)
+[![codecov.io](http://codecov.io/github/ruflin/Elastica/coverage.svg?branch=master)](http://codecov.io/github/ruflin/Elastica?branch=master)
+[![Dependency Status](https://www.versioneye.com/php/ruflin:elastica/dev-master/badge.svg)](https://www.versioneye.com/php/ruflin:elastica/dev-master)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ruflin/Elastica/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/ruflin/Elastica/?branch=master)
+[![Total Downloads](https://poser.pugx.org/ruflin/Elastica/downloads.png)](https://packagist.org/packages/ruflin/elastica)
+[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=ruflin&url=https://github.com/ruflin/Elastica&title=Elastica&language=PHP&tags=github&category=software)
+[![Join the chat at https://gitter.im/ruflin/Elastica](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ruflin/Elastica?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+All documentation for Elastica can be found under [Elastica.io](http://Elastica.io/).
+If you have questions, don't hesitate to ask them on [Stackoverflow](http://stackoverflow.com/questions/tagged/elastica) and add the Tag "Elastica" or
+in our [Gitter](https://gitter.im/ruflin/Elastica) channel.
+All library issues should go to the [issue tracker from github](https://github.com/ruflin/Elastica/issues).
+
+Contributing
+------------
+Contributions are always welcome. For details on how to contribute, check the [CONTRIBUTING](https://github.com/ruflin/Elastica/blob/master/CONTRIBUTING.md) file.
+
+Dependencies
+------------
+| Project | Version | Required |
+|---------|---------|----------|
+|[Elasticsearch](https://github.com/elasticsearch/elasticsearch/tree/v1.6.0)|1.6.0|yes|
+|[Elasticsearch mapper attachments plugin](https://github.com/elasticsearch/elasticsearch-mapper-attachments/tree/v2.6.0)|2.6.0|no|
+|[Elasticsearch thrift transport plugin](https://github.com/elasticsearch/elasticsearch-transport-thrift/tree/v2.6.0)|2.6.0|no|
+|[Elasticsearch memcached transport plugin](https://github.com/elastic/elasticsearch-transport-memcached/tree/v2.6.0)|2.6.0|no|
+|[Elasticsearch geocluster facet plugin](https://github.com/zenobase/geocluster-facet/tree/0.0.12)|0.0.12|no|
+|[Elasticsearch image plugin](https://github.com/SibaTokyo/elasticsearch-image/tree/1.4.0)|1.4.0|no|
diff --git a/vendor/ruflin/elastica/Vagrantfile b/vendor/ruflin/elastica/Vagrantfile
new file mode 100644
index 00000000..2deebbd4
--- /dev/null
+++ b/vendor/ruflin/elastica/Vagrantfile
@@ -0,0 +1,18 @@
+
+Vagrant.require_version ">= 1.4.0"
+
+Vagrant.configure("2") do |config|
+
+ config.vm.box = "ubuntu/precise32"
+
+ config.vm.network :private_network, ip: "10.10.10.10"
+
+ config.vm.provision "shell" do |sh|
+ sh.inline = "/bin/bash /vagrant/ansible/provision.sh"
+ end
+
+ config.vm.provider :virtualbox do |vb|
+ vb.customize ["modifyvm", :id, "--memory", "1024"]
+ end
+
+end
diff --git a/vendor/ruflin/elastica/ansible/es-playbook.yml b/vendor/ruflin/elastica/ansible/es-playbook.yml
new file mode 100644
index 00000000..3a471b64
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/es-playbook.yml
@@ -0,0 +1,20 @@
+---
+
+- name: Create a virtual machine
+ connection: local
+ hosts: localhost
+ sudo: true
+ vars:
+ - ES_VER: "1.6.0"
+ - ES_SHORT_VER: "1.6"
+ - ES_MAPPER_ATTACHMENTS_VER: "2.6.0"
+ - ES_TRANSPORT_MEMCACHED_VER: "2.6.0"
+ - ES_TRANSPORT_THRIFT_VER: "2.6.0"
+ - ES_GEOCLUSTER_FACET_VER: "0.0.12"
+ - ES_IMAGE_PLUGIN_VER: "1.4.0"
+ - ES_PROJECT_ROOT: "{{ lookup('env', 'ES_PROJECT_ROOT') }}"
+ roles:
+ - base
+ - elasticsearch
+ - nginx
+ - php
diff --git a/vendor/ruflin/elastica/ansible/provision.sh b/vendor/ruflin/elastica/ansible/provision.sh
new file mode 100755
index 00000000..6ea8e575
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/provision.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+set -o xtrace
+
+install_ansible() {
+ sudo apt-get update
+ sudo apt-get install python python-pip python-dev -y
+ sudo pip install ansible==1.8.2
+ sudo mkdir -p /etc/ansible/
+ echo "localhost" | sudo tee /etc/ansible/hosts
+}
+
+run_playbook() {
+ # Write to stdout directly
+ export PYTHONUNBUFFERED=1
+
+ # No cows >_<
+ export ANSIBLE_NOCOWS=1
+
+ # Root of git repo
+ if [ -z "$ES_PROJECT_ROOT" ]; then
+ export ES_PROJECT_ROOT="$(dirname $(dirname $(readlink -f $0)))"
+ fi
+
+ if [ ! -x $(which ansible-playbook) ]; then
+ echo "Ansible is not installed"
+ return 1
+ fi
+
+ ansible-playbook $ES_PROJECT_ROOT/ansible/es-playbook.yml -v | tee /tmp/ansible-playbook-progress
+
+ if grep -q "FATAL\|ERROR" /tmp/ansible-playbook-progress; then
+ return 1
+ fi
+}
+
+check_cluster() {
+ curl -m 5 -s -o /dev/null "http://localhost:9200" &&
+ curl -m 5 -s -o /dev/null "http://localhost:9201"
+ return $?
+}
+
+travis_retry() {
+ # We don't use builtin Travis CI function, because this script is also used for vagrant provision.
+ # But main idea of restarts is so simple, so lets override it without name change.
+
+ $@ && return 0
+
+ echo "The command $@ failed. Retrying, 2 of 3"
+ sleep 60s && $@ && return 0
+
+ echo "The command $@ failed. Retrying, 3 of 3"
+ sleep 60s && $@ && return 0
+
+ echo "The command $@ failed."
+ return 1
+}
+
+travis_retry install_ansible || exit 1
+
+travis_retry run_playbook || exit 1
+
+travis_retry check_cluster || exit 1
diff --git a/vendor/ruflin/elastica/ansible/roles/base/tasks/main.yml b/vendor/ruflin/elastica/ansible/roles/base/tasks/main.yml
new file mode 100644
index 00000000..061b8155
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/base/tasks/main.yml
@@ -0,0 +1,13 @@
+---
+
+- name: install base packages
+ apt: >
+ force=yes
+ name={{ item }}
+ state=present
+ update_cache=no
+ with_items:
+ - curl
+ - git
+ - htop
+ - vim
diff --git a/vendor/ruflin/elastica/ansible/roles/elasticsearch/handlers/main.yml b/vendor/ruflin/elastica/ansible/roles/elasticsearch/handlers/main.yml
new file mode 100644
index 00000000..97cccdd2
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/elasticsearch/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+
+- name: restart elasticsearch
+ service: >
+ name=elasticsearch
+ state=restarted
diff --git a/vendor/ruflin/elastica/ansible/roles/elasticsearch/tasks/main.yml b/vendor/ruflin/elastica/ansible/roles/elasticsearch/tasks/main.yml
new file mode 100644
index 00000000..c2041343
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/elasticsearch/tasks/main.yml
@@ -0,0 +1,101 @@
+---
+
+- name: import ppa:webupd8team/java gpg key
+ apt_key: >
+ id=EEA14886
+ keyserver=keyserver.ubuntu.com
+ state=present
+
+- name: add ppa:webupd8team/java repository
+ apt_repository: >
+ repo="deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main"
+ state=present
+ update_cache=yes
+
+- name: accept oracle license
+ shell: >
+ echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections
+
+- name: install java
+ apt: >
+ force=yes
+ name={{ item }}
+ state=present
+ update_cache=no
+ with_items:
+ - oracle-java7-installer
+ - oracle-java7-set-default
+
+- name: import elasticsearch gpg key
+ apt_key: >
+ id=D88E42B4
+ url=https://packages.elasticsearch.org/GPG-KEY-elasticsearch
+ state=present
+
+- name: add elasticsearch repository
+ apt_repository: >
+ repo="deb http://packages.elasticsearch.org/elasticsearch/{{ ES_SHORT_VER }}/debian stable main"
+ state=present
+ update_cache=yes
+
+- name: install elasticsearch
+ apt: >
+ force=yes
+ name=elasticsearch={{ ES_VER }}
+ state=present
+ update_cache=no
+
+- name: install image plugin
+ command: >
+ creates=/usr/share/elasticsearch/plugins/image
+ /usr/share/elasticsearch/bin/plugin --url https://github.com/SibaTokyo/elasticsearch-image/releases/download/{{ ES_IMAGE_PLUGIN_VER }}/elasticsearch-image-{{ ES_IMAGE_PLUGIN_VER }}.zip -install image
+
+- name: install mapper-attachments plugin
+ command: >
+ creates=/usr/share/elasticsearch/plugins/mapper-attachments
+ /usr/share/elasticsearch/bin/plugin -install elasticsearch/elasticsearch-mapper-attachments/{{ ES_MAPPER_ATTACHMENTS_VER }}
+
+- name: install geocluster-facet plugin
+ command: >
+ creates=/usr/share/elasticsearch/plugins/geocluster-facet
+ /usr/share/elasticsearch/bin/plugin -install geocluster-facet --url https://github.com/zenobase/geocluster-facet/releases/download/{{ ES_GEOCLUSTER_FACET_VER }}/geocluster-facet-{{ ES_GEOCLUSTER_FACET_VER }}.jar
+
+- name: install transport-thrift plugin
+ command: >
+ creates=/usr/share/elasticsearch/plugins/transport-thrift
+ /usr/share/elasticsearch/bin/plugin -install elasticsearch/elasticsearch-transport-thrift/{{ ES_TRANSPORT_THRIFT_VER }}
+
+- name: install transport-memcached plugin
+ command: >
+ creates=/usr/share/elasticsearch/plugins/transport-memcached
+ /usr/share/elasticsearch/bin/plugin -install elasticsearch/elasticsearch-transport-memcached/{{ ES_TRANSPORT_MEMCACHED_VER }}
+
+- name: remove default config
+ file: >
+ path={{ item }}
+ state=absent
+ with_items:
+ - /etc/default/elasticsearch
+ - /etc/elasticsearch/elasticsearch.yml
+
+- name: create custom config
+ template: >
+ dest=/etc/elasticsearch/{{ item }}
+ src={{ item }}
+ with_items:
+ - config-0.yml
+ - config-1.yml
+ - logging.yml
+ notify: restart elasticsearch
+
+- name: create elasticsearch service script
+ template: >
+ dest=/etc/init.d/elasticsearch
+ src=elasticsearch.service
+ notify: restart elasticsearch
+
+- name: start elasticsearch
+ service: >
+ enabled=yes
+ name=elasticsearch
+ state=started
diff --git a/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-0.yml b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-0.yml
new file mode 100644
index 00000000..aa956910
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-0.yml
@@ -0,0 +1,10 @@
+{% extends "config-default.yml" %}
+
+{% block config %}
+
+http.port: 9200
+transport.tcp.port: 9300
+thrift.port: 9500
+memcached.port: 11211
+
+{% endblock %}
diff --git a/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-1.yml b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-1.yml
new file mode 100644
index 00000000..a54d719e
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-1.yml
@@ -0,0 +1,10 @@
+{% extends "config-default.yml" %}
+
+{% block config %}
+
+http.port: 9201
+transport.tcp.port: 9301
+thrift.port: 9501
+memcached.port: 11212
+
+{% endblock %}
diff --git a/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-default.yml b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-default.yml
new file mode 100644
index 00000000..0917f244
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/config-default.yml
@@ -0,0 +1,40 @@
+{% block default_config %}
+
+index.number_of_shards: 2
+index.number_of_replicas: 0
+
+# Dont write data to hdd in tests
+index.store.type: memory
+
+# Required plugins
+plugin.mandatory: mapper-attachments, geocluster-facet, transport-thrift, transport-memcached, image
+
+# For bulk tests
+bulk.udp.enabled: true
+bulk.udp.bulk_actions: 5
+
+# For script tests
+script.inline: on
+script.indexed: on
+
+# Disable dynamic memory allocation
+bootstrap.mlockall: true
+
+# Dont accept connections not from localhost
+network.host: "127.0.0.1"
+
+# Limit threadpool by set number of available processors to 1
+# Without this, travis builds will be failed with OutOfMemory error
+processors: 1
+
+# All nodes will be called Elastica
+node.name: Elastica
+
+# Added for snapshot tests
+path.repo: ["/tmp/test_register", "/tmp/test_repository"]
+
+{% endblock %}
+
+{% block config %}
+# Node specific config should be overwritten in child template
+{% endblock %}
diff --git a/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/elasticsearch.service b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/elasticsearch.service
new file mode 100755
index 00000000..0268e230
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/elasticsearch.service
@@ -0,0 +1,229 @@
+#!/bin/sh
+#
+# /etc/init.d/elasticsearch -- startup script for Elasticsearch
+#
+# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
+# Modified for Debian GNU/Linux by Ian Murdock <imurdock@gnu.ai.mit.edu>.
+# Modified for Tomcat by Stefan Gybas <sgybas@debian.org>.
+# Modified for Tomcat6 by Thierry Carrez <thierry.carrez@ubuntu.com>.
+# Additional improvements by Jason Brittain <jason.brittain@mulesoft.com>.
+# Modified by Nicolas Huray for Elasticsearch <nicolas.huray@gmail.com>.
+# Modified by Igor Denisenko for Elastica <im.denisenko@yahoo.com>
+#
+### BEGIN INIT INFO
+# Provides: elasticsearch
+# Required-Start: $network $remote_fs $named
+# Required-Stop: $network $remote_fs $named
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Starts elasticsearch
+# Description: Starts elasticsearch using start-stop-daemon
+### END INIT INFO
+
+PATH="/bin:/usr/bin:/sbin:/usr/sbin"
+NAME="elasticsearch"
+DESC="Elasticsearch Server"
+
+if [ `id -u` -ne 0 ]; then
+ echo "You need root privileges to run this script"
+ exit 1
+fi
+
+
+. /lib/lsb/init-functions
+
+if [ -r /etc/default/rcS ]; then
+ . /etc/default/rcS
+fi
+
+
+# Run Elasticsearch as this user ID and group ID
+ES_USER="elasticsearch"
+ES_GROUP="elasticsearch"
+
+# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not defined)
+JDK_DIRS="/usr/lib/jvm/java-8-oracle/ /usr/lib/jvm/j2sdk1.8-oracle/ /usr/lib/jvm/jdk-7-oracle-x64 /usr/lib/jvm/java-7-oracle /usr/lib/jvm/j2sdk1.7-oracle/ /usr/lib/jvm/java-7-openjdk /usr/lib/jvm/java-7-openjdk-amd64/ /usr/lib/jvm/java-7-openjdk-armhf /usr/lib/jvm/java-7-openjdk-i386/ /usr/lib/jvm/default-java"
+
+# Look for the right JVM to use
+for jdir in $JDK_DIRS; do
+ if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
+ JAVA_HOME="$jdir"
+ fi
+done
+export JAVA_HOME
+
+# Directory where the Elasticsearch binary distribution resides
+ES_HOME="/usr/share/$NAME"
+
+# Heap size defaults to 256m min, 1g max
+# Be modest. Entire cluster will allocate (3*ES_HEAP_SIZE) memory
+ES_HEAP_SIZE="256m"
+export ES_HEAP_SIZE
+
+# Heap new generation
+# ES_HEAP_NEWSIZE=
+# export ES_HEAP_NEWSIZE
+
+# max direct memory
+# ES_DIRECT_SIZE=
+# export ES_DIRECT_SIZE
+
+# Additional Java OPTS
+ES_JAVA_OPTS="-server"
+export ES_JAVA_OPTS
+
+# Maximum number of open files
+MAX_OPEN_FILES="65535"
+
+# Maximum amount of locked memory
+MAX_LOCKED_MEMORY="unlimited"
+
+# Elasticsearch log directory
+LOG_DIR="/var/log/$NAME"
+
+# Elasticsearch data directory
+DATA_DIR="/var/lib/$NAME"
+
+# Elasticsearch work directory
+WORK_DIR="/tmp/$NAME"
+
+# Elasticsearch configuration directory
+CONF_DIR="/etc/$NAME"
+
+# Define other required variables
+DAEMON="$ES_HOME/bin/elasticsearch"
+
+# Check DAEMON exists
+if [ ! -x $DAEMON ]; then
+ exit 0
+fi
+
+checkJava() {
+ if [ -x "$JAVA_HOME/bin/java" ]; then
+ JAVA="$JAVA_HOME/bin/java"
+ else
+ JAVA=`which java`
+ fi
+
+ if [ ! -x "$JAVA" ]; then
+ echo "Could not find any executable java binary. Please install java in your PATH or set JAVA_HOME"
+ exit 1
+ fi
+}
+
+case "$1" in
+ start)
+ checkJava
+
+ if [ -n "$MAX_LOCKED_MEMORY" -a -z "$ES_HEAP_SIZE" ]; then
+ log_failure_msg "MAX_LOCKED_MEMORY is set - ES_HEAP_SIZE must also be set"
+ exit 1
+ fi
+
+
+ mkdir -p "$LOG_DIR" "$DATA_DIR" "$WORK_DIR"
+ chown "$ES_USER":"$ES_GROUP" "$LOG_DIR" "$DATA_DIR" "$WORK_DIR"
+
+ if [ -n "$MAX_OPEN_FILES" ];then
+ ulimit -n $MAX_OPEN_FILES
+ fi
+
+ if [ -n "$MAX_LOCKED_MEMORY" ];then
+ ulimit -l $MAX_LOCKED_MEMORY
+ fi
+
+ ulimit -s 1024
+
+ for node in 0 1; do
+ log_daemon_msg "Starting elasticsearch node #$node"
+
+ PID_FILE="/var/run/$NAME-$node.pid"
+ CONF_FILE="$CONF_DIR/config-$node.yml"
+
+ DAEMON="$ES_HOME/bin/elasticsearch"
+ DAEMON_OPTS="
+ -Des.config=$CONF_FILE \
+ -Des.path.home=$ES_HOME \
+ -Des.path.logs=$LOG_DIR \
+ -Des.path.data=$DATA_DIR \
+ -Des.path.work=$WORK_DIR \
+ -Des.path.conf=$CONF_DIR \
+ -p $PID_FILE
+ "
+
+ pid=`pidofproc -p $PID_FILE elasticsearch`
+ if [ -n "$pid" ] ; then
+ log_begin_msg "Elasticsearch node #$node already running"
+ continue
+ fi
+
+ touch "$PID_FILE"
+ chown "$ES_USER":"$ES_GROUP" "$PID_FILE"
+
+ # Start Daemon
+ start-stop-daemon --start -b --user "$ES_USER" -c "$ES_USER" --pidfile "$PID_FILE" --exec "$DAEMON" -- "$DAEMON_OPTS"
+ return=$?
+ if [ $return -eq 0 ]; then
+ i=0
+ timeout=10
+ # Wait for the process to be properly started before exiting
+ until { cat "$PID_FILE" | xargs kill -0; } >/dev/null 2>&1
+ do
+ sleep 1
+ i=$(($i + 1))
+ [ $i -gt $timeout ] && log_end_msg 1
+ done
+ else
+ log_end_msg $return
+ fi
+ done
+ ;;
+ stop)
+ for node in 0 1; do
+ log_daemon_msg "Stopping elasticsearch node #$node"
+
+ PID_FILE="/var/run/$NAME-$node.pid"
+
+ if [ -f "$PID_FILE" ]; then
+ start-stop-daemon --stop --pidfile "$PID_FILE" \
+ --user "$ES_USER" \
+ --retry=TERM/20/KILL/5 >/dev/null
+ if [ $? -eq 1 ]; then
+ log_progress_msg "$DESC is not running but pid file exists, cleaning up"
+ elif [ $? -eq 3 ]; then
+ PID="`cat $PID_FILE`"
+ log_failure_msg "Failed to stop $DESC (pid $PID)"
+ exit 1
+ fi
+ rm -f "$PID_FILE"
+ else
+ log_progress_msg "(not running)"
+ fi
+ done
+
+ log_end_msg 0
+ ;;
+ status)
+ for node in 0 1; do
+ PID_FILE="/var/run/$NAME-$node.pid"
+ status_of_proc -p $PID_FILE "Elasticsearch node #$node" "Elasticsearch node #$node"
+ done
+ exit 0
+ ;;
+ restart|force-reload)
+ for node in 0 1; do
+ PID_FILE="/var/run/$NAME-$node.pid"
+ if [ -f "$PID_FILE" ]; then
+ $0 stop
+ sleep 1
+ fi
+ done
+ $0 start
+ ;;
+ *)
+ log_success_msg "Usage: $0 {start|stop|restart|force-reload|status}"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/logging.yml b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/logging.yml
new file mode 100644
index 00000000..9e00d01c
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/elasticsearch/templates/logging.yml
@@ -0,0 +1,56 @@
+# you can override this using by setting a system property, for example -Des.logger.level=DEBUG
+es.logger.level: INFO
+rootLogger: ${es.logger.level}, console, file
+logger:
+ # log action execution errors for easier debugging
+ action: DEBUG
+ # reduce the logging for aws, too much is logged under the default INFO
+ com.amazonaws: WARN
+
+ # gateway
+ #gateway: DEBUG
+ #index.gateway: DEBUG
+
+ # peer shard recovery
+ #indices.recovery: DEBUG
+
+ # discovery
+ #discovery: TRACE
+
+ index.search.slowlog: TRACE, index_search_slow_log_file
+ index.indexing.slowlog: TRACE, index_indexing_slow_log_file
+
+additivity:
+ index.search.slowlog: false
+ index.indexing.slowlog: false
+
+appender:
+ console:
+ type: console
+ layout:
+ type: consolePattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+ file:
+ type: dailyRollingFile
+ file: ${path.logs}/${cluster.name}.log
+ datePattern: "'.'yyyy-MM-dd"
+ layout:
+ type: pattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+ index_search_slow_log_file:
+ type: dailyRollingFile
+ file: ${path.logs}/${cluster.name}_index_search_slowlog.log
+ datePattern: "'.'yyyy-MM-dd"
+ layout:
+ type: pattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+ index_indexing_slow_log_file:
+ type: dailyRollingFile
+ file: ${path.logs}/${cluster.name}_index_indexing_slowlog.log
+ datePattern: "'.'yyyy-MM-dd"
+ layout:
+ type: pattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
diff --git a/vendor/ruflin/elastica/ansible/roles/nginx/handlers/main.yml b/vendor/ruflin/elastica/ansible/roles/nginx/handlers/main.yml
new file mode 100644
index 00000000..fc583f27
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/nginx/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+
+- name: restart nginx
+ service: >
+ name=nginx
+ state=restarted
diff --git a/vendor/ruflin/elastica/ansible/roles/nginx/tasks/main.yml b/vendor/ruflin/elastica/ansible/roles/nginx/tasks/main.yml
new file mode 100644
index 00000000..6b260531
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/nginx/tasks/main.yml
@@ -0,0 +1,26 @@
+---
+
+- name: install nginx
+ apt: >
+ force=yes
+ name=nginx
+ state=present
+ update_cache=no
+
+- name: create mime.types
+ template: >
+ dest=/etc/nginx/mime.types
+ src=mime.types.j2
+ notify: restart nginx
+
+- name: create nginx.conf
+ template: >
+ dest=/etc/nginx/nginx.conf
+ src=nginx.conf.j2
+ notify: restart nginx
+
+- name: start nginx
+ service: >
+ enabled=yes
+ name=nginx
+ state=started
diff --git a/vendor/ruflin/elastica/ansible/roles/nginx/templates/mime.types.j2 b/vendor/ruflin/elastica/ansible/roles/nginx/templates/mime.types.j2
new file mode 100644
index 00000000..6c64bf73
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/nginx/templates/mime.types.j2
@@ -0,0 +1,109 @@
+types {
+
+# Audio
+ audio/midi mid midi kar;
+ audio/mp4 aac f4a f4b m4a;
+ audio/mpeg mp3;
+ audio/ogg oga ogg opus;
+ audio/x-realaudio ra;
+ audio/x-wav wav;
+
+# Images
+ image/bmp bmp;
+ image/gif gif;
+ image/jpeg jpeg jpg;
+ image/png png;
+ image/svg+xml svg svgz;
+ image/tiff tif tiff;
+ image/vnd.wap.wbmp wbmp;
+ image/webp webp;
+ image/x-icon ico cur;
+ image/x-jng jng;
+
+# JavaScript
+ application/javascript js;
+ application/json json;
+
+# Manifest files
+ application/x-web-app-manifest+json webapp;
+ text/cache-manifest manifest appcache;
+
+# Microsoft Office
+ application/msword doc;
+ application/vnd.ms-excel xls;
+ application/vnd.ms-powerpoint ppt;
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
+ application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
+
+# Video
+ video/3gpp 3gpp 3gp;
+ video/mp4 mp4 m4v f4v f4p;
+ video/mpeg mpeg mpg;
+ video/ogg ogv;
+ video/quicktime mov;
+ video/webm webm;
+ video/x-flv flv;
+ video/x-mng mng;
+ video/x-ms-asf asx asf;
+ video/x-ms-wmv wmv;
+ video/x-msvideo avi;
+
+# Web feeds
+ application/xml atom rdf rss xml;
+
+# Web fonts
+ application/font-woff woff;
+ application/font-woff2 woff2;
+ application/vnd.ms-fontobject eot;
+ application/x-font-ttf ttc ttf;
+ font/opentype otf;
+
+# Other
+ application/java-archive jar war ear;
+ application/mac-binhex40 hqx;
+ application/pdf pdf;
+ application/postscript ps eps ai;
+ application/rtf rtf;
+ application/vnd.wap.wmlc wmlc;
+ application/xhtml+xml xhtml;
+ application/vnd.google-earth.kml+xml kml;
+ application/vnd.google-earth.kmz kmz;
+ application/x-7z-compressed 7z;
+ application/x-chrome-extension crx;
+ application/x-opera-extension oex;
+ application/x-xpinstall xpi;
+ application/x-cocoa cco;
+ application/x-java-archive-diff jardiff;
+ application/x-java-jnlp-file jnlp;
+ application/x-makeself run;
+ application/x-perl pl pm;
+ application/x-pilot prc pdb;
+ application/x-rar-compressed rar;
+ application/x-redhat-package-manager rpm;
+ application/x-sea sea;
+ application/x-shockwave-flash swf;
+ application/x-stuffit sit;
+ application/x-tcl tcl tk;
+ application/x-x509-ca-cert der pem crt;
+ application/x-bittorrent torrent;
+ application/zip zip;
+
+ application/octet-stream bin exe dll;
+ application/octet-stream deb;
+ application/octet-stream dmg;
+ application/octet-stream iso img;
+ application/octet-stream msi msp msm;
+ application/octet-stream safariextz;
+
+ text/css css;
+ text/html html htm shtml;
+ text/mathml mml;
+ text/plain txt;
+ text/vnd.sun.j2me.app-descriptor jad;
+ text/vnd.wap.wml wml;
+ text/vtt vtt;
+ text/x-component htc;
+ text/x-vcard vcf;
+
+}
diff --git a/vendor/ruflin/elastica/ansible/roles/nginx/templates/nginx.conf.j2 b/vendor/ruflin/elastica/ansible/roles/nginx/templates/nginx.conf.j2
new file mode 100644
index 00000000..17966f7a
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/nginx/templates/nginx.conf.j2
@@ -0,0 +1,35 @@
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+ charset_types text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml text/css application/javascript application/json;
+
+ server {
+ listen 80;
+
+ root {{ ES_PROJECT_ROOT }};
+
+ location / {
+ autoindex on;
+ }
+ }
+
+ server {
+ listen 127.0.0.1:12345;
+
+ location / {
+ proxy_pass http://127.0.0.1:9200;
+ }
+ }
+
+ server {
+ listen 127.0.0.1:12346;
+
+ location / {
+ return 403;
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/ansible/roles/php/tasks/main.yml b/vendor/ruflin/elastica/ansible/roles/php/tasks/main.yml
new file mode 100644
index 00000000..fff65d52
--- /dev/null
+++ b/vendor/ruflin/elastica/ansible/roles/php/tasks/main.yml
@@ -0,0 +1,43 @@
+---
+- name: import ppa:ondrej/php5 gpg key
+ apt_key: >
+ id=E5267A6C
+ keyserver=keyserver.ubuntu.com
+ state=present
+
+- name: add ppa:ondrej/php5 repository
+ apt_repository: >
+ repo="deb http://ppa.launchpad.net/ondrej/php5/ubuntu precise main"
+ state=present
+ update_cache=yes
+
+- name: install php
+ apt: >
+ force=yes
+ name={{ item }}
+ state=present
+ update_cache=no
+ with_items:
+ - php5-cli
+ - php5-curl
+ - php5-xdebug
+ - php5-memcache
+
+- name: install phar packages
+ get_url: >
+ dest={{ item.dest }}
+ url={{ item.url }}
+ mode=0755
+ with_items:
+ - { dest: "/usr/local/bin/php-cs-fixer", url: "http://get.sensiolabs.org/php-cs-fixer.phar" }
+ - { dest: "/usr/local/bin/phpdoc", url: "http://phpdoc.org/phpDocumentor.phar" }
+ - { dest: "/usr/local/bin/phpunit", url: "https://phar.phpunit.de/phpunit.phar" }
+ - { dest: "/usr/local/bin/composer", url: "https://getcomposer.org/composer.phar" }
+
+- name: install dependencies from composer.json
+ composer: >
+ command=install
+ optimize_autoloader=yes
+ prefer_source=yes
+ no_dev=no
+ working_dir={{ ES_PROJECT_ROOT }}
diff --git a/vendor/ruflin/elastica/composer.json b/vendor/ruflin/elastica/composer.json
new file mode 100644
index 00000000..8bffc334
--- /dev/null
+++ b/vendor/ruflin/elastica/composer.json
@@ -0,0 +1,43 @@
+{
+ "name": "ruflin/elastica",
+ "description": "Elasticsearch Client",
+ "keywords": ["search","client"],
+ "homepage": "http://elastica.io/",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Ruflin",
+ "homepage": "http://ruflin.com/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3",
+ "psr/log": "~1.0"
+ },
+ "require-dev": {
+ "munkie/elasticsearch-thrift-php": "1.4.*",
+ "guzzlehttp/guzzle": "5.3.*"
+ },
+ "suggest": {
+ "munkie/elasticsearch-thrift-php": "Allow using thrift transport",
+ "guzzlehttp/guzzle": "Allow using guzzle 5.3.x as the http transport (Requires php 5.4)",
+ "egeloen/http-adapter": "Allow using httpadapter transport",
+ "monolog/monolog": "Logging request"
+ },
+ "autoload": {
+ "psr-4": {
+ "Elastica\\": "lib/Elastica/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Elastica\\Test\\": "test/lib/Elastica/Test/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/docker-compose.yml b/vendor/ruflin/elastica/docker-compose.yml
new file mode 100644
index 00000000..674d6e9e
--- /dev/null
+++ b/vendor/ruflin/elastica/docker-compose.yml
@@ -0,0 +1,27 @@
+elastica:
+ #build: . # In case the image must be built locally
+ image: ruflin/elastica
+ ports:
+ - "9200:9200"
+ volumes:
+ - .:/app
+ links:
+ - nginx
+ - elasticsearch
+ environment:
+ - ES_HOST=elasticsearch
+ - PROXY_HOST=nginx
+elasticsearch:
+ #build: ./env/elasticsearch/ # In case image must be built locally
+ image: ruflin/elasticsearch-elastica
+nginx:
+ image: nginx
+ volumes:
+ - ./env/nginx/nginx.conf:/etc/nginx/nginx.conf
+ - ./env/nginx/mime.types:/etc/nginx/mime.types
+ ports:
+ - "12345"
+ - "12346"
+ - "80"
+ links:
+ - elasticsearch
diff --git a/vendor/ruflin/elastica/env/elasticsearch/Dockerfile b/vendor/ruflin/elastica/env/elasticsearch/Dockerfile
new file mode 100644
index 00000000..ae2665a0
--- /dev/null
+++ b/vendor/ruflin/elastica/env/elasticsearch/Dockerfile
@@ -0,0 +1,26 @@
+FROM elasticsearch:1.6.0
+MAINTAINER Nicolas Ruflin <spam@ruflin.com>
+
+# Dependencies
+ENV ES_MAPPER_ATTACHMENTS_VER 2.6.0
+ENV ES_TRANSPORT_MEMCACHED_VER 2.6.0
+ENV ES_TRANSPORT_THRIFT_VER 2.6.0
+ENV ES_GEOCLUSTER_FACET_VER 0.0.12
+ENV ES_IMAGE_PLUGIN_VER 1.4.0
+ENV ES_PLUGIN_BIN /usr/share/elasticsearch/bin/plugin
+
+# Install Plugins
+RUN ${ES_PLUGIN_BIN} -install elasticsearch/elasticsearch-mapper-attachments/${ES_MAPPER_ATTACHMENTS_VER}
+RUN ${ES_PLUGIN_BIN} -install image --url https://github.com/SibaTokyo/elasticsearch-image/releases/download/${ES_IMAGE_PLUGIN_VER}/elasticsearch-image-${ES_IMAGE_PLUGIN_VER}.zip
+RUN ${ES_PLUGIN_BIN} -install geocluster-facet --url https://github.com/zenobase/geocluster-facet/releases/download/${ES_GEOCLUSTER_FACET_VER}/geocluster-facet-${ES_GEOCLUSTER_FACET_VER}.jar
+RUN ${ES_PLUGIN_BIN} -install elasticsearch/elasticsearch-transport-thrift/${ES_TRANSPORT_THRIFT_VER}
+RUN ${ES_PLUGIN_BIN} -install elasticsearch/elasticsearch-transport-memcached/${ES_TRANSPORT_MEMCACHED_VER}
+
+# Debug interface
+RUN ${ES_PLUGIN_BIN} -install mobz/elasticsearch-head
+
+# Copy config files
+COPY *.yml /usr/share/elasticsearch/config/
+
+# Expose standard ports, thrift, udp, memcache
+EXPOSE 9200 9300 9500 9700 9800 11211
diff --git a/vendor/ruflin/elastica/env/elasticsearch/elasticsearch.yml b/vendor/ruflin/elastica/env/elasticsearch/elasticsearch.yml
new file mode 100644
index 00000000..bd0368da
--- /dev/null
+++ b/vendor/ruflin/elastica/env/elasticsearch/elasticsearch.yml
@@ -0,0 +1,39 @@
+
+index.number_of_shards: 2
+index.number_of_replicas: 0
+
+# Dont write data to hdd in tests
+index.store.type: memory
+
+# Required plugins
+plugin.mandatory: mapper-attachments, geocluster-facet, transport-thrift, transport-memcached, image
+
+# For bulk tests
+bulk.udp.enabled: true
+bulk.udp.bulk_actions: 5
+
+# For script tests
+script.inline: on
+script.indexed: on
+
+# Disable dynamic memory allocation
+bootstrap.mlockall: true
+
+# Dont accept connections not from localhost
+#network.host: "127.0.0.1"
+
+# Limit threadpool by set number of available processors to 1
+# Without this, travis builds will be failed with OutOfMemory error
+processors: 1
+
+# All nodes will be called Elastica
+node.name: Elastica
+
+# Ports config
+http.port: 9200
+transport.tcp.port: 9300
+thrift.port: 9500
+memcached.port: 11211
+
+# Added for snapshot tests
+path.repo: ["/tmp/test_register", "/tmp/test_repository"] \ No newline at end of file
diff --git a/vendor/ruflin/elastica/env/elasticsearch/logging.yml b/vendor/ruflin/elastica/env/elasticsearch/logging.yml
new file mode 100644
index 00000000..9e00d01c
--- /dev/null
+++ b/vendor/ruflin/elastica/env/elasticsearch/logging.yml
@@ -0,0 +1,56 @@
+# you can override this using by setting a system property, for example -Des.logger.level=DEBUG
+es.logger.level: INFO
+rootLogger: ${es.logger.level}, console, file
+logger:
+ # log action execution errors for easier debugging
+ action: DEBUG
+ # reduce the logging for aws, too much is logged under the default INFO
+ com.amazonaws: WARN
+
+ # gateway
+ #gateway: DEBUG
+ #index.gateway: DEBUG
+
+ # peer shard recovery
+ #indices.recovery: DEBUG
+
+ # discovery
+ #discovery: TRACE
+
+ index.search.slowlog: TRACE, index_search_slow_log_file
+ index.indexing.slowlog: TRACE, index_indexing_slow_log_file
+
+additivity:
+ index.search.slowlog: false
+ index.indexing.slowlog: false
+
+appender:
+ console:
+ type: console
+ layout:
+ type: consolePattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+ file:
+ type: dailyRollingFile
+ file: ${path.logs}/${cluster.name}.log
+ datePattern: "'.'yyyy-MM-dd"
+ layout:
+ type: pattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+ index_search_slow_log_file:
+ type: dailyRollingFile
+ file: ${path.logs}/${cluster.name}_index_search_slowlog.log
+ datePattern: "'.'yyyy-MM-dd"
+ layout:
+ type: pattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+ index_indexing_slow_log_file:
+ type: dailyRollingFile
+ file: ${path.logs}/${cluster.name}_index_indexing_slowlog.log
+ datePattern: "'.'yyyy-MM-dd"
+ layout:
+ type: pattern
+ conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
diff --git a/vendor/ruflin/elastica/env/nginx/mime.types b/vendor/ruflin/elastica/env/nginx/mime.types
new file mode 100644
index 00000000..6c64bf73
--- /dev/null
+++ b/vendor/ruflin/elastica/env/nginx/mime.types
@@ -0,0 +1,109 @@
+types {
+
+# Audio
+ audio/midi mid midi kar;
+ audio/mp4 aac f4a f4b m4a;
+ audio/mpeg mp3;
+ audio/ogg oga ogg opus;
+ audio/x-realaudio ra;
+ audio/x-wav wav;
+
+# Images
+ image/bmp bmp;
+ image/gif gif;
+ image/jpeg jpeg jpg;
+ image/png png;
+ image/svg+xml svg svgz;
+ image/tiff tif tiff;
+ image/vnd.wap.wbmp wbmp;
+ image/webp webp;
+ image/x-icon ico cur;
+ image/x-jng jng;
+
+# JavaScript
+ application/javascript js;
+ application/json json;
+
+# Manifest files
+ application/x-web-app-manifest+json webapp;
+ text/cache-manifest manifest appcache;
+
+# Microsoft Office
+ application/msword doc;
+ application/vnd.ms-excel xls;
+ application/vnd.ms-powerpoint ppt;
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
+ application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
+
+# Video
+ video/3gpp 3gpp 3gp;
+ video/mp4 mp4 m4v f4v f4p;
+ video/mpeg mpeg mpg;
+ video/ogg ogv;
+ video/quicktime mov;
+ video/webm webm;
+ video/x-flv flv;
+ video/x-mng mng;
+ video/x-ms-asf asx asf;
+ video/x-ms-wmv wmv;
+ video/x-msvideo avi;
+
+# Web feeds
+ application/xml atom rdf rss xml;
+
+# Web fonts
+ application/font-woff woff;
+ application/font-woff2 woff2;
+ application/vnd.ms-fontobject eot;
+ application/x-font-ttf ttc ttf;
+ font/opentype otf;
+
+# Other
+ application/java-archive jar war ear;
+ application/mac-binhex40 hqx;
+ application/pdf pdf;
+ application/postscript ps eps ai;
+ application/rtf rtf;
+ application/vnd.wap.wmlc wmlc;
+ application/xhtml+xml xhtml;
+ application/vnd.google-earth.kml+xml kml;
+ application/vnd.google-earth.kmz kmz;
+ application/x-7z-compressed 7z;
+ application/x-chrome-extension crx;
+ application/x-opera-extension oex;
+ application/x-xpinstall xpi;
+ application/x-cocoa cco;
+ application/x-java-archive-diff jardiff;
+ application/x-java-jnlp-file jnlp;
+ application/x-makeself run;
+ application/x-perl pl pm;
+ application/x-pilot prc pdb;
+ application/x-rar-compressed rar;
+ application/x-redhat-package-manager rpm;
+ application/x-sea sea;
+ application/x-shockwave-flash swf;
+ application/x-stuffit sit;
+ application/x-tcl tcl tk;
+ application/x-x509-ca-cert der pem crt;
+ application/x-bittorrent torrent;
+ application/zip zip;
+
+ application/octet-stream bin exe dll;
+ application/octet-stream deb;
+ application/octet-stream dmg;
+ application/octet-stream iso img;
+ application/octet-stream msi msp msm;
+ application/octet-stream safariextz;
+
+ text/css css;
+ text/html html htm shtml;
+ text/mathml mml;
+ text/plain txt;
+ text/vnd.sun.j2me.app-descriptor jad;
+ text/vnd.wap.wml wml;
+ text/vtt vtt;
+ text/x-component htc;
+ text/x-vcard vcf;
+
+}
diff --git a/vendor/ruflin/elastica/env/nginx/nginx.conf b/vendor/ruflin/elastica/env/nginx/nginx.conf
new file mode 100644
index 00000000..edf177d3
--- /dev/null
+++ b/vendor/ruflin/elastica/env/nginx/nginx.conf
@@ -0,0 +1,38 @@
+
+worker_processes 1;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+ charset_types text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml text/css application/javascript application/json;
+
+ server {
+ listen 80;
+
+ #root {{ ES_PROJECT_ROOT }};
+
+ location / {
+ autoindex on;
+ }
+ }
+
+ server {
+ listen 12345;
+
+ location / {
+ proxy_pass http://elasticsearch:9200;
+ }
+ }
+
+ server {
+ listen 12346;
+
+ location / {
+ return 403;
+ }
+ }
+}
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;
+ }
+}
diff --git a/vendor/ruflin/elastica/phpdoc.dist.xml b/vendor/ruflin/elastica/phpdoc.dist.xml
new file mode 100644
index 00000000..585a4687
--- /dev/null
+++ b/vendor/ruflin/elastica/phpdoc.dist.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<docblox>
+ <title>Elastica</title>
+ <parser>
+ <target>./build/api</target>
+ </parser>
+ <transformer>
+ <target>./build/api</target>
+ </transformer>
+ <files>
+ <directory>./lib</directory>
+ </files>
+</docblox>
diff --git a/vendor/ruflin/elastica/test/bootstrap.php b/vendor/ruflin/elastica/test/bootstrap.php
new file mode 100644
index 00000000..8a29cf0f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/bootstrap.php
@@ -0,0 +1,5 @@
+<?php
+
+defined('BASE_PATH') || define('BASE_PATH', realpath(__DIR__));
+
+require dirname(__DIR__).'/vendor/autoload.php';
diff --git a/vendor/ruflin/elastica/test/data/test.doc b/vendor/ruflin/elastica/test/data/test.doc
new file mode 100644
index 00000000..d90d83c1
--- /dev/null
+++ b/vendor/ruflin/elastica/test/data/test.doc
Binary files differ
diff --git a/vendor/ruflin/elastica/test/data/test.docx b/vendor/ruflin/elastica/test/data/test.docx
new file mode 100644
index 00000000..924c1066
--- /dev/null
+++ b/vendor/ruflin/elastica/test/data/test.docx
Binary files differ
diff --git a/vendor/ruflin/elastica/test/data/test.jpg b/vendor/ruflin/elastica/test/data/test.jpg
new file mode 100644
index 00000000..d69e5672
--- /dev/null
+++ b/vendor/ruflin/elastica/test/data/test.jpg
Binary files differ
diff --git a/vendor/ruflin/elastica/test/data/test.pdf b/vendor/ruflin/elastica/test/data/test.pdf
new file mode 100644
index 00000000..e94c3f67
--- /dev/null
+++ b/vendor/ruflin/elastica/test/data/test.pdf
Binary files differ
diff --git a/vendor/ruflin/elastica/test/data/test.txt b/vendor/ruflin/elastica/test/data/test.txt
new file mode 100644
index 00000000..839b72a1
--- /dev/null
+++ b/vendor/ruflin/elastica/test/data/test.txt
@@ -0,0 +1 @@
+Wie geht es ihnen? \ No newline at end of file
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/AvgTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/AvgTest.php
new file mode 100644
index 00000000..650a4655
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/AvgTest.php
@@ -0,0 +1,39 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Avg;
+use Elastica\Document;
+use Elastica\Query;
+
+class AvgTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAvgAggregation()
+ {
+ $agg = new Avg('avg');
+ $agg->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregations();
+ $this->assertEquals((5 + 8 + 1 + 3) / 4.0, $results['avg']['value']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/BaseAggregationTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/BaseAggregationTest.php
new file mode 100644
index 00000000..48003d7e
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/BaseAggregationTest.php
@@ -0,0 +1,8 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Test\Base;
+
+abstract class BaseAggregationTest extends Base
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/CardinalityTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/CardinalityTest.php
new file mode 100644
index 00000000..7bc383f0
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/CardinalityTest.php
@@ -0,0 +1,132 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Cardinality;
+use Elastica\Document;
+use Elastica\Query;
+
+class CardinalityTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('color' => 'blue')),
+ new Document(2, array('color' => 'blue')),
+ new Document(3, array('color' => 'red')),
+ new Document(4, array('color' => 'green')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCardinalityAggregation()
+ {
+ $agg = new Cardinality('cardinality');
+ $agg->setField('color');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('cardinality');
+
+ $this->assertEquals(3, $results['value']);
+ }
+
+ /**
+ * @dataProvider invalidPrecisionThresholdProvider
+ * @expectedException \InvalidArgumentException
+ *
+ * @param $threshold
+ */
+ public function testInvalidPrecisionThreshold($threshold)
+ {
+ $agg = new Cardinality('threshold');
+ $agg->setPrecisionThreshold($threshold);
+ }
+
+ /**
+ * @dataProvider validPrecisionThresholdProvider
+ *
+ * @param $threshold
+ */
+ public function testPrecisionThreshold($threshold)
+ {
+ $agg = new Cardinality('threshold');
+ $agg->setPrecisionThreshold($threshold);
+
+ $this->assertNotNull($agg->getParam('precision_threshold'));
+ $this->assertInternalType('int', $agg->getParam('precision_threshold'));
+ }
+
+ public function invalidPrecisionThresholdProvider()
+ {
+ return array(
+ 'string' => array('100'),
+ 'float' => array(7.8),
+ 'boolean' => array(true),
+ 'array' => array(array()),
+ 'object' => array(new \StdClass()),
+ );
+ }
+
+ public function validPrecisionThresholdProvider()
+ {
+ return array(
+ 'negative-int' => array(-140),
+ 'zero' => array(0),
+ 'positive-int' => array(150),
+ 'more-than-max' => array(40001),
+ );
+ }
+
+ /**
+ * @dataProvider validRehashProvider
+ *
+ * @param bool $rehash
+ */
+ public function testRehash($rehash)
+ {
+ $agg = new Cardinality('rehash');
+ $agg->setRehash($rehash);
+
+ $this->assertNotNull($agg->getParam('rehash'));
+ $this->assertInternalType('boolean', $agg->getParam('rehash'));
+ }
+
+ /**
+ * @dataProvider invalidRehashProvider
+ * @expectedException \InvalidArgumentException
+ *
+ * @param mixed $rehash
+ */
+ public function testInvalidRehash($rehash)
+ {
+ $agg = new Cardinality('rehash');
+ $agg->setRehash($rehash);
+ }
+
+ public function invalidRehashProvider()
+ {
+ return array(
+ 'string' => array('100'),
+ 'int' => array(100),
+ 'float' => array(7.8),
+ 'array' => array(array()),
+ 'object' => array(new \StdClass()),
+ );
+ }
+
+ public function validRehashProvider()
+ {
+ return array(
+ 'true' => array(true),
+ 'false' => array(false),
+ );
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateHistogramTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateHistogramTest.php
new file mode 100644
index 00000000..ca115ccc
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateHistogramTest.php
@@ -0,0 +1,103 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\DateHistogram;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class DateHistogramTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(new Mapping(null, array(
+ 'created' => array('type' => 'date'),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array('created' => '2014-01-29T00:20:00')),
+ new Document(2, array('created' => '2014-01-29T02:20:00')),
+ new Document(3, array('created' => '2014-01-29T03:20:00')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDateHistogramAggregation()
+ {
+ $agg = new DateHistogram('hist', 'created', '1h');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('hist');
+
+ $this->assertEquals(3, sizeof($results['buckets']));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetOffset()
+ {
+ $agg = new DateHistogram('hist', 'created', '1h');
+
+ $agg->setOffset('3m');
+
+ $expected = array(
+ 'date_histogram' => array(
+ 'field' => 'created',
+ 'interval' => '1h',
+ 'offset' => '3m',
+ ),
+ );
+
+ $this->assertEquals($expected, $agg->toArray());
+
+ $this->assertInstanceOf('Elastica\Aggregation\DateHistogram', $agg->setOffset('3m'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetOffsetWorks()
+ {
+ $agg = new DateHistogram('hist', 'created', '1m');
+ $agg->setOffset('+40s');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('hist');
+
+ $this->assertEquals('2014-01-29T00:19:40.000Z', $results['buckets'][0]['key_as_string']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetTimezone()
+ {
+ $agg = new DateHistogram('hist', 'created', '1h');
+
+ $agg->setTimezone('-02:30');
+
+ $expected = array(
+ 'date_histogram' => array(
+ 'field' => 'created',
+ 'interval' => '1h',
+ 'time_zone' => '-02:30',
+ ),
+ );
+
+ $this->assertEquals($expected, $agg->toArray());
+
+ $this->assertInstanceOf('Elastica\Aggregation\DateHistogram', $agg->setTimezone('-02:30'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateRangeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateRangeTest.php
new file mode 100644
index 00000000..b8078a4c
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/DateRangeTest.php
@@ -0,0 +1,52 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\DateRange;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class DateRangeTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(new Mapping(null, array(
+ 'created' => array('type' => 'date'),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array('created' => 1390962135000)),
+ new Document(2, array('created' => 1390965735000)),
+ new Document(3, array('created' => 1390954935000)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDateRangeAggregation()
+ {
+ $agg = new DateRange('date');
+ $agg->setField('created');
+ $agg->addRange(1390958535000)->addRange(null, 1390958535000);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('date');
+
+ foreach ($results['buckets'] as $bucket) {
+ if (array_key_exists('to', $bucket)) {
+ $this->assertEquals(1, $bucket['doc_count']);
+ } elseif (array_key_exists('from', $bucket)) {
+ $this->assertEquals(2, $bucket['doc_count']);
+ }
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ExtendedStatsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ExtendedStatsTest.php
new file mode 100644
index 00000000..8c336245
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ExtendedStatsTest.php
@@ -0,0 +1,45 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\ExtendedStats;
+use Elastica\Document;
+use Elastica\Query;
+
+class ExtendedStatsTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testExtendedStatsAggregation()
+ {
+ $agg = new ExtendedStats('stats');
+ $agg->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('stats');
+
+ $this->assertEquals(4, $results['count']);
+ $this->assertEquals(1, $results['min']);
+ $this->assertEquals(8, $results['max']);
+ $this->assertEquals((5 + 8 + 1 + 3) / 4.0, $results['avg']);
+ $this->assertEquals((5 + 8 + 1 + 3), $results['sum']);
+ $this->assertTrue(array_key_exists('sum_of_squares', $results));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FilterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FilterTest.php
new file mode 100644
index 00000000..9198bb95
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FilterTest.php
@@ -0,0 +1,113 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Avg;
+use Elastica\Aggregation\Filter;
+use Elastica\Document;
+use Elastica\Filter\Range;
+use Elastica\Filter\Term;
+use Elastica\Query;
+
+class FilterTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5, 'color' => 'blue')),
+ new Document(2, array('price' => 8, 'color' => 'blue')),
+ new Document(3, array('price' => 1, 'color' => 'red')),
+ new Document(4, array('price' => 3, 'color' => 'green')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $expected = array(
+ 'filter' => array('range' => array('stock' => array('gt' => 0))),
+ 'aggs' => array(
+ 'avg_price' => array('avg' => array('field' => 'price')),
+ ),
+ );
+
+ $agg = new Filter('in_stock_products');
+ $agg->setFilter(new Range('stock', array('gt' => 0)));
+ $avg = new Avg('avg_price');
+ $avg->setField('price');
+ $agg->addAggregation($avg);
+
+ $this->assertEquals($expected, $agg->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilterAggregation()
+ {
+ $agg = new Filter('filter');
+ $agg->setFilter(new Term(array('color' => 'blue')));
+ $avg = new Avg('price');
+ $avg->setField('price');
+ $agg->addAggregation($avg);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('filter');
+ $results = $results['price']['value'];
+
+ $this->assertEquals((5 + 8) / 2.0, $results);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilterNoSubAggregation()
+ {
+ $agg = new Avg('price');
+ $agg->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('price');
+ $results = $results['value'];
+
+ $this->assertEquals((5 + 8 + 1 + 3) / 4.0, $results);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $agg = new Filter('foo', new Term(array('color' => 'blue')));
+
+ $expected = array(
+ 'filter' => array(
+ 'term' => array(
+ 'color' => 'blue',
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $agg->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstructWithoutFilter()
+ {
+ $agg = new Filter('foo');
+ $this->assertEquals('foo', $agg->getName());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FiltersTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FiltersTest.php
new file mode 100644
index 00000000..36ebcd45
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/FiltersTest.php
@@ -0,0 +1,120 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Avg;
+use Elastica\Aggregation\Filter;
+use Elastica\Aggregation\Filters;
+use Elastica\Document;
+use Elastica\Filter\Term;
+use Elastica\Query;
+
+class FiltersTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex('filter');
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5, 'color' => 'blue')),
+ new Document(2, array('price' => 8, 'color' => 'blue')),
+ new Document(3, array('price' => 1, 'color' => 'red')),
+ new Document(4, array('price' => 3, 'color' => 'green')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArrayUsingNamedFilters()
+ {
+ $expected = array(
+ 'filters' => array(
+ 'filters' => array(
+ 'blue' => array(
+ 'term' => array('color' => 'blue'),
+ ),
+ 'red' => array(
+ 'term' => array('color' => 'red'),
+ ),
+ ),
+ ),
+ 'aggs' => array(
+ 'avg_price' => array('avg' => array('field' => 'price')),
+ ),
+ );
+
+ $agg = new Filters('by_color');
+ $agg->addFilter(new Term(array('color' => 'blue')), 'blue');
+ $agg->addFilter(new Term(array('color' => 'red')), 'red');
+
+ $avg = new Avg('avg_price');
+ $avg->setField('price');
+ $agg->addAggregation($avg);
+
+ $this->assertEquals($expected, $agg->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArrayUsingAnonymousFilters()
+ {
+ $expected = array(
+ 'filters' => array(
+ 'filters' => array(
+ array(
+ 'term' => array('color' => 'blue'),
+ ),
+ array(
+ 'term' => array('color' => 'red'),
+ ),
+ ),
+ ),
+ 'aggs' => array(
+ 'avg_price' => array('avg' => array('field' => 'price')),
+ ),
+ );
+
+ $agg = new Filters('by_color');
+ $agg->addFilter(new Term(array('color' => 'blue')));
+ $agg->addFilter(new Term(array('color' => 'red')));
+
+ $avg = new Avg('avg_price');
+ $avg->setField('price');
+ $agg->addAggregation($avg);
+
+ $this->assertEquals($expected, $agg->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilterAggregation()
+ {
+ $agg = new Filters('by_color');
+ $agg->addFilter(new Term(array('color' => 'blue')), 'blue');
+ $agg->addFilter(new Term(array('color' => 'red')), 'red');
+
+ $avg = new Avg('avg_price');
+ $avg->setField('price');
+ $agg->addAggregation($avg);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('by_color');
+
+ $resultsForBlue = $results['buckets']['blue'];
+ $resultsForRed = $results['buckets']['red'];
+
+ $this->assertEquals(2, $resultsForBlue['doc_count']);
+ $this->assertEquals(1, $resultsForRed['doc_count']);
+
+ $this->assertEquals((5 + 8) / 2, $resultsForBlue['avg_price']['value']);
+ $this->assertEquals(1, $resultsForRed['avg_price']['value']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeoDistanceTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeoDistanceTest.php
new file mode 100644
index 00000000..f8a02d1d
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeoDistanceTest.php
@@ -0,0 +1,46 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\GeoDistance;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class GeoDistanceTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(new Mapping(null, array(
+ 'location' => array('type' => 'geo_point'),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array('location' => array('lat' => 32.849437, 'lon' => -117.271732))),
+ new Document(2, array('location' => array('lat' => 32.798320, 'lon' => -117.246648))),
+ new Document(3, array('location' => array('lat' => 37.782439, 'lon' => -122.392560))),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGeoDistanceAggregation()
+ {
+ $agg = new GeoDistance('geo', 'location', array('lat' => 32.804654, 'lon' => -117.242594));
+ $agg->addRange(null, 100);
+ $agg->setUnit('mi');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('geo');
+
+ $this->assertEquals(2, $results['buckets'][0]['doc_count']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeohashGridTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeohashGridTest.php
new file mode 100644
index 00000000..6e0d43fd
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GeohashGridTest.php
@@ -0,0 +1,46 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\GeohashGrid;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class GeohashGridTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(new Mapping(null, array(
+ 'location' => array('type' => 'geo_point'),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array('location' => array('lat' => 32.849437, 'lon' => -117.271732))),
+ new Document(2, array('location' => array('lat' => 32.798320, 'lon' => -117.246648))),
+ new Document(3, array('location' => array('lat' => 37.782439, 'lon' => -122.392560))),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGeohashGridAggregation()
+ {
+ $agg = new GeohashGrid('hash', 'location');
+ $agg->setPrecision(3);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('hash');
+
+ $this->assertEquals(2, $results['buckets'][0]['doc_count']);
+ $this->assertEquals(1, $results['buckets'][1]['doc_count']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GlobalAggregationTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GlobalAggregationTest.php
new file mode 100644
index 00000000..6ab086d0
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/GlobalAggregationTest.php
@@ -0,0 +1,27 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Avg;
+use Elastica\Aggregation\GlobalAggregation;
+
+class GlobalAggregationTest extends BaseAggregationTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $expected = array(
+ 'global' => new \stdClass(),
+ 'aggs' => array(
+ 'avg_price' => array('avg' => array('field' => 'price')),
+ ),
+ );
+
+ $agg = new GlobalAggregation('all_products');
+ $avg = new Avg('avg_price');
+ $avg->setField('price');
+ $agg->addAggregation($avg);
+ $this->assertEquals($expected, $agg->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/HistogramTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/HistogramTest.php
new file mode 100644
index 00000000..ffdf73a4
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/HistogramTest.php
@@ -0,0 +1,47 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Histogram;
+use Elastica\Document;
+use Elastica\Query;
+
+class HistogramTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5, 'color' => 'blue')),
+ new Document(2, array('price' => 8, 'color' => 'blue')),
+ new Document(3, array('price' => 1, 'color' => 'red')),
+ new Document(4, array('price' => 30, 'color' => 'green')),
+ new Document(5, array('price' => 40, 'color' => 'red')),
+ new Document(6, array('price' => 35, 'color' => 'green')),
+ new Document(7, array('price' => 42, 'color' => 'red')),
+ new Document(8, array('price' => 41, 'color' => 'blue')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testHistogramAggregation()
+ {
+ $agg = new Histogram('hist', 'price', 10);
+ $agg->setMinimumDocumentCount(0); // should return empty buckets
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('hist');
+
+ $buckets = $results['buckets'];
+ $this->assertEquals(5, sizeof($buckets));
+ $this->assertEquals(30, $buckets[3]['key']);
+ $this->assertEquals(2, $buckets[3]['doc_count']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/IpRangeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/IpRangeTest.php
new file mode 100644
index 00000000..2f3099f6
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/IpRangeTest.php
@@ -0,0 +1,57 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\IpRange;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class IpRangeTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(new Mapping(null, array(
+ 'address' => array('type' => 'ip'),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array('address' => '192.168.1.100')),
+ new Document(2, array('address' => '192.168.1.150')),
+ new Document(3, array('address' => '192.168.1.200')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testIpRangeAggregation()
+ {
+ $agg = new IpRange('ip', 'address');
+ $agg->addRange('192.168.1.101');
+ $agg->addRange(null, '192.168.1.200');
+
+ $cidrRange = '192.168.1.0/24';
+ $agg->addMaskRange($cidrRange);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('ip');
+
+ foreach ($results['buckets'] as $bucket) {
+ if (array_key_exists('key', $bucket) && $bucket['key'] == $cidrRange) {
+ // the CIDR mask
+ $this->assertEquals(3, $bucket['doc_count']);
+ } else {
+ // the normal ip ranges
+ $this->assertEquals(2, $bucket['doc_count']);
+ }
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MaxTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MaxTest.php
new file mode 100644
index 00000000..f057b81d
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MaxTest.php
@@ -0,0 +1,79 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Max;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Script;
+
+class MaxTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $expected = array(
+ 'max' => array(
+ 'field' => 'price',
+ 'script' => '_value * conversion_rate',
+ 'params' => array(
+ 'conversion_rate' => 1.2,
+ ),
+ ),
+ 'aggs' => array(
+ 'subagg' => array('max' => array('field' => 'foo')),
+ ),
+ );
+
+ $agg = new Max('min_price_in_euros');
+ $agg->setField('price');
+ $agg->setScript(new Script('_value * conversion_rate', array('conversion_rate' => 1.2)));
+ $max = new Max('subagg');
+ $max->setField('foo');
+ $agg->addAggregation($max);
+
+ $this->assertEquals($expected, $agg->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMaxAggregation()
+ {
+ $index = $this->_getIndexForTest();
+
+ $agg = new Max('min_price');
+ $agg->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $index->search($query)->getAggregation('min_price');
+
+ $this->assertEquals(8, $results['value']);
+
+ // test using a script
+ $agg->setScript(new Script('_value * conversion_rate', array('conversion_rate' => 1.2)));
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $index->search($query)->getAggregation('min_price');
+
+ $this->assertEquals(8 * 1.2, $results['value']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MinTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MinTest.php
new file mode 100644
index 00000000..ce0ad5e7
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MinTest.php
@@ -0,0 +1,40 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Min;
+use Elastica\Document;
+use Elastica\Query;
+
+class MinTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMinAggregation()
+ {
+ $agg = new Min('min_price');
+ $agg->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('min_price');
+
+ $this->assertEquals(1, $results['value']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MissingTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MissingTest.php
new file mode 100644
index 00000000..85461879
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/MissingTest.php
@@ -0,0 +1,39 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Missing;
+use Elastica\Document;
+use Elastica\Query;
+
+class MissingTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5, 'color' => 'blue')),
+ new Document(2, array('price' => 8, 'color' => 'blue')),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3, 'color' => 'green')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMissingAggregation()
+ {
+ $agg = new Missing('missing', 'color');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('missing');
+
+ $this->assertEquals(1, $results['doc_count']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/NestedTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/NestedTest.php
new file mode 100644
index 00000000..58c5d13a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/NestedTest.php
@@ -0,0 +1,63 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Min;
+use Elastica\Aggregation\Nested;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class NestedTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(new Mapping(null, array(
+ 'resellers' => array(
+ 'type' => 'nested',
+ 'properties' => array(
+ 'name' => array('type' => 'string'),
+ 'price' => array('type' => 'double'),
+ ),
+ ),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array(
+ 'resellers' => array(
+ 'name' => 'spacely sprockets',
+ 'price' => 5.55,
+ ),
+ )),
+ new Document(2, array(
+ 'resellers' => array(
+ 'name' => 'cogswell cogs',
+ 'price' => 4.98,
+ ),
+ )),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testNestedAggregation()
+ {
+ $agg = new Nested('resellers', 'resellers');
+ $min = new Min('min_price');
+ $min->setField('price');
+ $agg->addAggregation($min);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('resellers');
+
+ $this->assertEquals(4.98, $results['min_price']['value']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/PercentilesTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/PercentilesTest.php
new file mode 100644
index 00000000..ee4dd2c5
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/PercentilesTest.php
@@ -0,0 +1,125 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Percentiles;
+use Elastica\Document;
+use Elastica\Query;
+
+class PercentilesTest extends BaseAggregationTest
+{
+ /**
+ * @group functional
+ */
+ public function testConstruct()
+ {
+ $aggr = new Percentiles('price_percentile');
+ $this->assertEquals('price_percentile', $aggr->getName());
+
+ $aggr = new Percentiles('price_percentile', 'price');
+ $this->assertEquals('price', $aggr->getParam('field'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetField()
+ {
+ $aggr = new Percentiles('price_percentile');
+ $aggr->setField('price');
+
+ $this->assertEquals('price', $aggr->getParam('field'));
+ $this->assertInstanceOf('Elastica\Aggregation\Percentiles', $aggr->setField('price'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetCompression()
+ {
+ $aggr = new Percentiles('price_percentile');
+ $aggr->setCompression(200);
+ $this->assertEquals(200, $aggr->getParam('compression'));
+ $this->assertInstanceOf('Elastica\Aggregation\Percentiles', $aggr->setCompression(200));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetPercents()
+ {
+ $percents = array(1, 2, 3);
+ $aggr = new Percentiles('price_percentile');
+ $aggr->setPercents($percents);
+ $this->assertEquals($percents, $aggr->getParam('percents'));
+ $this->assertInstanceOf('Elastica\Aggregation\Percentiles', $aggr->setPercents($percents));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddPercent()
+ {
+ $percents = array(1, 2, 3);
+ $aggr = new Percentiles('price_percentile');
+ $aggr->setPercents($percents);
+ $this->assertEquals($percents, $aggr->getParam('percents'));
+ $aggr->addPercent(4);
+ $percents[] = 4;
+ $this->assertEquals($percents, $aggr->getParam('percents'));
+ $this->assertInstanceOf('Elastica\Aggregation\Percentiles', $aggr->addPercent(4));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetScript()
+ {
+ $script = 'doc["load_time"].value / 20';
+ $aggr = new Percentiles('price_percentile');
+ $aggr->setScript($script);
+ $this->assertEquals($script, $aggr->getParam('script'));
+ $this->assertInstanceOf('Elastica\Aggregation\Percentiles', $aggr->setScript($script));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testActualWork()
+ {
+ // prepare
+ $index = $this->_createIndex();
+ $type = $index->getType('offer');
+ $type->addDocuments(array(
+ new Document(1, array('price' => 100)),
+ new Document(2, array('price' => 200)),
+ new Document(3, array('price' => 300)),
+ new Document(4, array('price' => 400)),
+ new Document(5, array('price' => 500)),
+ new Document(6, array('price' => 600)),
+ new Document(7, array('price' => 700)),
+ new Document(8, array('price' => 800)),
+ new Document(9, array('price' => 900)),
+ new Document(10, array('price' => 1000)),
+ ));
+ $index->refresh();
+
+ // execute
+ $aggr = new Percentiles('price_percentile');
+ $aggr->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($aggr);
+
+ $resultSet = $type->search($query);
+ $aggrResult = $resultSet->getAggregation('price_percentile');
+
+ // hope it's ok to hardcode results...
+ $this->assertEquals(109.0, $aggrResult['values']['1.0']);
+ $this->assertEquals(145.0, $aggrResult['values']['5.0']);
+ $this->assertEquals(325.0, $aggrResult['values']['25.0']);
+ $this->assertEquals(550.0, $aggrResult['values']['50.0']);
+ $this->assertEquals(775.0, $aggrResult['values']['75.0']);
+ $this->assertEquals(955.0, $aggrResult['values']['95.0']);
+ $this->assertEquals(991.0, $aggrResult['values']['99.0']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/RangeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/RangeTest.php
new file mode 100644
index 00000000..f96e4096
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/RangeTest.php
@@ -0,0 +1,78 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Range;
+use Elastica\Document;
+use Elastica\Query;
+
+class RangeTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ new Document(5, array('price' => 1.5)),
+ new Document(6, array('price' => 2)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testRangeAggregation()
+ {
+ $agg = new Range('range');
+ $agg->setField('price');
+ $agg->addRange(1.5, 5);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('range');
+
+ $this->assertEquals(2, $results['buckets'][0]['doc_count']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testRangeAggregationWithKey()
+ {
+ $agg = new Range('range');
+ $agg->setField('price');
+ $agg->addRange(null, 50, 'cheap');
+ $agg->addRange(50, 100, 'average');
+ $agg->addRange(100, null, 'expensive');
+
+ $expected = array(
+ 'range' => array(
+ 'field' => 'price',
+ 'ranges' => array(
+ array(
+ 'to' => 50,
+ 'key' => 'cheap',
+ ),
+ array(
+ 'from' => 50,
+ 'to' => 100,
+ 'key' => 'average',
+ ),
+ array(
+ 'from' => 100,
+ 'key' => 'expensive',
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $agg->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php
new file mode 100644
index 00000000..0e2ed2e6
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ReverseNestedTest.php
@@ -0,0 +1,134 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Nested;
+use Elastica\Aggregation\ReverseNested;
+use Elastica\Aggregation\Terms;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class ReverseNestedTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $mapping = new Mapping();
+ $mapping->setProperties(array(
+ 'comments' => array(
+ 'type' => 'nested',
+ 'properties' => array(
+ 'name' => array('type' => 'string'),
+ 'body' => array('type' => 'string'),
+ ),
+ ),
+ ));
+ $type = $index->getType('test');
+ $type->setMapping($mapping);
+
+ $type->addDocuments(array(
+ new Document(1, array(
+ 'comments' => array(
+ array(
+ 'name' => 'bob',
+ 'body' => 'this is bobs comment',
+ ),
+ array(
+ 'name' => 'john',
+ 'body' => 'this is johns comment',
+ ),
+ ),
+ 'tags' => array('foo', 'bar'),
+ )),
+ new Document(2, array(
+ 'comments' => array(
+ array(
+ 'name' => 'bob',
+ 'body' => 'this is another comment from bob',
+ ),
+ array(
+ 'name' => 'susan',
+ 'body' => 'this is susans comment',
+ ),
+ ),
+ 'tags' => array('foo', 'baz'),
+ )),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testPathNotSetIfNull()
+ {
+ $agg = new ReverseNested('nested');
+ $this->assertFalse($agg->hasParam('path'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testPathSetIfNotNull()
+ {
+ $agg = new ReverseNested('nested', 'some_field');
+ $this->assertEquals('some_field', $agg->getParam('path'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testReverseNestedAggregation()
+ {
+ $agg = new Nested('comments', 'comments');
+ $names = new Terms('name');
+ $names->setField('comments.name');
+
+ $tags = new Terms('tags');
+ $tags->setField('tags');
+
+ $reverseNested = new ReverseNested('main');
+ $reverseNested->addAggregation($tags);
+
+ $names->addAggregation($reverseNested);
+
+ $agg->addAggregation($names);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('comments');
+
+ $this->assertArrayHasKey('name', $results);
+ $nameResults = $results['name'];
+
+ $this->assertCount(3, $nameResults['buckets']);
+
+ // bob
+ $this->assertEquals('bob', $nameResults['buckets'][0]['key']);
+ $tags = array(
+ array('key' => 'foo', 'doc_count' => 2),
+ array('key' => 'bar', 'doc_count' => 1),
+ array('key' => 'baz', 'doc_count' => 1),
+ );
+ $this->assertEquals($tags, $nameResults['buckets'][0]['main']['tags']['buckets']);
+
+ // john
+ $this->assertEquals('john', $nameResults['buckets'][1]['key']);
+ $tags = array(
+ array('key' => 'bar', 'doc_count' => 1),
+ array('key' => 'foo', 'doc_count' => 1),
+ );
+ $this->assertEquals($tags, $nameResults['buckets'][1]['main']['tags']['buckets']);
+
+ // susan
+ $this->assertEquals('susan', $nameResults['buckets'][2]['key']);
+ $tags = array(
+ array('key' => 'baz', 'doc_count' => 1),
+ array('key' => 'foo', 'doc_count' => 1),
+ );
+ $this->assertEquals($tags, $nameResults['buckets'][2]['main']['tags']['buckets']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptTest.php
new file mode 100644
index 00000000..bf32b251
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptTest.php
@@ -0,0 +1,87 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Sum;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Script;
+
+class ScriptTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document('1', array('price' => 5)),
+ new Document('2', array('price' => 8)),
+ new Document('3', array('price' => 1)),
+ new Document('4', array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregationScript()
+ {
+ $agg = new Sum('sum');
+ // x = (0..1) is groovy-specific syntax, to see if lang is recognized
+ $script = new Script("x = (0..1); return doc['price'].value", null, 'groovy');
+ $agg->setScript($script);
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('sum');
+
+ $this->assertEquals(5 + 8 + 1 + 3, $results['value']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregationScriptAsString()
+ {
+ $agg = new Sum('sum');
+ $agg->setScript("doc['price'].value");
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('sum');
+
+ $this->assertEquals(5 + 8 + 1 + 3, $results['value']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScript()
+ {
+ $aggregation = 'sum';
+ $string = "doc['price'].value";
+ $params = array(
+ 'param1' => 'one',
+ 'param2' => 1,
+ );
+ $lang = 'groovy';
+
+ $agg = new Sum($aggregation);
+ $script = new Script($string, $params, $lang);
+ $agg->setScript($script);
+
+ $array = $agg->toArray();
+
+ $expected = array(
+ $aggregation => array(
+ 'script' => $string,
+ 'params' => $params,
+ 'lang' => $lang,
+ ),
+ );
+ $this->assertEquals($expected, $array);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptedMetricTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptedMetricTest.php
new file mode 100644
index 00000000..31f5798b
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ScriptedMetricTest.php
@@ -0,0 +1,50 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\ScriptedMetric;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Type\Mapping;
+
+class ScriptedMetricTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(new Mapping(null, array(
+ 'start' => array('type' => 'long'),
+ 'end' => array('type' => 'long'),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array('start' => 100, 'end' => 200)),
+ new Document(2, array('start' => 200, 'end' => 250)),
+ new Document(3, array('start' => 300, 'end' => 450)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testScriptedMetricAggregation()
+ {
+ $agg = new ScriptedMetric(
+ 'scripted',
+ "_agg['durations'] = [:]",
+ "key = doc['start'].value+ \":\"+ doc['end'].value; _agg.durations[key] = doc['end'].value - doc['start'].value;",
+ 'values = []; for (item in _agg.durations) { values.add(item.value) }; return values'
+ );
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('scripted');
+
+ $this->assertEquals(array(100, 50, 150), $results['value'][0]);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SignificantTermsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SignificantTermsTest.php
new file mode 100644
index 00000000..8960768b
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SignificantTermsTest.php
@@ -0,0 +1,72 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\SignificantTerms;
+use Elastica\Document;
+use Elastica\Filter\Terms as TermsFilter;
+use Elastica\Query;
+use Elastica\Query\Terms;
+
+class SignificantTermsTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $colors = array('blue', 'blue', 'red', 'red', 'green', 'yellow', 'white', 'cyan', 'magenta');
+ $temperatures = array(1500, 1500, 1500, 1500, 2500, 3500, 4500, 5500, 6500, 7500, 7500, 8500, 9500);
+ $docs = array();
+ for ($i = 0;$i < 250;$i++) {
+ $docs[] = new Document($i, array('color' => $colors[$i % count($colors)], 'temperature' => $temperatures[$i % count($temperatures)]));
+ }
+ $index->getType('test')->addDocuments($docs);
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSignificantTermsAggregation()
+ {
+ $agg = new SignificantTerms('significantTerms');
+ $agg->setField('temperature');
+ $agg->setSize(1);
+
+ $termsQuery = new Terms();
+ $termsQuery->setTerms('color', array('blue', 'red', 'green', 'yellow', 'white'));
+
+ $query = new Query($termsQuery);
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('significantTerms');
+
+ $this->assertEquals(1, count($results['buckets']));
+ $this->assertEquals(63, $results['buckets'][0]['doc_count']);
+ $this->assertEquals(79, $results['buckets'][0]['bg_count']);
+ $this->assertEquals('1500', $results['buckets'][0]['key_as_string']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSignificantTermsAggregationWithBackgroundFilter()
+ {
+ $agg = new SignificantTerms('significantTerms');
+ $agg->setField('temperature');
+ $agg->setSize(1);
+ $termsFilter = new TermsFilter();
+ $termsFilter->setTerms('color', array('blue', 'red', 'green', 'yellow'));
+ $agg->setBackgroundFilter($termsFilter);
+
+ $termsQuery = new Terms();
+ $termsQuery->setTerms('color', array('blue', 'red', 'green', 'yellow', 'white'));
+
+ $query = new Query($termsQuery);
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('significantTerms');
+
+ $this->assertEquals(15, $results['buckets'][0]['doc_count']);
+ $this->assertEquals(12, $results['buckets'][0]['bg_count']);
+ $this->assertEquals('4500', $results['buckets'][0]['key_as_string']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/StatsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/StatsTest.php
new file mode 100644
index 00000000..45c9d08c
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/StatsTest.php
@@ -0,0 +1,44 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Stats;
+use Elastica\Document;
+use Elastica\Query;
+
+class StatsTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testStatsAggregation()
+ {
+ $agg = new Stats('stats');
+ $agg->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('stats');
+
+ $this->assertEquals(4, $results['count']);
+ $this->assertEquals(1, $results['min']);
+ $this->assertEquals(8, $results['max']);
+ $this->assertEquals((5 + 8 + 1 + 3) / 4.0, $results['avg']);
+ $this->assertEquals((5 + 8 + 1 + 3), $results['sum']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SumTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SumTest.php
new file mode 100644
index 00000000..b60e6e14
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/SumTest.php
@@ -0,0 +1,40 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Sum;
+use Elastica\Document;
+use Elastica\Query;
+
+class SumTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSumAggregation()
+ {
+ $agg = new Sum('sum');
+ $agg->setField('price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('sum');
+
+ $this->assertEquals(5 + 8 + 1 + 3, $results['value']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TermsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TermsTest.php
new file mode 100644
index 00000000..58eb02c2
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TermsTest.php
@@ -0,0 +1,41 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Terms;
+use Elastica\Document;
+use Elastica\Query;
+
+class TermsTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('color' => 'blue')),
+ new Document(2, array('color' => 'blue')),
+ new Document(3, array('color' => 'red')),
+ new Document(4, array('color' => 'green')),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testTermsAggregation()
+ {
+ $agg = new Terms('terms');
+ $agg->setField('color');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('terms');
+
+ $this->assertEquals(2, $results['buckets'][0]['doc_count']);
+ $this->assertEquals('blue', $results['buckets'][0]['key']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TopHitsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TopHitsTest.php
new file mode 100644
index 00000000..afe23e27
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/TopHitsTest.php
@@ -0,0 +1,385 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\Terms;
+use Elastica\Aggregation\TopHits;
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Query\SimpleQueryString;
+use Elastica\Script;
+use Elastica\ScriptFields;
+
+class TopHitsTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('questions')->addDocuments(array(
+ new Document(1, array(
+ 'tags' => array('linux'),
+ 'last_activity_date' => '2015-01-05',
+ 'title' => 'Question about linux #1',
+ )),
+ new Document(2, array(
+ 'tags' => array('linux'),
+ 'last_activity_date' => '2014-12-23',
+ 'title' => 'Question about linux #2',
+ )),
+ new Document(3, array(
+ 'tags' => array('windows'),
+ 'last_activity_date' => '2015-01-05',
+ 'title' => 'Question about windows #1',
+ )),
+ new Document(4, array(
+ 'tags' => array('windows'),
+ 'last_activity_date' => '2014-12-23',
+ 'title' => 'Question about windows #2',
+ )),
+ new Document(5, array(
+ 'tags' => array('osx', 'apple'),
+ 'last_activity_date' => '2014-12-23',
+ 'title' => 'Question about osx',
+ )),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSize()
+ {
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setSize(12);
+ $this->assertEquals(12, $agg->getParam('size'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetFrom()
+ {
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setFrom(12);
+ $this->assertEquals(12, $agg->getParam('from'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSort()
+ {
+ $sort = array('last_activity_date' => array('order' => 'desc'));
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setSort($sort);
+ $this->assertEquals($sort, $agg->getParam('sort'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSource()
+ {
+ $fields = array('title', 'tags');
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setSource($fields);
+ $this->assertEquals($fields, $agg->getParam('_source'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetVersion()
+ {
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setVersion(true);
+ $this->assertTrue($agg->getParam('version'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+
+ $agg->setVersion(false);
+ $this->assertFalse($agg->getParam('version'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetExplain()
+ {
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setExplain(true);
+ $this->assertTrue($agg->getParam('explain'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+
+ $agg->setExplain(false);
+ $this->assertFalse($agg->getParam('explain'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetHighlight()
+ {
+ $highlight = array(
+ 'fields' => array(
+ 'title',
+ ),
+ );
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setHighlight($highlight);
+ $this->assertEquals($highlight, $agg->getParam('highlight'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetFieldDataFields()
+ {
+ $fields = array('title', 'tags');
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setFieldDataFields($fields);
+ $this->assertEquals($fields, $agg->getParam('fielddata_fields'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScriptFields()
+ {
+ $script = new Script('1 + 2');
+ $scriptFields = new ScriptFields(array('three' => $script));
+
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->setScriptFields($scriptFields);
+ $this->assertEquals($scriptFields->toArray(), $agg->getParam('script_fields'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddScriptField()
+ {
+ $script = new Script('2+3');
+ $agg = new TopHits('agg_name');
+ $returnValue = $agg->addScriptField('five', $script);
+ $this->assertEquals(array('five' => $script->toArray()), $agg->getParam('script_fields'));
+ $this->assertInstanceOf('Elastica\Aggregation\TopHits', $returnValue);
+ }
+
+ protected function getOuterAggregationResult($innerAggr)
+ {
+ $outerAggr = new Terms('top_tags');
+ $outerAggr->setField('tags');
+ $outerAggr->setMinimumDocumentCount(2);
+ $outerAggr->addAggregation($innerAggr);
+
+ $query = new Query(new MatchAll());
+ $query->addAggregation($outerAggr);
+
+ return $this->_getIndexForTest()->search($query)->getAggregation('top_tags');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateUpdatedRecently()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setSize(1);
+ $aggr->setSort(array('last_activity_date' => array('order' => 'desc')));
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $resultDocs[] = $doc['_id'];
+ }
+ }
+ $this->assertEquals(array(1, 3), $resultDocs);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateUpdatedFarAgo()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setSize(1);
+ $aggr->setSort(array('last_activity_date' => array('order' => 'asc')));
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $resultDocs[] = $doc['_id'];
+ }
+ }
+ $this->assertEquals(array(2, 4), $resultDocs);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateTwoDocumentPerTag()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setSize(2);
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $resultDocs[] = $doc['_id'];
+ }
+ }
+ $this->assertEquals(array(1, 2, 3, 4), $resultDocs);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateTwoDocumentPerTagWithOffset()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setSize(2);
+ $aggr->setFrom(1);
+ $aggr->setSort(array('last_activity_date' => array('order' => 'desc')));
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $resultDocs[] = $doc['_id'];
+ }
+ }
+ $this->assertEquals(array(2, 4), $resultDocs);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateWithLimitedSource()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setSource(array('title'));
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $this->assertArrayHasKey('title', $doc['_source']);
+ $this->assertArrayNotHasKey('tags', $doc['_source']);
+ $this->assertArrayNotHasKey('last_activity_date', $doc['_source']);
+ }
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateWithVersion()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setVersion(true);
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $this->assertArrayHasKey('_version', $doc);
+ }
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateWithExplain()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setExplain(true);
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $this->assertArrayHasKey('_explanation', $doc);
+ }
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateWithScriptFields()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setSize(1);
+ $aggr->setScriptFields(array('three' => new Script('1 + 2')));
+ $aggr->addScriptField('five', new Script('3 + 2'));
+
+ $resultDocs = array();
+ $outerAggrResult = $this->getOuterAggregationResult($aggr);
+ foreach ($outerAggrResult['buckets'] as $bucket) {
+ foreach ($bucket['top_tag_hits']['hits']['hits'] as $doc) {
+ $this->assertEquals(3, $doc['fields']['three'][0]);
+ $this->assertEquals(5, $doc['fields']['five'][0]);
+ }
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateWithHighlight()
+ {
+ $queryString = new SimpleQueryString('linux', array('title'));
+
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setHighlight(array('fields' => array('title' => new \stdClass())));
+
+ $query = new Query($queryString);
+ $query->addAggregation($aggr);
+
+ $resultSet = $this->_getIndexForTest()->search($query);
+ $aggrResult = $resultSet->getAggregation('top_tag_hits');
+
+ foreach ($aggrResult['hits']['hits'] as $doc) {
+ $this->assertArrayHasKey('highlight', $doc);
+ $this->assertRegExp('#<em>linux</em>#', $doc['highlight']['title'][0]);
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAggregateWithFieldData()
+ {
+ $aggr = new TopHits('top_tag_hits');
+ $aggr->setFieldDataFields(array('title'));
+
+ $query = new Query(new MatchAll());
+ $query->addAggregation($aggr);
+
+ $resultSet = $this->_getIndexForTest()->search($query);
+ $aggrResult = $resultSet->getAggregation('top_tag_hits');
+
+ foreach ($aggrResult['hits']['hits'] as $doc) {
+ $this->assertArrayHasKey('fields', $doc);
+ $this->assertArrayHasKey('title', $doc['fields']);
+ $this->assertArrayNotHasKey('tags', $doc['fields']);
+ $this->assertArrayNotHasKey('last_activity_date', $doc['fields']);
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ValueCountTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ValueCountTest.php
new file mode 100644
index 00000000..21b63cbe
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Aggregation/ValueCountTest.php
@@ -0,0 +1,40 @@
+<?php
+namespace Elastica\Test\Aggregation;
+
+use Elastica\Aggregation\ValueCount;
+use Elastica\Document;
+use Elastica\Query;
+
+class ValueCountTest extends BaseAggregationTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ $index->getType('test')->addDocuments(array(
+ new Document(1, array('price' => 5)),
+ new Document(2, array('price' => 8)),
+ new Document(3, array('price' => 1)),
+ new Document(4, array('price' => 3)),
+ new Document(5, array('price' => 3)),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testValueCountAggregation()
+ {
+ $agg = new ValueCount('count', 'price');
+
+ $query = new Query();
+ $query->addAggregation($agg);
+ $results = $this->_getIndexForTest()->search($query)->getAggregation('count');
+
+ $this->assertEquals(5, $results['value']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Base.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Base.php
new file mode 100644
index 00000000..c826c747
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Base.php
@@ -0,0 +1,142 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Client;
+use Elastica\Connection;
+use Elastica\Index;
+
+class Base extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @param array $params Additional configuration params. Host and Port are already set
+ * @param callback $callback
+ *
+ * @return Client
+ */
+ protected function _getClient(array $params = array(), $callback = null)
+ {
+ $config = array(
+ 'host' => $this->_getHost(),
+ 'port' => $this->_getPort(),
+ );
+
+ $config = array_merge($config, $params);
+
+ return new Client($config, $callback);
+ }
+
+ /**
+ * @return string Host to es for elastica tests
+ */
+ protected function _getHost()
+ {
+ return getenv('ES_HOST') ?: Connection::DEFAULT_HOST;
+ }
+
+ /**
+ * @return int Port to es for elastica tests
+ */
+ protected function _getPort()
+ {
+ return getenv('ES_PORT') ?: Connection::DEFAULT_PORT;
+ }
+
+ /**
+ * @return string Proxy url string
+ */
+ protected function _getProxyUrl()
+ {
+ $proxyHost = getenv('PROXY_HOST') ?: Connection::DEFAULT_HOST;
+
+ return 'http://'.$proxyHost.':12345';
+ }
+
+ /**
+ * @return string Proxy url string to proxy which returns 403
+ */
+ protected function _getProxyUrl403()
+ {
+ $proxyHost = getenv('PROXY_HOST') ?: Connection::DEFAULT_HOST;
+
+ return 'http://'.$proxyHost.':12346';
+ }
+
+ /**
+ * @param string $name Index name
+ * @param bool $delete Delete index if it exists
+ * @param int $shards Number of shards to create
+ *
+ * @return \Elastica\Index
+ */
+ protected function _createIndex($name = null, $delete = true, $shards = 1)
+ {
+ if (is_null($name)) {
+ $name = preg_replace('/[^a-z]/i', '', strtolower(get_called_class())).uniqid();
+ }
+
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_'.$name);
+ $index->create(array('index' => array('number_of_shards' => $shards, 'number_of_replicas' => 0)), $delete);
+
+ return $index;
+ }
+
+ protected function _waitForAllocation(Index $index)
+ {
+ do {
+ $settings = $index->getStatus()->get();
+ $allocated = true;
+ foreach ($settings['shards'] as $shard) {
+ if ($shard[0]['routing']['state'] != 'STARTED') {
+ $allocated = false;
+ }
+ }
+ } while (!$allocated);
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $hasGroup = $this->_isUnitGroup() || $this->_isFunctionalGroup() || $this->_isShutdownGroup() || $this->_isBenchmarkGroup();
+ $this->assertTrue($hasGroup, 'Every test must have one of "unit", "functional", "shutdown" or "benchmark" group');
+ }
+
+ protected function tearDown()
+ {
+ if ($this->_isFunctionalGroup()) {
+ $this->_getClient()->getIndex('_all')->delete();
+ $this->_getClient()->getIndex('_all')->clearCache();
+ }
+
+ parent::tearDown();
+ }
+
+ protected function _isUnitGroup()
+ {
+ $groups = \PHPUnit_Util_Test::getGroups(get_class($this), $this->getName(false));
+
+ return in_array('unit', $groups);
+ }
+
+ protected function _isFunctionalGroup()
+ {
+ $groups = \PHPUnit_Util_Test::getGroups(get_class($this), $this->getName(false));
+
+ return in_array('functional', $groups);
+ }
+
+ protected function _isShutdownGroup()
+ {
+ $groups = \PHPUnit_Util_Test::getGroups(get_class($this), $this->getName(false));
+
+ return in_array('shutdown', $groups);
+ }
+
+ protected function _isBenchmarkGroup()
+ {
+ $groups = \PHPUnit_Util_Test::getGroups(get_class($this), $this->getName(false));
+
+ return in_array('benchmark', $groups);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ActionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ActionTest.php
new file mode 100644
index 00000000..e4588e70
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ActionTest.php
@@ -0,0 +1,66 @@
+<?php
+namespace Elastica\Test\Bulk;
+
+use Elastica\Bulk\Action;
+use Elastica\Index;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+
+class ActionTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testAction()
+ {
+ $action = new Action();
+ $this->assertEquals('index', $action->getOpType());
+ $this->assertFalse($action->hasSource());
+
+ $expected = '{"index":{}}'."\n";
+ $this->assertEquals($expected, $action->toString());
+
+ $action->setIndex('index');
+
+ $expected = '{"index":{"_index":"index"}}'."\n";
+ $this->assertEquals($expected, $action->toString());
+
+ $action->setType('type');
+
+ $expected = '{"index":{"_index":"index","_type":"type"}}'."\n";
+ $this->assertEquals($expected, $action->toString());
+
+ $action->setId(1);
+ $expected = '{"index":{"_index":"index","_type":"type","_id":1}}'."\n";
+ $this->assertEquals($expected, $action->toString());
+
+ $action->setRouting(1);
+ $expected = '{"index":{"_index":"index","_type":"type","_id":1,"_routing":1}}'."\n";
+ $this->assertEquals($expected, $action->toString());
+
+ $client = $this->_getClient();
+ $index = new Index($client, 'index2');
+ $type = new Type($index, 'type2');
+
+ $action->setIndex($index);
+
+ $expected = '{"index":{"_index":"index2","_type":"type","_id":1,"_routing":1}}'."\n";
+ $this->assertEquals($expected, $action->toString());
+
+ $action->setType($type);
+
+ $expected = '{"index":{"_index":"index2","_type":"type2","_id":1,"_routing":1}}'."\n";
+ $this->assertEquals($expected, $action->toString());
+
+ $action->setSource(array('user' => 'name'));
+
+ $expected = '{"index":{"_index":"index2","_type":"type2","_id":1,"_routing":1}}'."\n";
+ $expected .= '{"user":"name"}'."\n";
+
+ $this->assertEquals($expected, $action->toString());
+ $this->assertTrue($action->hasSource());
+
+ $this->assertFalse(Action::isValidOpType('foo'));
+ $this->assertTrue(Action::isValidOpType('delete'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ResponseSetTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ResponseSetTest.php
new file mode 100644
index 00000000..949dcf7a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Bulk/ResponseSetTest.php
@@ -0,0 +1,200 @@
+<?php
+namespace Elastica\Test\Bulk;
+
+use Elastica\Bulk;
+use Elastica\Bulk\Action;
+use Elastica\Exception\Bulk\ResponseException;
+use Elastica\Response;
+use Elastica\Test\Base as BaseTest;
+
+class ResponseSetTest extends BaseTest
+{
+ /**
+ * @group unit
+ * @dataProvider isOkDataProvider
+ */
+ public function testIsOk($responseData, $actions, $expected)
+ {
+ $responseSet = $this->_createResponseSet($responseData, $actions);
+ $this->assertEquals($expected, $responseSet->isOk());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetError()
+ {
+ list($responseData, $actions) = $this->_getFixture();
+ $responseData['items'][1]['index']['ok'] = false;
+ $responseData['items'][1]['index']['error'] = 'SomeExceptionMessage';
+ $responseData['items'][2]['index']['ok'] = false;
+ $responseData['items'][2]['index']['error'] = 'AnotherExceptionMessage';
+
+ try {
+ $this->_createResponseSet($responseData, $actions);
+ $this->fail('Bulk request should fail');
+ } catch (ResponseException $e) {
+ $responseSet = $e->getResponseSet();
+
+ $this->assertInstanceOf('Elastica\\Bulk\\ResponseSet', $responseSet);
+
+ $this->assertTrue($responseSet->hasError());
+ $this->assertNotEquals('AnotherExceptionMessage', $responseSet->getError());
+ $this->assertEquals('SomeExceptionMessage', $responseSet->getError());
+
+ $actionExceptions = $e->getActionExceptions();
+ $this->assertEquals(2, count($actionExceptions));
+
+ $this->assertInstanceOf('Elastica\Exception\Bulk\Response\ActionException', $actionExceptions[0]);
+ $this->assertSame($actions[1], $actionExceptions[0]->getAction());
+ $this->assertContains('SomeExceptionMessage', $actionExceptions[0]->getMessage());
+ $this->assertTrue($actionExceptions[0]->getResponse()->hasError());
+
+ $this->assertInstanceOf('Elastica\Exception\Bulk\Response\ActionException', $actionExceptions[1]);
+ $this->assertSame($actions[2], $actionExceptions[1]->getAction());
+ $this->assertContains('AnotherExceptionMessage', $actionExceptions[1]->getMessage());
+ $this->assertTrue($actionExceptions[1]->getResponse()->hasError());
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetBulkResponses()
+ {
+ list($responseData, $actions) = $this->_getFixture();
+
+ $responseSet = $this->_createResponseSet($responseData, $actions);
+
+ $bulkResponses = $responseSet->getBulkResponses();
+ $this->assertInternalType('array', $bulkResponses);
+ $this->assertEquals(3, count($bulkResponses));
+
+ foreach ($bulkResponses as $i => $bulkResponse) {
+ $this->assertInstanceOf('Elastica\\Bulk\\Response', $bulkResponse);
+ $bulkResponseData = $bulkResponse->getData();
+ $this->assertInternalType('array', $bulkResponseData);
+ $this->assertArrayHasKey('_id', $bulkResponseData);
+ $this->assertEquals($responseData['items'][$i]['index']['_id'], $bulkResponseData['_id']);
+ $this->assertSame($actions[$i], $bulkResponse->getAction());
+ $this->assertEquals('index', $bulkResponse->getOpType());
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIterator()
+ {
+ list($responseData, $actions) = $this->_getFixture();
+
+ $responseSet = $this->_createResponseSet($responseData, $actions);
+
+ $this->assertEquals(3, count($responseSet));
+
+ foreach ($responseSet as $i => $bulkResponse) {
+ $this->assertInstanceOf('Elastica\Bulk\Response', $bulkResponse);
+ $bulkResponseData = $bulkResponse->getData();
+ $this->assertInternalType('array', $bulkResponseData);
+ $this->assertArrayHasKey('_id', $bulkResponseData);
+ $this->assertEquals($responseData['items'][$i]['index']['_id'], $bulkResponseData['_id']);
+ $this->assertSame($actions[$i], $bulkResponse->getAction());
+ $this->assertEquals('index', $bulkResponse->getOpType());
+ }
+
+ $this->assertFalse($responseSet->valid());
+ $this->assertNotInstanceOf('Elastica\Bulk\Response', $responseSet->current());
+ $this->assertFalse($responseSet->current());
+
+ $responseSet->next();
+
+ $this->assertFalse($responseSet->valid());
+ $this->assertNotInstanceOf('Elastica\Bulk\Response', $responseSet->current());
+ $this->assertFalse($responseSet->current());
+
+ $responseSet->rewind();
+
+ $this->assertEquals(0, $responseSet->key());
+ $this->assertTrue($responseSet->valid());
+ $this->assertInstanceOf('Elastica\Bulk\Response', $responseSet->current());
+ }
+
+ public function isOkDataProvider()
+ {
+ list($responseData, $actions) = $this->_getFixture();
+
+ $return = array();
+ $return[] = array($responseData, $actions, true);
+ $responseData['items'][2]['index']['ok'] = false;
+ $return[] = array($responseData, $actions, false);
+
+ return $return;
+ }
+
+ /**
+ * @param array $responseData
+ * @param array $actions
+ *
+ * @return \Elastica\Bulk\ResponseSet
+ */
+ protected function _createResponseSet(array $responseData, array $actions)
+ {
+ $client = $this->getMock('Elastica\\Client', array('request'));
+
+ $client->expects($this->once())
+ ->method('request')
+ ->withAnyParameters()
+ ->will($this->returnValue(new Response($responseData)));
+
+ $bulk = new Bulk($client);
+ $bulk->addActions($actions);
+
+ return $bulk->send();
+ }
+
+ /**
+ * @return array
+ */
+ protected function _getFixture()
+ {
+ $responseData = array(
+ 'took' => 5,
+ 'items' => array(
+ array(
+ 'index' => array(
+ '_index' => 'index',
+ '_type' => 'type',
+ '_id' => '1',
+ '_version' => 1,
+ 'ok' => true,
+ ),
+ ),
+ array(
+ 'index' => array(
+ '_index' => 'index',
+ '_type' => 'type',
+ '_id' => '2',
+ '_version' => 1,
+ 'ok' => true,
+ ),
+ ),
+ array(
+ 'index' => array(
+ '_index' => 'index',
+ '_type' => 'type',
+ '_id' => '3',
+ '_version' => 1,
+ 'ok' => true,
+ ),
+ ),
+ ),
+ );
+ $bulkResponses = array(
+ new Action(),
+ new Action(),
+ new Action(),
+ );
+
+ return array($responseData, $bulkResponses);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/BulkTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/BulkTest.php
new file mode 100644
index 00000000..c3ff15bc
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/BulkTest.php
@@ -0,0 +1,792 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Bulk;
+use Elastica\Bulk\Action;
+use Elastica\Bulk\Action\AbstractDocument;
+use Elastica\Document;
+use Elastica\Exception\Bulk\ResponseException;
+use Elastica\Exception\NotFoundException;
+use Elastica\Filter\Script;
+use Elastica\Test\Base as BaseTest;
+
+class BulkTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testSend()
+ {
+ $index = $this->_createIndex();
+ $indexName = $index->getName();
+ $type = $index->getType('bulk_test');
+ $type2 = $index->getType('bulk_test2');
+ $client = $index->getClient();
+
+ $newDocument1 = $type->createDocument(1, array('name' => 'Mister Fantastic'));
+ $newDocument2 = new Document(2, array('name' => 'Invisible Woman'));
+ $newDocument3 = $type->createDocument(3, array('name' => 'The Human Torch'));
+ $newDocument4 = $type->createDocument(null, array('name' => 'The Thing'));
+
+ $newDocument3->setOpType(Document::OP_TYPE_CREATE);
+
+ $documents = array(
+ $newDocument1,
+ $newDocument2,
+ $newDocument3,
+ $newDocument4,
+ );
+
+ $bulk = new Bulk($client);
+ $bulk->setType($type2);
+ $bulk->addDocuments($documents);
+
+ $actions = $bulk->getActions();
+
+ $this->assertInstanceOf('Elastica\Bulk\Action\IndexDocument', $actions[0]);
+ $this->assertEquals('index', $actions[0]->getOpType());
+ $this->assertSame($newDocument1, $actions[0]->getDocument());
+
+ $this->assertInstanceOf('Elastica\Bulk\Action\IndexDocument', $actions[1]);
+ $this->assertEquals('index', $actions[1]->getOpType());
+ $this->assertSame($newDocument2, $actions[1]->getDocument());
+
+ $this->assertInstanceOf('Elastica\Bulk\Action\CreateDocument', $actions[2]);
+ $this->assertEquals('create', $actions[2]->getOpType());
+ $this->assertSame($newDocument3, $actions[2]->getDocument());
+
+ $this->assertInstanceOf('Elastica\Bulk\Action\IndexDocument', $actions[3]);
+ $this->assertEquals('index', $actions[3]->getOpType());
+ $this->assertSame($newDocument4, $actions[3]->getDocument());
+
+ $data = $bulk->toArray();
+
+ $expected = array(
+ array('index' => array('_index' => $indexName, '_type' => 'bulk_test', '_id' => 1)),
+ array('name' => 'Mister Fantastic'),
+ array('index' => array('_id' => 2)),
+ array('name' => 'Invisible Woman'),
+ array('create' => array('_index' => $indexName, '_type' => 'bulk_test', '_id' => 3)),
+ array('name' => 'The Human Torch'),
+ array('index' => array('_index' => $indexName, '_type' => 'bulk_test')),
+ array('name' => 'The Thing'),
+ );
+ $this->assertEquals($expected, $data);
+
+ $expected = '{"index":{"_index":"'.$indexName.'","_type":"bulk_test","_id":1}}
+{"name":"Mister Fantastic"}
+{"index":{"_id":2}}
+{"name":"Invisible Woman"}
+{"create":{"_index":"'.$indexName.'","_type":"bulk_test","_id":3}}
+{"name":"The Human Torch"}
+{"index":{"_index":"'.$indexName.'","_type":"bulk_test"}}
+{"name":"The Thing"}
+';
+
+ $expected = str_replace(PHP_EOL, "\n", $expected);
+ $this->assertEquals($expected, (string) str_replace(PHP_EOL, "\n", (string) $bulk));
+
+ $response = $bulk->send();
+
+ $this->assertInstanceOf('Elastica\Bulk\ResponseSet', $response);
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ foreach ($response as $i => $bulkResponse) {
+ $this->assertInstanceOf('Elastica\Bulk\Response', $bulkResponse);
+ $this->assertTrue($bulkResponse->isOk());
+ $this->assertFalse($bulkResponse->hasError());
+ $this->assertSame($actions[$i], $bulkResponse->getAction());
+ }
+
+ $type->getIndex()->refresh();
+ $type2->getIndex()->refresh();
+
+ $this->assertEquals(3, $type->count());
+ $this->assertEquals(1, $type2->count());
+
+ $bulk = new Bulk($client);
+ $bulk->addDocument($newDocument3, Action::OP_TYPE_DELETE);
+
+ $data = $bulk->toArray();
+
+ $expected = array(
+ array('delete' => array('_index' => $indexName, '_type' => 'bulk_test', '_id' => 3)),
+ );
+ $this->assertEquals($expected, $data);
+
+ $bulk->send();
+
+ $type->getIndex()->refresh();
+
+ $this->assertEquals(2, $type->count());
+
+ try {
+ $type->getDocument(3);
+ $this->fail('Document #3 should be deleted');
+ } catch (NotFoundException $e) {
+ $this->assertTrue(true);
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUnicodeBulkSend()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('bulk_test');
+ $type2 = $index->getType('bulk_test2');
+ $client = $index->getClient();
+
+ $newDocument1 = $type->createDocument(1, array('name' => 'Сегодня, я вижу, особенно грустен твой взгляд,'));
+ $newDocument2 = new Document(2, array('name' => 'И руки особенно тонки, колени обняв.'));
+ $newDocument3 = $type->createDocument(3, array('name' => 'Послушай: далеко, далеко, на озере Чад / Изысканный бродит жираф.'));
+
+ $documents = array(
+ $newDocument1,
+ $newDocument2,
+ $newDocument3,
+ );
+
+ $bulk = new Bulk($client);
+ $bulk->setType($type2);
+ $bulk->addDocuments($documents);
+
+ $actions = $bulk->getActions();
+
+ $this->assertSame($newDocument1, $actions[0]->getDocument());
+ $this->assertSame($newDocument2, $actions[1]->getDocument());
+ $this->assertSame($newDocument3, $actions[2]->getDocument());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetIndexType()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('index');
+ $type = $index->getType('type');
+
+ $index2 = $client->getIndex('index2');
+ $type2 = $index2->getType('type2');
+
+ $bulk = new Bulk($client);
+
+ $this->assertFalse($bulk->hasIndex());
+ $this->assertFalse($bulk->hasType());
+
+ $bulk->setIndex($index);
+ $this->assertTrue($bulk->hasIndex());
+ $this->assertFalse($bulk->hasType());
+ $this->assertEquals('index', $bulk->getIndex());
+
+ $bulk->setType($type2);
+ $this->assertTrue($bulk->hasIndex());
+ $this->assertTrue($bulk->hasType());
+ $this->assertEquals('index2', $bulk->getIndex());
+ $this->assertEquals('type2', $bulk->getType());
+
+ $bulk->setType($type);
+ $this->assertTrue($bulk->hasIndex());
+ $this->assertTrue($bulk->hasType());
+ $this->assertEquals('index', $bulk->getIndex());
+ $this->assertEquals('type', $bulk->getType());
+
+ $bulk->setIndex($index2);
+ $this->assertTrue($bulk->hasIndex());
+ $this->assertTrue($bulk->hasType());
+ $this->assertEquals('index2', $bulk->getIndex());
+ $this->assertEquals('type', $bulk->getType());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddActions()
+ {
+ $client = $this->_getClient();
+ $bulk = new Bulk($client);
+
+ $action1 = new Action(Action::OP_TYPE_DELETE);
+ $action1->setIndex('index');
+ $action1->setType('type');
+ $action1->setId(1);
+
+ $action2 = new Action(Action::OP_TYPE_INDEX);
+ $action2->setIndex('index');
+ $action2->setType('type');
+ $action2->setId(1);
+ $action2->setSource(array('name' => 'Batman'));
+
+ $actions = array(
+ $action1,
+ $action2,
+ );
+
+ $bulk->addActions($actions);
+
+ $getActions = $bulk->getActions();
+
+ $this->assertSame($action1, $getActions[0]);
+ $this->assertSame($action2, $getActions[1]);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddRawData()
+ {
+ $bulk = new Bulk($this->_getClient());
+
+ $rawData = array(
+ array('index' => array('_index' => 'test', '_type' => 'user', '_id' => '1')),
+ array('user' => array('name' => 'hans')),
+ array('delete' => array('_index' => 'test', '_type' => 'user', '_id' => '2')),
+ array('delete' => array('_index' => 'test', '_type' => 'user', '_id' => '3')),
+ array('create' => array('_index' => 'test', '_type' => 'user', '_id' => '4')),
+ array('user' => array('name' => 'mans')),
+ array('delete' => array('_index' => 'test', '_type' => 'user', '_id' => '5')),
+ );
+
+ $bulk->addRawData($rawData);
+
+ $actions = $bulk->getActions();
+
+ $this->assertInternalType('array', $actions);
+ $this->assertEquals(5, count($actions));
+
+ $this->assertInstanceOf('Elastica\Bulk\Action', $actions[0]);
+ $this->assertEquals('index', $actions[0]->getOpType());
+ $this->assertEquals($rawData[0]['index'], $actions[0]->getMetadata());
+ $this->assertTrue($actions[0]->hasSource());
+ $this->assertEquals($rawData[1], $actions[0]->getSource());
+
+ $this->assertInstanceOf('Elastica\Bulk\Action', $actions[1]);
+ $this->assertEquals('delete', $actions[1]->getOpType());
+ $this->assertEquals($rawData[2]['delete'], $actions[1]->getMetadata());
+ $this->assertFalse($actions[1]->hasSource());
+
+ $this->assertInstanceOf('Elastica\Bulk\Action', $actions[2]);
+ $this->assertEquals('delete', $actions[2]->getOpType());
+ $this->assertEquals($rawData[3]['delete'], $actions[2]->getMetadata());
+ $this->assertFalse($actions[2]->hasSource());
+
+ $this->assertInstanceOf('Elastica\Bulk\Action', $actions[3]);
+ $this->assertEquals('create', $actions[3]->getOpType());
+ $this->assertEquals($rawData[4]['create'], $actions[3]->getMetadata());
+ $this->assertTrue($actions[3]->hasSource());
+ $this->assertEquals($rawData[5], $actions[3]->getSource());
+
+ $this->assertInstanceOf('Elastica\Bulk\Action', $actions[4]);
+ $this->assertEquals('delete', $actions[4]->getOpType());
+ $this->assertEquals($rawData[6]['delete'], $actions[4]->getMetadata());
+ $this->assertFalse($actions[4]->hasSource());
+ }
+
+ /**
+ * @group unit
+ * @dataProvider invalidRawDataProvider
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testInvalidRawData($rawData, $failMessage)
+ {
+ $bulk = new Bulk($this->_getClient());
+
+ $bulk->addRawData($rawData);
+
+ $this->fail($failMessage);
+ }
+
+ public function invalidRawDataProvider()
+ {
+ return array(
+ array(
+ array(
+ array('index' => array('_index' => 'test', '_type' => 'user', '_id' => '1')),
+ array('user' => array('name' => 'hans')),
+ array('user' => array('name' => 'mans')),
+ ),
+ 'Two sources for one action',
+ ),
+ array(
+ array(
+ array('index' => array('_index' => 'test', '_type' => 'user', '_id' => '1')),
+ array('user' => array('name' => 'hans')),
+ array('upsert' => array('_index' => 'test', '_type' => 'user', '_id' => '2')),
+ ),
+ 'Invalid optype for action',
+ ),
+ array(
+ array(
+ array('user' => array('name' => 'mans')),
+ ),
+ 'Source without action',
+ ),
+ array(
+ array(
+ array(),
+ ),
+ 'Empty array',
+ ),
+ array(
+ array(
+ 'dummy',
+ ),
+ 'String as data',
+ ),
+ );
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreateAbstractDocumentWithInvalidData()
+ {
+ //Wrong class type
+ try {
+ $badDocument = new \stdClass();
+ AbstractDocument::create($badDocument);
+ $this->fail('Tried to create an abstract document with an object that is not a Document or Script, but no exception was thrown');
+ } catch (\Exception $e) {
+ //Excepted exception was thrown.
+ }
+
+ //Try to create document with a script
+ try {
+ $script = new Script();
+ AbstractDocument::create($script, AbstractDocument::OP_TYPE_CREATE);
+ $this->fail('Tried to create an abstract document with a Script, but no exception was thrown');
+ } catch (\Exception $e) {
+ //Excepted exception was thrown.
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testErrorRequest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('bulk_test');
+ $client = $index->getClient();
+
+ $documents = array(
+ $type->createDocument(1, array('name' => 'Mister Fantastic')),
+ $type->createDocument(2, array('name' => 'Invisible Woman')),
+ $type->createDocument(2, array('name' => 'The Human Torch')),
+ );
+
+ $documents[2]->setOpType(Document::OP_TYPE_CREATE);
+
+ $bulk = new Bulk($client);
+ $bulk->addDocuments($documents);
+
+ try {
+ $bulk->send();
+ $bulk->fail('3rd document create should produce error');
+ } catch (ResponseException $e) {
+ $this->assertContains('DocumentAlreadyExists', $e->getMessage());
+ $failures = $e->getFailures();
+ $this->assertInternalType('array', $failures);
+ $this->assertArrayHasKey(0, $failures);
+ $this->assertContains('DocumentAlreadyExists', $failures[0]);
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testRawDocumentDataRequest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('bulk_test');
+ $client = $index->getClient();
+
+ $documents = array(
+ new Document(null, '{"name":"Mister Fantastic"}'),
+ new Document(null, '{"name":"Invisible Woman"}'),
+ new Document(null, '{"name":"The Human Torch"}'),
+ );
+
+ $bulk = new Bulk($client);
+ $bulk->addDocuments($documents);
+ $bulk->setType($type);
+
+ $expectedJson = '{"index":{}}
+{"name":"Mister Fantastic"}
+{"index":{}}
+{"name":"Invisible Woman"}
+{"index":{}}
+{"name":"The Human Torch"}
+';
+ $expectedJson = str_replace(PHP_EOL, "\n", $expectedJson);
+ $this->assertEquals($expectedJson, $bulk->toString());
+
+ $response = $bulk->send();
+ $this->assertTrue($response->isOk());
+
+ $type->getIndex()->refresh();
+
+ $response = $type->search();
+ $this->assertEquals(3, $response->count());
+
+ foreach (array('Mister', 'Invisible', 'Torch') as $name) {
+ $result = $type->search($name);
+ $this->assertEquals(1, count($result->getResults()));
+ }
+ }
+
+ /**
+ * @group functional
+ * @dataProvider udpDataProvider
+ */
+ public function testUdp($clientConfig, $host, $port, $shouldFail = false)
+ {
+ if (!function_exists('socket_create')) {
+ $this->markTestSkipped('Function socket_create() does not exist.');
+ }
+ $client = $this->_getClient($clientConfig);
+ $index = $client->getIndex('elastica_test');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+ $type = $index->getType('udp_test');
+ $client = $index->getClient();
+
+ $type->setMapping(array('name' => array('type' => 'string')));
+
+ $docs = array(
+ $type->createDocument(1, array('name' => 'Mister Fantastic')),
+ $type->createDocument(2, array('name' => 'Invisible Woman')),
+ $type->createDocument(3, array('name' => 'The Human Torch')),
+ $type->createDocument(4, array('name' => 'The Thing')),
+ $type->createDocument(5, array('name' => 'Mole Man')),
+ $type->createDocument(6, array('name' => 'The Skrulls')),
+ );
+
+ $bulk = new Bulk($client);
+ $bulk->addDocuments($docs);
+
+ $bulk->sendUdp($host, $port);
+
+ $i = 0;
+ $limit = 20;
+ do {
+ usleep(200000);
+ } while ($type->count() < 6 && ++$i < $limit);
+
+ if ($shouldFail) {
+ $this->assertEquals($limit, $i, 'Invalid udp connection data. Test should fail');
+ } else {
+ $this->assertLessThan($limit, $i, 'It took too much time waiting for UDP request result');
+
+ foreach ($docs as $doc) {
+ $getDoc = $type->getDocument($doc->getId());
+ $this->assertEquals($doc->getData(), $getDoc->getData());
+ }
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdate()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('bulk_test');
+ $client = $index->getClient();
+
+ $doc1 = $type->createDocument(1, array('name' => 'John'));
+ $doc2 = $type->createDocument(2, array('name' => 'Paul'));
+ $doc3 = $type->createDocument(3, array('name' => 'George'));
+ $doc4 = $type->createDocument(4, array('name' => 'Ringo'));
+ $documents = array($doc1, $doc2, $doc3, $doc4);
+
+ //index some documents
+ $bulk = new Bulk($client);
+ $bulk->setType($type);
+ $bulk->addDocuments($documents);
+ $response = $bulk->send();
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $index->refresh();
+
+ //test updating via document
+ $doc2 = $type->createDocument(2, array('name' => 'The Walrus'));
+ $bulk = new Bulk($client);
+ $bulk->setType($type);
+ $updateAction = new \Elastica\Bulk\Action\UpdateDocument($doc2);
+ $bulk->addAction($updateAction);
+ $response = $bulk->send();
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $index->refresh();
+
+ $doc = $type->getDocument(2);
+ $docData = $doc->getData();
+ $this->assertEquals('The Walrus', $docData['name']);
+
+ //test updating via script
+ $script = new \Elastica\Script('ctx._source.name += param1;', array('param1' => ' was Paul'), null, 2);
+ $doc2 = new Document();
+ $script->setUpsert($doc2);
+ $updateAction = Action\AbstractDocument::create($script, Action::OP_TYPE_UPDATE);
+ $bulk = new Bulk($client);
+ $bulk->setType($type);
+ $bulk->addAction($updateAction);
+ $response = $bulk->send();
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $index->refresh();
+
+ $doc2 = $type->getDocument(2);
+ $this->assertEquals('The Walrus was Paul', $doc2->name);
+
+ //test upsert
+ $script = new \Elastica\Script('ctx._scource.counter += count', array('count' => 1), null, 5);
+ $doc = new Document('', array('counter' => 1));
+ $script->setUpsert($doc);
+ $updateAction = Action\AbstractDocument::create($script, Action::OP_TYPE_UPDATE);
+ $bulk = new Bulk($client);
+ $bulk->setType($type);
+ $bulk->addAction($updateAction);
+ $response = $bulk->send();
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $index->refresh();
+ $doc = $type->getDocument(5);
+ $this->assertEquals(1, $doc->counter);
+
+ //test doc_as_upsert
+ $doc = new \Elastica\Document(6, array('test' => 'test'));
+ $doc->setDocAsUpsert(true);
+ $updateAction = Action\AbstractDocument::create($doc, Action::OP_TYPE_UPDATE);
+ $bulk = new Bulk($client);
+ $bulk->setType($type);
+ $bulk->addAction($updateAction);
+ $response = $bulk->send();
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $index->refresh();
+ $doc = $type->getDocument(6);
+ $this->assertEquals('test', $doc->test);
+
+ //test doc_as_upsert with set of documents (use of addDocuments)
+ $doc1 = new \Elastica\Document(7, array('test' => 'test1'));
+ $doc1->setDocAsUpsert(true);
+ $doc2 = new \Elastica\Document(8, array('test' => 'test2'));
+ $doc2->setDocAsUpsert(true);
+ $docs = array($doc1, $doc2);
+ $bulk = new Bulk($client);
+ $bulk->setType($type);
+ $bulk->addDocuments($docs, \Elastica\Bulk\Action::OP_TYPE_UPDATE);
+ $response = $bulk->send();
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $index->refresh();
+ $doc = $type->getDocument(7);
+ $this->assertEquals('test1', $doc->test);
+ $doc = $type->getDocument(8);
+ $this->assertEquals('test2', $doc->test);
+
+ //test updating via document with json string as data
+ $doc3 = $type->createDocument(2);
+ $bulk = new Bulk($client);
+ $bulk->setType($type);
+ $doc3->setData('{"name" : "Paul it is"}');
+ $updateAction = new \Elastica\Bulk\Action\UpdateDocument($doc3);
+ $bulk->addAction($updateAction);
+ $response = $bulk->send();
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $index->refresh();
+
+ $doc = $type->getDocument(2);
+ $docData = $doc->getData();
+ $this->assertEquals('Paul it is', $docData['name']);
+
+ $index->delete();
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetPath()
+ {
+ $client = $this->_getClient();
+ $bulk = new Bulk($client);
+
+ $this->assertEquals('_bulk', $bulk->getPath());
+
+ $indexName = 'testIndex';
+
+ $bulk->setIndex($indexName);
+ $this->assertEquals($indexName.'/_bulk', $bulk->getPath());
+
+ $typeName = 'testType';
+ $bulk->setType($typeName);
+ $this->assertEquals($indexName.'/'.$typeName.'/_bulk', $bulk->getPath());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testRetry()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('bulk_test');
+ $client = $index->getClient();
+
+ $doc1 = $type->createDocument(1, array('name' => 'Mister Fantastic'));
+ $doc1->setOpType(Action::OP_TYPE_UPDATE);
+ $doc1->setRetryOnConflict(5);
+
+ $bulk = new Bulk($client);
+ $bulk->addDocument($doc1);
+
+ $actions = $bulk->getActions();
+
+ $metadata = $actions[0]->getMetadata();
+ $this->assertEquals(5, $metadata[ '_retry_on_conflict' ]);
+
+ $script = new \Elastica\Script('');
+ $script->setRetryOnConflict(5);
+
+ $bulk = new Bulk($client);
+ $bulk->addScript($script);
+
+ $actions = $bulk->getActions();
+
+ $metadata = $actions[0]->getMetadata();
+ $this->assertEquals(5, $metadata[ '_retry_on_conflict' ]);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetShardTimeout()
+ {
+ $bulk = new Bulk($this->_getClient());
+ $this->assertInstanceOf('Elastica\Bulk', $bulk->setShardTimeout(10));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetRequestParam()
+ {
+ $bulk = new Bulk($this->_getClient());
+ $this->assertInstanceOf('Elastica\Bulk', $bulk->setRequestParam('key', 'value'));
+ }
+
+ /**
+ * @group benchmark
+ */
+ public function testMemoryUsage()
+ {
+ $type = $this->_createIndex()->getType('test');
+
+ $data = array(
+ 'text1' => 'Very long text for a string',
+ 'text2' => 'But this is not very long',
+ 'text3' => 'random or not random?',
+ );
+
+ $startMemory = memory_get_usage();
+
+ for ($n = 1; $n < 10; $n++) {
+ $docs = array();
+
+ for ($i = 1; $i <= 3000; $i++) {
+ $docs[] = new Document(uniqid(), $data);
+ }
+
+ $type->addDocuments($docs);
+ $docs = array();
+ }
+
+ unset($docs);
+
+ $endMemory = memory_get_usage();
+
+ $this->assertLessThan(1.3, $endMemory / $startMemory);
+ }
+
+ public function udpDataProvider()
+ {
+ return array(
+ array(
+ array(),
+ null,
+ null,
+ ),
+ array(
+ array(),
+ $this->_getHost(),
+ null,
+ ),
+ array(
+ array(),
+ null,
+ 9700,
+ ),
+ array(
+ array(),
+ $this->_getHost(),
+ 9700,
+ ),
+ array(
+ array(
+ 'udp' => array(
+ 'host' => $this->_getHost(),
+ 'port' => 9700,
+ ),
+ ),
+ null,
+ null,
+ ),
+ array(
+ array(
+ 'udp' => array(
+ 'host' => $this->_getHost(),
+ 'port' => 9800,
+ ),
+ ),
+ $this->_getHost(),
+ 9700,
+ ),
+ array(
+ array(
+ 'udp' => array(
+ 'host' => $this->_getHost(),
+ 'port' => 9800,
+ ),
+ ),
+ null,
+ null,
+ true,
+ ),
+ array(
+ array(),
+ $this->_getHost(),
+ 9800,
+ true,
+ ),
+ );
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ClientTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ClientTest.php
new file mode 100644
index 00000000..a5f2b46f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ClientTest.php
@@ -0,0 +1,1160 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Connection;
+use Elastica\Document;
+use Elastica\Exception\Connection\HttpException;
+use Elastica\Exception\InvalidException;
+use Elastica\Index;
+use Elastica\Request;
+use Elastica\Script;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+
+class ClientTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $client = $this->_getClient();
+ $this->assertCount(1, $client->getConnections());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testConnectionsArray()
+ {
+ // Creates a new index 'xodoa' and a type 'user' inside this index
+ $client = $this->_getClient(array('connections' => array(array('host' => $this->_getHost(), 'port' => 9200))));
+ $index = $client->getIndex('elastica_test1');
+ $index->create(array(), true);
+
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc1 = new Document(1,
+ array('username' => 'hans', 'test' => array('2', '3', '5'))
+ );
+ $type->addDocument($doc1);
+
+ // Adds a list of documents with _bulk upload to the index
+ $docs = array();
+ $docs[] = new Document(2,
+ array('username' => 'john', 'test' => array('1', '3', '6'))
+ );
+ $docs[] = new Document(3,
+ array('username' => 'rolf', 'test' => array('2', '3', '7'))
+ );
+ $type->addDocuments($docs);
+
+ // Refresh index
+ $index->refresh();
+
+ $resultSet = $type->search('rolf');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testTwoServersSame()
+ {
+ // Creates a new index 'xodoa' and a type 'user' inside this index
+ $client = $this->_getClient(array('connections' => array(
+ array('host' => $this->_getHost(), 'port' => 9200),
+ array('host' => $this->_getHost(), 'port' => 9200),
+ )));
+ $index = $client->getIndex('elastica_test1');
+ $index->create(array(), true);
+
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc1 = new Document(1,
+ array('username' => 'hans', 'test' => array('2', '3', '5'))
+ );
+ $type->addDocument($doc1);
+
+ // Adds a list of documents with _bulk upload to the index
+ $docs = array();
+ $docs[] = new Document(2,
+ array('username' => 'john', 'test' => array('1', '3', '6'))
+ );
+ $docs[] = new Document(3,
+ array('username' => 'rolf', 'test' => array('2', '3', '7'))
+ );
+ $type->addDocuments($docs);
+
+ // Refresh index
+ $index->refresh();
+
+ $resultSet = $type->search('rolf');
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConnectionParamsArePreparedForConnectionsOption()
+ {
+ $url = 'https://'.$this->_getHost().':9200';
+ $client = $this->_getClient(array('connections' => array(array('url' => $url))));
+ $connection = $client->getConnection();
+
+ $this->assertEquals($url, $connection->getConfig('url'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConnectionParamsArePreparedForServersOption()
+ {
+ $url = 'https://'.$this->_getHost().':9200';
+ $client = $this->_getClient(array('servers' => array(array('url' => $url))));
+ $connection = $client->getConnection();
+
+ $this->assertEquals($url, $connection->getConfig('url'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConnectionParamsArePreparedForDefaultOptions()
+ {
+ $url = 'https://'.$this->_getHost().':9200';
+ $client = $this->_getClient(array('url' => $url));
+ $connection = $client->getConnection();
+
+ $this->assertEquals($url, $connection->getConfig('url'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testBulk()
+ {
+ $client = $this->_getClient();
+
+ $params = array(
+ array('index' => array('_index' => 'test', '_type' => 'user', '_id' => '1')),
+ array('user' => array('name' => 'hans')),
+ array('index' => array('_index' => 'test', '_type' => 'user', '_id' => '2')),
+ array('user' => array('name' => 'peter')),
+ );
+
+ $client->bulk($params);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testOptimizeAll()
+ {
+ $client = $this->_getClient();
+ $response = $client->optimizeAll();
+
+ $this->assertFalse($response->hasError());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testAddDocumentsEmpty()
+ {
+ $client = $this->_getClient();
+ $client->addDocuments(array());
+ }
+
+ /**
+ * Test bulk operations on Index.
+ *
+ * @group functional
+ */
+ public function testBulkIndex()
+ {
+ $index = $this->_getClient()->getIndex('cryptocurrencies');
+
+ $anonCoin = new Document(1, array('name' => 'anoncoin'), 'altcoin');
+ $ixCoin = new Document(2, array('name' => 'ixcoin'), 'altcoin');
+
+ $index->addDocuments(array($anonCoin, $ixCoin));
+
+ $this->assertEquals('anoncoin', $index->getType('altcoin')->getDocument(1)->get('name'));
+ $this->assertEquals('ixcoin', $index->getType('altcoin')->getDocument(2)->get('name'));
+
+ $index->updateDocuments(array(
+ new Document(1, array('name' => 'AnonCoin'), 'altcoin'),
+ new Document(2, array('name' => 'iXcoin'), 'altcoin'),
+ ));
+
+ $this->assertEquals('AnonCoin', $index->getType('altcoin')->getDocument(1)->get('name'));
+ $this->assertEquals('iXcoin', $index->getType('altcoin')->getDocument(2)->get('name'));
+
+ $ixCoin->setIndex(null); // Make sure the index gets set properly if missing
+ $index->deleteDocuments(array($anonCoin, $ixCoin));
+
+ $this->setExpectedException('Elastica\Exception\NotFoundException');
+ $index->getType('altcoin')->getDocument(1);
+ $index->getType('altcoin')->getDocument(2);
+ }
+
+ /**
+ * Test bulk operations on Type.
+ *
+ * @group functional
+ */
+ public function testBulkType()
+ {
+ $type = $this->_getClient()->getIndex('cryptocurrencies')->getType('altcoin');
+
+ $liteCoin = new Document(1, array('name' => 'litecoin'));
+ $nameCoin = new Document(2, array('name' => 'namecoin'));
+
+ $type->addDocuments(array($liteCoin, $nameCoin));
+
+ $this->assertEquals('litecoin', $type->getDocument(1)->get('name'));
+ $this->assertEquals('namecoin', $type->getDocument(2)->get('name'));
+
+ $type->updateDocuments(array(
+ new Document(1, array('name' => 'LiteCoin')),
+ new Document(2, array('name' => 'NameCoin')),
+ ));
+
+ $this->assertEquals('LiteCoin', $type->getDocument(1)->get('name'));
+ $this->assertEquals('NameCoin', $type->getDocument(2)->get('name'));
+
+ $nameCoin->setType(null); // Make sure the type gets set properly if missing
+ $type->deleteDocuments(array($liteCoin, $nameCoin));
+
+ $this->setExpectedException('Elastica\Exception\NotFoundException');
+ $type->getDocument(1);
+ $type->getDocument(2);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocuments()
+ {
+ $indexName = 'test';
+ $typeName = 'people';
+
+ $client = $this->_getClient();
+ $type = $client->getIndex($indexName)->getType($typeName);
+
+ $initialValue = 28;
+ $modifiedValue = 27;
+
+ $doc1 = new Document(
+ 1,
+ array('name' => 'hans', 'age' => $initialValue),
+ $typeName,
+ $indexName
+ );
+ $doc2 = new Document(
+ 2,
+ array('name' => 'anna', 'age' => $initialValue),
+ $typeName,
+ $indexName
+ );
+ $data = array($doc1, $doc2);
+ $client->addDocuments($data);
+
+ foreach ($data as $i => $doc) {
+ $data[$i]->age = $modifiedValue;
+ }
+ $client->updateDocuments($data);
+
+ $docData1 = $type->getDocument(1)->getData();
+ $docData2 = $type->getDocument(2)->getData();
+
+ $this->assertEquals($modifiedValue, $docData1['age']);
+ $this->assertEquals($modifiedValue, $docData2['age']);
+ }
+
+ /**
+ * Test deleteIds method using string parameters.
+ *
+ * This test ensures that the deleteIds method of
+ * the \Elastica\Client can properly accept and use
+ * an $index parameter and $type parameter that are
+ * strings
+ *
+ * This test is a bit more verbose than just sending the
+ * values to deleteIds and checking for exceptions or
+ * warnings.
+ *
+ * It will add a document, search for it, then delete it
+ * using the parameter types we are interested in, and then
+ * re-search to verify that they have been deleted
+ *
+ * @group functional
+ */
+ public function testDeleteIdsIdxStringTypeString()
+ {
+ $data = array('username' => 'hans');
+ $userSearch = 'username:hans';
+
+ $index = $this->_createIndex(null, true, 2);
+
+ // Create the index, deleting it first if it already exists
+ $index->create(array(), true);
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc = new Document(null, $data);
+ $doc->setRouting(1);
+ $result = $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $resultData = $result->getData();
+ $ids = array($resultData['_id']);
+
+ // Check to make sure the document is in the index
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(1, $totalHits);
+
+ // And verify that the variables we are doing to send to
+ // deleteIds are the type we are testing for
+ $idxString = $index->getName();
+ $typeString = $type->getName();
+ $this->assertTrue(is_string($idxString));
+ $this->assertTrue(is_string($typeString));
+
+ // Try to delete doc with a routing value which hashes to
+ // a different shard then the id.
+ $resp = $index->getClient()->deleteIds($ids, $index, $type, 2);
+
+ // Refresh the index
+ $index->refresh();
+
+ // Research the index to verify that the items are still there
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(1, $totalHits);
+
+ // Using the existing $index and $type variables which
+ // are \Elastica\Index and \Elastica\Type objects respectively
+ $resp = $index->getClient()->deleteIds($ids, $index, $type, 1);
+
+ // Refresh the index to clear out deleted ID information
+ $index->refresh();
+
+ // Research the index to verify that the items have been deleted
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(0, $totalHits);
+ }
+
+ /**
+ * Test deleteIds method using string parameter for $index
+ * and object parameter for $type.
+ *
+ * This test ensures that the deleteIds method of
+ * the \Elastica\Client can properly accept and use
+ * an $index parameter that is a string and a $type
+ * parameter that is of type \Elastica\Type
+ *
+ * This test is a bit more verbose than just sending the
+ * values to deleteIds and checking for exceptions or
+ * warnings.
+ *
+ * It will add a document, search for it, then delete it
+ * using the parameter types we are interested in, and then
+ * re-search to verify that they have been deleted
+ *
+ * @group functional
+ */
+ public function testDeleteIdsIdxStringTypeObject()
+ {
+ $data = array('username' => 'hans');
+ $userSearch = 'username:hans';
+
+ $index = $this->_createIndex();
+
+ // Create the index, deleting it first if it already exists
+ $index->create(array(), true);
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc = new Document(null, $data);
+ $result = $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $resultData = $result->getData();
+ $ids = array($resultData['_id']);
+
+ // Check to make sure the document is in the index
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(1, $totalHits);
+
+ // And verify that the variables we are doing to send to
+ // deleteIds are the type we are testing for
+ $idxString = $index->getName();
+ $this->assertTrue(is_string($idxString));
+ $this->assertInstanceOf('Elastica\Type', $type);
+
+ // Using the existing $index and $type variables which
+ // are \Elastica\Index and \Elastica\Type objects respectively
+ $resp = $index->getClient()->deleteIds($ids, $index, $type);
+
+ // Refresh the index to clear out deleted ID information
+ $index->refresh();
+
+ // Research the index to verify that the items have been deleted
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(0, $totalHits);
+ }
+
+ /**
+ * Test deleteIds method using object parameter for $index
+ * and string parameter for $type.
+ *
+ * This test ensures that the deleteIds method of
+ * the \Elastica\Client can properly accept and use
+ * an $index parameter that is of type Elasitca_Index
+ * and a $type parameter that is a string
+ *
+ * This test is a bit more verbose than just sending the
+ * values to deleteIds and checking for exceptions or
+ * warnings.
+ *
+ * It will add a document, search for it, then delete it
+ * using the parameter types we are interested in, and then
+ * re-search to verify that they have been deleted
+ *
+ * @group functional
+ */
+ public function testDeleteIdsIdxObjectTypeString()
+ {
+ $data = array('username' => 'hans');
+ $userSearch = 'username:hans';
+
+ $index = $this->_createIndex();
+
+ // Create the index, deleting it first if it already exists
+ $index->create(array(), true);
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc = new Document(null, $data);
+ $result = $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $resultData = $result->getData();
+ $ids = array($resultData['_id']);
+
+ // Check to make sure the document is in the index
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(1, $totalHits);
+
+ // And verify that the variables we are doing to send to
+ // deleteIds are the type we are testing for
+ $typeString = $type->getName();
+ $this->assertInstanceOf('Elastica\Index', $index);
+ $this->assertTrue(is_string($typeString));
+
+ // Using the existing $index and $type variables which
+ // are \Elastica\Index and \Elastica\Type objects respectively
+ $resp = $index->getClient()->deleteIds($ids, $index, $type);
+
+ // Refresh the index to clear out deleted ID information
+ $index->refresh();
+
+ // Research the index to verify that the items have been deleted
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(0, $totalHits);
+ }
+
+ /**
+ * Test deleteIds method using object parameter for $index
+ * and object parameter for $type.
+ *
+ * This test ensures that the deleteIds method of
+ * the \Elastica\Client can properly accept and use
+ * an $index parameter that is an object and a $type
+ * parameter that is of type \Elastica\Type
+ *
+ * This test is a bit more verbose than just sending the
+ * values to deleteIds and checking for exceptions or
+ * warnings.
+ *
+ * It will add a document, search for it, then delete it
+ * using the parameter types we are interested in, and then
+ * re-search to verify that they have been deleted
+ *
+ * @group functional
+ */
+ public function testDeleteIdsIdxObjectTypeObject()
+ {
+ $data = array('username' => 'hans');
+ $userSearch = 'username:hans';
+
+ $index = $this->_createIndex();
+
+ // Create the index, deleting it first if it already exists
+ $index->create(array(), true);
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc = new Document(null, $data);
+ $result = $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $resultData = $result->getData();
+ $ids = array($resultData['_id']);
+
+ // Check to make sure the document is in the index
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(1, $totalHits);
+
+ // And verify that the variables we are doing to send to
+ // deleteIds are the type we are testing for
+ $this->assertInstanceOf('Elastica\Index', $index);
+ $this->assertInstanceOf('Elastica\Type', $type);
+
+ // Using the existing $index and $type variables which
+ // are \Elastica\Index and \Elastica\Type objects respectively
+ $resp = $index->getClient()->deleteIds($ids, $index, $type);
+
+ // Refresh the index to clear out deleted ID information
+ $index->refresh();
+
+ // Research the index to verify that the items have been deleted
+ $resultSet = $type->search($userSearch);
+ $totalHits = $resultSet->getTotalHits();
+ $this->assertEquals(0, $totalHits);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testOneInvalidConnection()
+ {
+ $client = $this->_getClient();
+
+ // First connection work, second should not work
+ $connection1 = new Connection(array('port' => '9100', 'timeout' => 2, 'host' => $this->_getHost()));
+ $connection2 = new Connection(array('port' => '9200', 'timeout' => 2, 'host' => $this->_getHost()));
+
+ $client->setConnections(array($connection1, $connection2));
+
+ $client->request('_status', Request::GET);
+
+ $connections = $client->getConnections();
+
+ // two connections are setup
+ $this->assertEquals(2, count($connections));
+
+ // One connection has to be disabled
+ $this->assertTrue($connections[0]->isEnabled() == false || $connections[1]->isEnabled() == false);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testTwoInvalidConnection()
+ {
+ $client = $this->_getClient();
+
+ // First connection work, second should not work
+ $connection1 = new Connection(array('port' => '9101', 'timeout' => 2));
+ $connection2 = new Connection(array('port' => '9102', 'timeout' => 2));
+
+ $client->setConnections(array($connection1, $connection2));
+
+ try {
+ $client->request('_status', Request::GET);
+ $this->fail('Should throw exception as no connection valid');
+ } catch (HttpException $e) {
+ }
+
+ $connections = $client->getConnections();
+
+ // two connections are setup
+ $this->assertEquals(2, count($connections));
+
+ // One connection has to be disabled
+ $this->assertTrue($connections[0]->isEnabled() == false || $connections[1]->isEnabled() == false);
+ }
+
+ /**
+ * Tests if the callback works in case a connection is down.
+ *
+ * @group functional
+ */
+ public function testCallback()
+ {
+ $count = 0;
+ $object = $this;
+
+ // Callback function which verifies that disabled connection objects are returned
+ $callback = function ($connection, $exception, $client) use (&$object, &$count) {
+ $object->assertInstanceOf('Elastica\Connection', $connection);
+ $object->assertInstanceOf('Elastica\Exception\ConnectionException', $exception);
+ $object->assertInstanceOf('Elastica\Client', $client);
+ $object->assertFalse($connection->isEnabled());
+ $count++;
+ };
+
+ $client = $this->_getClient(array(), $callback);
+
+ // First connection work, second should not work
+ $connection1 = new Connection(array('port' => '9101', 'timeout' => 2));
+ $connection2 = new Connection(array('port' => '9102', 'timeout' => 2));
+
+ $client->setConnections(array($connection1, $connection2));
+
+ $this->assertEquals(0, $count);
+
+ try {
+ $client->request('_status', Request::GET);
+ $this->fail('Should throw exception as no connection valid');
+ } catch (HttpException $e) {
+ $this->assertTrue(true);
+ }
+
+ // Two disabled connections (from closure call)
+ $this->assertEquals(2, $count);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUrlConstructor()
+ {
+ $url = 'http://'.$this->_getHost().':9200/';
+
+ // Url should overwrite invalid host
+ $client = $this->_getClient(array('url' => $url, 'port' => '9101', 'timeout' => 2));
+
+ $response = $client->request('_status');
+ $this->assertInstanceOf('Elastica\Response', $response);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentByDocument()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ $newDocument = new Document(1, array('field1' => 'value1', 'field2' => 'value2'));
+ $type->addDocument($newDocument);
+
+ $updateDocument = new Document(1, array('field2' => 'value2changed', 'field3' => 'value3added'));
+ $client->updateDocument(1, $updateDocument, $index->getName(), $type->getName());
+
+ $document = $type->getDocument(1);
+
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('value2changed', $data['field2']);
+ $this->assertArrayHasKey('field3', $data);
+ $this->assertEquals('value3added', $data['field3']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentByScript()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ $newDocument = new Document(1, array('field1' => 'value1', 'field2' => 10, 'field3' => 'should be removed', 'field4' => 'should be changed'));
+ $type->addDocument($newDocument);
+
+ $script = new Script('ctx._source.field2 += 5; ctx._source.remove("field3"); ctx._source.field4 = "changed"');
+ $client->updateDocument(1, $script, $index->getName(), $type->getName());
+
+ $document = $type->getDocument(1);
+
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals(15, $data['field2']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('changed', $data['field4']);
+ $this->assertArrayNotHasKey('field3', $data);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentByScriptWithUpsert()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ $script = new Script('ctx._source.field2 += count; ctx._source.remove("field3"); ctx._source.field4 = "changed"');
+ $script->setParam('count', 5);
+ $script->setUpsert(array('field1' => 'value1', 'field2' => 10, 'field3' => 'should be removed', 'field4' => 'value4'));
+
+ // should use document fields because document does not exist, script is avoided
+ $client->updateDocument(1, $script, $index->getName(), $type->getName(), array('fields' => '_source'));
+
+ $document = $type->getDocument(1);
+
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals(10, $data['field2']);
+ $this->assertArrayHasKey('field3', $data);
+ $this->assertEquals('should be removed', $data['field3']);
+ $this->assertArrayHasKey('field4', $data);
+ $this->assertEquals('value4', $data['field4']);
+
+ // should use script because document exists, document values are ignored
+ $client->updateDocument(1, $script, $index->getName(), $type->getName(), array('fields' => '_source'));
+
+ $document = $type->getDocument(1);
+
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals(15, $data['field2']);
+ $this->assertArrayHasKey('field4', $data);
+ $this->assertEquals('changed', $data['field4']);
+ $this->assertArrayNotHasKey('field3', $data);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentByRawData()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ $newDocument = new Document(1, array('field1' => 'value1'));
+ $type->addDocument($newDocument);
+
+ $rawData = array(
+ 'doc' => array(
+ 'field2' => 'value2',
+ ),
+ );
+
+ $response = $client->updateDocument(1, $rawData, $index->getName(), $type->getName(), array('retry_on_conflict' => 1));
+ $this->assertTrue($response->isOk());
+
+ $document = $type->getDocument(1);
+
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('value2', $data['field2']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentByDocumentWithUpsert()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ $newDocument = new Document(1, array('field1' => 'value1updated', 'field2' => 'value2updated'));
+ $upsert = new Document(1, array('field1' => 'value1', 'field2' => 'value2'));
+ $newDocument->setUpsert($upsert);
+ $client->updateDocument(1, $newDocument, $index->getName(), $type->getName(), array('fields' => '_source'));
+
+ $document = $type->getDocument(1);
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('value2', $data['field2']);
+
+ // should use update document because document exists, upsert document values are ignored
+ $client->updateDocument(1, $newDocument, $index->getName(), $type->getName(), array('fields' => '_source'));
+
+ $document = $type->getDocument(1);
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1updated', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('value2updated', $data['field2']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDocAsUpsert()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ //Confirm document one does not exist
+ try {
+ $document = $type->getDocument(1);
+ $this->fail('Exception was not thrown. Maybe the document exists?');
+ } catch (\Exception $e) {
+ //Ignore the exception because we expect the document to not exist.
+ }
+
+ $newDocument = new Document(1, array('field1' => 'value1', 'field2' => 'value2'));
+ $newDocument->setDocAsUpsert(true);
+ $client->updateDocument(1, $newDocument, $index->getName(), $type->getName(), array('fields' => '_source'));
+
+ $document = $type->getDocument(1);
+ $this->assertInstanceOf('Elastica\Document', $document);
+ $data = $document->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('value2', $data['field2']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateWithInvalidType()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ //Try to update using a stdClass object
+ $badDocument = new \stdClass();
+
+ try {
+ $client->updateDocument(1, $badDocument, $index->getName(), $type->getName());
+ $this->fail('Tried to update using an object that is not a Document or a Script but no exception was thrown');
+ } catch (\Exception $e) {
+ //Good. An exception was thrown.
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteDocuments()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ $docs = array(
+ new Document(1, array('field' => 'value1'), $type, $index),
+ new Document(2, array('field' => 'value2'), $type, $index),
+ new Document(3, array('field' => 'value3'), $type, $index),
+ );
+
+ $response = $client->addDocuments($docs);
+
+ $this->assertInstanceOf('Elastica\Bulk\ResponseSet', $response);
+ $this->assertEquals(3, count($response));
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+ $this->assertEquals('', $response->getError());
+
+ $index->refresh();
+
+ $this->assertEquals(3, $type->count());
+
+ $deleteDocs = array(
+ $docs[0],
+ $docs[2],
+ );
+
+ $response = $client->deleteDocuments($deleteDocs);
+
+ $this->assertInstanceOf('Elastica\Bulk\ResponseSet', $response);
+ $this->assertEquals(2, count($response));
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+ $this->assertEquals('', $response->getError());
+
+ $index->refresh();
+
+ $this->assertEquals(1, $type->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testLastRequestResponse()
+ {
+ $client = $this->_getClient();
+ $response = $client->request('_status');
+
+ $this->assertInstanceOf('Elastica\Response', $response);
+
+ $lastRequest = $client->getLastRequest();
+
+ $this->assertInstanceOf('Elastica\Request', $lastRequest);
+ $this->assertEquals('_status', $lastRequest->getPath());
+
+ $lastResponse = $client->getLastResponse();
+ $this->assertInstanceOf('Elastica\Response', $lastResponse);
+ $this->assertSame($response, $lastResponse);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentPopulateFields()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $client = $index->getClient();
+
+ $newDocument = new Document(1, array('field1' => 'value1', 'field2' => 10, 'field3' => 'should be removed', 'field4' => 'value4'));
+ $newDocument->setAutoPopulate();
+ $type->addDocument($newDocument);
+
+ $script = new Script('ctx._source.field2 += count; ctx._source.remove("field3"); ctx._source.field4 = "changed"');
+ $script->setParam('count', 5);
+ $script->setUpsert($newDocument);
+
+ $client->updateDocument(
+ 1,
+ $script,
+ $index->getName(),
+ $type->getName(),
+ array('fields' => '_source')
+ );
+
+ $data = $type->getDocument(1)->getData();
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals(15, $data['field2']);
+ $this->assertArrayHasKey('field4', $data);
+ $this->assertEquals('changed', $data['field4']);
+ $this->assertArrayNotHasKey('field3', $data);
+
+ $script = new Script('ctx._source.field2 += count; ctx._source.remove("field4"); ctx._source.field1 = field1;');
+ $script->setParam('count', 5);
+ $script->setParam('field1', 'updated');
+ $script->setUpsert($newDocument);
+
+ $client->updateDocument(
+ 1,
+ $script,
+ $index->getName(),
+ $type->getName(),
+ array('fields' => 'field2,field4')
+ );
+
+ $document = $type->getDocument(1);
+
+ $data = $document->getData();
+
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('updated', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals(20, $data['field2']);
+ $this->assertArrayNotHasKey('field3', $data);
+ $this->assertArrayNotHasKey('field4', $data);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddDocumentsWithoutIds()
+ {
+ $docs = array();
+ for ($i = 0; $i < 10; $i++) {
+ $docs[] = new Document(null, array('pos' => $i));
+ }
+
+ foreach ($docs as $doc) {
+ $this->assertFalse($doc->hasId());
+ }
+
+ $index = $this->_createIndex();
+
+ $client = $index->getClient();
+ $client->setConfigValue('document', array('autoPopulate' => true));
+
+ $type = $index->getType('pos');
+ $type->addDocuments($docs);
+
+ foreach ($docs as $doc) {
+ $this->assertTrue($doc->hasId());
+ $this->assertTrue($doc->hasVersion());
+ $this->assertEquals(1, $doc->getVersion());
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConfigValue()
+ {
+ $config = array(
+ 'level1' => array(
+ 'level2' => array(
+ 'level3' => 'value3',
+ ),
+ 'level21' => 'value21',
+ ),
+ 'level11' => 'value11',
+ );
+ $client = $this->_getClient($config);
+
+ $this->assertNull($client->getConfigValue('level12'));
+ $this->assertFalse($client->getConfigValue('level12', false));
+ $this->assertEquals(10, $client->getConfigValue('level12', 10));
+
+ $this->assertEquals('value11', $client->getConfigValue('level11'));
+ $this->assertNotNull($client->getConfigValue('level11'));
+ $this->assertNotEquals(false, $client->getConfigValue('level11', false));
+ $this->assertNotEquals(10, $client->getConfigValue('level11', 10));
+
+ $this->assertEquals('value3', $client->getConfigValue(array('level1', 'level2', 'level3')));
+ $this->assertInternalType('array', $client->getConfigValue(array('level1', 'level2')));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testArrayQuery()
+ {
+ $client = $this->_getClient();
+
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+ $type->addDocument(new Document(1, array('username' => 'ruflin')));
+ $index->refresh();
+
+ $query = array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'ruflin',
+ ),
+ ),
+ );
+
+ $path = $index->getName().'/'.$type->getName().'/_search';
+
+ $response = $client->request($path, Request::GET, $query);
+ $responseArray = $response->getData();
+
+ $this->assertEquals(1, $responseArray['hits']['total']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testJSONQuery()
+ {
+ $client = $this->_getClient();
+
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+ $type->addDocument(new Document(1, array('username' => 'ruflin')));
+ $index->refresh();
+
+ $query = '{"query":{"query_string":{"query":"ruflin"}}}';
+
+ $path = $index->getName().'/'.$type->getName().'/_search';
+
+ $response = $client->request($path, Request::GET, $query);
+ $responseArray = $response->getData();
+
+ $this->assertEquals(1, $responseArray['hits']['total']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddHeader()
+ {
+ $client = $this->_getClient();
+
+ // add one header
+ $client->addHeader('foo', 'bar');
+ $this->assertEquals(array('foo' => 'bar'), $client->getConfigValue('headers'));
+
+ // check class
+ $this->assertInstanceOf('Elastica\Client', $client->addHeader('foo', 'bar'));
+
+ // check invalid parameters
+ try {
+ $client->addHeader(new \stdClass(), 'foo');
+ $this->fail('Header name is not a string but exception not thrown');
+ } catch (InvalidException $ex) {
+ }
+
+ try {
+ $client->addHeader('foo', new \stdClass());
+ $this->fail('Header value is not a string but exception not thrown');
+ } catch (InvalidException $ex) {
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testRemoveHeader()
+ {
+ $client = $this->_getClient();
+
+ // set headers
+ $headers = array(
+ 'first' => 'first value',
+ 'second' => 'second value',
+ );
+ foreach ($headers as $key => $value) {
+ $client->addHeader($key, $value);
+ }
+ $this->assertEquals($headers, $client->getConfigValue('headers'));
+
+ // remove one
+ $client->removeHeader('first');
+ unset($headers['first']);
+ $this->assertEquals($headers, $client->getConfigValue('headers'));
+
+ // check class
+ $this->assertInstanceOf('Elastica\Client', $client->removeHeader('second'));
+
+ // check invalid parameter
+ try {
+ $client->removeHeader(new \stdClass());
+ $this->fail('Header name is not a string but exception not thrown');
+ } catch (InvalidException $ex) {
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/IndexTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/IndexTest.php
new file mode 100644
index 00000000..00a121fc
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/IndexTest.php
@@ -0,0 +1,144 @@
+<?php
+namespace Elastica\Test\Cluster\Health;
+
+use Elastica\Cluster\Health\Index as HealthIndex;
+use Elastica\Test\Base as BaseTest;
+
+class IndexTest extends BaseTest
+{
+ /**
+ * @var \Elastica\Cluster\Health\Index
+ */
+ protected $_index;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $data = array(
+ 'status' => 'yellow',
+ 'number_of_shards' => 1,
+ 'number_of_replicas' => 2,
+ 'active_primary_shards' => 3,
+ 'active_shards' => 4,
+ 'relocating_shards' => 5,
+ 'initializing_shards' => 6,
+ 'unassigned_shards' => 7,
+ 'shards' => array(
+ '0' => array(
+ 'status' => 'yellow',
+ 'primary_active' => false,
+ 'active_shards' => 0,
+ 'relocating_shards' => 1,
+ 'initializing_shards' => 0,
+ 'unassigned_shards' => 1,
+ ),
+ '1' => array(
+ 'status' => 'yellow',
+ 'primary_active' => true,
+ 'active_shards' => 1,
+ 'relocating_shards' => 0,
+ 'initializing_shards' => 0,
+ 'unassigned_shards' => 1,
+ ),
+ '2' => array(
+ 'status' => 'green',
+ 'primary_active' => true,
+ 'active_shards' => 1,
+ 'relocating_shards' => 0,
+ 'initializing_shards' => 0,
+ 'unassigned_shards' => 0,
+ ),
+ ),
+ );
+
+ $this->_index = new HealthIndex('test', $data);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetName()
+ {
+ $this->assertEquals('test', $this->_index->getName());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetStatus()
+ {
+ $this->assertEquals('yellow', $this->_index->getStatus());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetNumberOfShards()
+ {
+ $this->assertEquals(1, $this->_index->getNumberOfShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetNumberOfReplicas()
+ {
+ $this->assertEquals(2, $this->_index->getNumberOfReplicas());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetActivePrimaryShards()
+ {
+ $this->assertEquals(3, $this->_index->getActivePrimaryShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetActiveShards()
+ {
+ $this->assertEquals(4, $this->_index->getActiveShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetRelocatingShards()
+ {
+ $this->assertEquals(5, $this->_index->getRelocatingShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetInitializingShards()
+ {
+ $this->assertEquals(6, $this->_index->getInitializingShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetUnassignedShards()
+ {
+ $this->assertEquals(7, $this->_index->getUnassignedShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetShards()
+ {
+ $shards = $this->_index->getShards();
+
+ $this->assertInternalType('array', $shards);
+ $this->assertEquals(3, count($shards));
+
+ foreach ($shards as $shard) {
+ $this->assertInstanceOf('Elastica\Cluster\Health\Shard', $shard);
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/ShardTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/ShardTest.php
new file mode 100644
index 00000000..5a436623
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/Health/ShardTest.php
@@ -0,0 +1,85 @@
+<?php
+namespace Elastica\Test\Cluster\Health;
+
+use Elastica\Cluster\Health\Shard as HealthShard;
+use Elastica\Test\Base as BaseTest;
+
+class ShardTest extends BaseTest
+{
+ /**
+ * @var \Elastica\Cluster\Health\Shard
+ */
+ protected $_shard;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $shardData = array(
+ 'status' => 'red',
+ 'primary_active' => true,
+ 'active_shards' => 1,
+ 'relocating_shards' => 0,
+ 'initializing_shards' => 0,
+ 'unassigned_shards' => 1,
+ );
+
+ $this->_shard = new HealthShard(2, $shardData);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetShardNumber()
+ {
+ $this->assertEquals(2, $this->_shard->getShardNumber());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetStatus()
+ {
+ $this->assertEquals('red', $this->_shard->getStatus());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testisPrimaryActive()
+ {
+ $this->assertTrue($this->_shard->isPrimaryActive());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsActive()
+ {
+ $this->assertTrue($this->_shard->isActive());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsRelocating()
+ {
+ $this->assertFalse($this->_shard->isRelocating());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsInitialized()
+ {
+ $this->assertFalse($this->_shard->isInitialized());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsUnassigned()
+ {
+ $this->assertTrue($this->_shard->isUnassigned());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/HealthTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/HealthTest.php
new file mode 100644
index 00000000..bb3e82ec
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/HealthTest.php
@@ -0,0 +1,147 @@
+<?php
+namespace Elastica\Test\Cluster;
+
+use Elastica\Test\Base as BaseTest;
+
+class HealthTest extends BaseTest
+{
+ /**
+ * @var \Elastica\Cluster\Health
+ */
+ protected $_health;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $data = array(
+ 'cluster_name' => 'test_cluster',
+ 'status' => 'green',
+ 'timed_out' => false,
+ 'number_of_nodes' => 10,
+ 'number_of_data_nodes' => 8,
+ 'active_primary_shards' => 3,
+ 'active_shards' => 4,
+ 'relocating_shards' => 2,
+ 'initializing_shards' => 7,
+ 'unassigned_shards' => 5,
+ 'indices' => array(
+ 'index_one' => array(
+ ),
+ 'index_two' => array(
+ ),
+ ),
+ );
+
+ $health = $this
+ ->getMockBuilder('Elastica\Cluster\Health')
+ ->setConstructorArgs(array($this->_getClient()))
+ ->setMethods(array('_retrieveHealthData'))
+ ->getMock();
+
+ $health
+ ->expects($this->any())
+ ->method('_retrieveHealthData')
+ ->will($this->returnValue($data));
+
+ // need to explicitly refresh because the mocking won't refresh the data in the constructor
+ $health->refresh();
+
+ $this->_health = $health;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetClusterName()
+ {
+ $this->assertEquals('test_cluster', $this->_health->getClusterName());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetStatus()
+ {
+ $this->assertEquals('green', $this->_health->getStatus());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetTimedOut()
+ {
+ $this->assertFalse($this->_health->getTimedOut());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetNumberOfNodes()
+ {
+ $this->assertEquals(10, $this->_health->getNumberOfNodes());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetNumberOfDataNodes()
+ {
+ $this->assertEquals(8, $this->_health->getNumberOfDataNodes());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetActivePrimaryShards()
+ {
+ $this->assertEquals(3, $this->_health->getActivePrimaryShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetActiveShards()
+ {
+ $this->assertEquals(4, $this->_health->getActiveShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetRelocatingShards()
+ {
+ $this->assertEquals(2, $this->_health->getRelocatingShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetInitializingShards()
+ {
+ $this->assertEquals(7, $this->_health->getInitializingShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetUnassignedShards()
+ {
+ $this->assertEquals(5, $this->_health->getUnassignedShards());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetIndices()
+ {
+ $indices = $this->_health->getIndices();
+
+ $this->assertInternalType('array', $indices);
+ $this->assertEquals(2, count($indices));
+
+ foreach ($indices as $index) {
+ $this->assertInstanceOf('Elastica\Cluster\Health\Index', $index);
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/SettingsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/SettingsTest.php
new file mode 100644
index 00000000..2a52fc8f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Cluster/SettingsTest.php
@@ -0,0 +1,117 @@
+<?php
+namespace Elastica\Test\Cluster;
+
+use Elastica\Cluster\Settings;
+use Elastica\Document;
+use Elastica\Exception\ResponseException;
+use Elastica\Test\Base as BaseTest;
+
+class SettingsTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testSetTransient()
+ {
+ $index = $this->_createIndex();
+
+ if (count($index->getClient()->getCluster()->getNodes()) < 2) {
+ $this->markTestSkipped('At least two master nodes have to be running for this test');
+ }
+
+ $settings = new Settings($index->getClient());
+
+ $settings->setTransient('discovery.zen.minimum_master_nodes', 2);
+ $data = $settings->get();
+ $this->assertEquals(2, $data['transient']['discovery']['zen']['minimum_master_nodes']);
+
+ $settings->setTransient('discovery.zen.minimum_master_nodes', 1);
+ $data = $settings->get();
+ $this->assertEquals(1, $data['transient']['discovery']['zen']['minimum_master_nodes']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetPersistent()
+ {
+ $index = $this->_createIndex();
+
+ if (count($index->getClient()->getCluster()->getNodes()) < 2) {
+ $this->markTestSkipped('At least two master nodes have to be running for this test');
+ }
+
+ $settings = new Settings($index->getClient());
+
+ $settings->setPersistent('discovery.zen.minimum_master_nodes', 2);
+ $data = $settings->get();
+ $this->assertEquals(2, $data['persistent']['discovery']['zen']['minimum_master_nodes']);
+
+ $settings->setPersistent('discovery.zen.minimum_master_nodes', 1);
+ $data = $settings->get();
+ $this->assertEquals(1, $data['persistent']['discovery']['zen']['minimum_master_nodes']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetReadOnly()
+ {
+ // Create two indices to check that the complete cluster is read only
+ $settings = new Settings($this->_getClient());
+ $settings->setReadOnly(false);
+ $index1 = $this->_createIndex();
+ $index2 = $this->_createIndex();
+
+ $doc1 = new Document(null, array('hello' => 'world'));
+ $doc2 = new Document(null, array('hello' => 'world'));
+ $doc3 = new Document(null, array('hello' => 'world'));
+ $doc4 = new Document(null, array('hello' => 'world'));
+ $doc5 = new Document(null, array('hello' => 'world'));
+ $doc6 = new Document(null, array('hello' => 'world'));
+
+ // Check that adding documents work
+ $index1->getType('test')->addDocument($doc1);
+ $index2->getType('test')->addDocument($doc2);
+
+ $response = $settings->setReadOnly(true);
+ $this->assertFalse($response->hasError());
+ $setting = $settings->getTransient('cluster.blocks.read_only');
+ $this->assertEquals('true', $setting);
+
+ // Make sure both index are read only
+ try {
+ $index1->getType('test')->addDocument($doc3);
+ $this->fail('should throw read only exception');
+ } catch (ResponseException $e) {
+ $message = $e->getMessage();
+ $this->assertContains('ClusterBlockException', $message);
+ $this->assertContains('cluster read-only', $message);
+ }
+
+ try {
+ $index2->getType('test')->addDocument($doc4);
+ $this->fail('should throw read only exception');
+ } catch (ResponseException $e) {
+ $message = $e->getMessage();
+ $this->assertContains('ClusterBlockException', $message);
+ $this->assertContains('cluster read-only', $message);
+ }
+
+ $response = $settings->setReadOnly(false);
+ $this->assertFalse($response->hasError());
+ $setting = $settings->getTransient('cluster.blocks.read_only');
+ $this->assertEquals('false', $setting);
+
+ // Check that adding documents works again
+ $index1->getType('test')->addDocument($doc5);
+ $index2->getType('test')->addDocument($doc6);
+
+ $index1->refresh();
+ $index2->refresh();
+
+ // 2 docs should be in each index
+ $this->assertEquals(2, $index1->count());
+ $this->assertEquals(2, $index2->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ClusterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ClusterTest.php
new file mode 100644
index 00000000..ebd89f01
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ClusterTest.php
@@ -0,0 +1,83 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Cluster;
+use Elastica\Test\Base as BaseTest;
+
+class ClusterTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGetNodeNames()
+ {
+ $client = $this->_getClient();
+
+ $cluster = new Cluster($client);
+
+ foreach ($cluster->getNodeNames() as $name) {
+ $this->assertEquals('Elastica', $name);
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetNodes()
+ {
+ $client = $this->_getClient();
+ $cluster = $client->getCluster();
+
+ $nodes = $cluster->getNodes();
+
+ foreach ($nodes as $node) {
+ $this->assertInstanceOf('Elastica\Node', $node);
+ }
+
+ $this->assertGreaterThan(0, count($nodes));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetState()
+ {
+ $client = $this->_getClient();
+ $cluster = $client->getCluster();
+ $state = $cluster->getState();
+ $this->assertInternalType('array', $state);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetIndexNames()
+ {
+ $client = $this->_getClient();
+ $cluster = $client->getCluster();
+
+ $index = $this->_createIndex();
+ $index->delete();
+ $cluster->refresh();
+
+ // Checks that index does not exist
+ $indexNames = $cluster->getIndexNames();
+ $this->assertNotContains($index->getName(), $indexNames);
+
+ $index = $this->_createIndex();
+ $cluster->refresh();
+
+ // Now index should exist
+ $indexNames = $cluster->getIndexNames();
+ $this->assertContains($index->getname(), $indexNames);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetHealth()
+ {
+ $client = $this->_getClient();
+ $this->assertInstanceOf('Elastica\Cluster\Health', $client->getCluster()->getHealth());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/ConnectionPoolTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/ConnectionPoolTest.php
new file mode 100644
index 00000000..ee03587a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/ConnectionPoolTest.php
@@ -0,0 +1,112 @@
+<?php
+namespace Elastica\Test\Connection;
+
+use Elastica\Connection;
+use Elastica\Connection\ConnectionPool;
+use Elastica\Connection\Strategy\StrategyFactory;
+use Elastica\Test\Base as BaseTest;
+
+/**
+ * @author chabior
+ */
+class ConnectionPoolTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $pool = $this->createPool();
+
+ $this->assertEquals($this->getConnections(), $pool->getConnections());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetConnections()
+ {
+ $pool = $this->createPool();
+
+ $connections = $this->getConnections(5);
+
+ $pool->setConnections($connections);
+
+ $this->assertEquals($connections, $pool->getConnections());
+
+ $this->assertInstanceOf('Elastica\Connection\ConnectionPool', $pool->setConnections($connections));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddConnection()
+ {
+ $pool = $this->createPool();
+ $pool->setConnections(array());
+
+ $connections = $this->getConnections(5);
+
+ foreach ($connections as $connection) {
+ $pool->addConnection($connection);
+ }
+
+ $this->assertEquals($connections, $pool->getConnections());
+
+ $this->assertInstanceOf('Elastica\Connection\ConnectionPool', $pool->addConnection($connections[0]));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testHasConnection()
+ {
+ $pool = $this->createPool();
+
+ $this->assertTrue($pool->hasConnection());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFailHasConnections()
+ {
+ $pool = $this->createPool();
+
+ $pool->setConnections(array());
+
+ $this->assertFalse($pool->hasConnection());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetConnection()
+ {
+ $pool = $this->createPool();
+
+ $this->assertInstanceOf('Elastica\Connection', $pool->getConnection());
+ }
+
+ protected function getConnections($quantity = 1)
+ {
+ $params = array();
+ $connections = array();
+
+ for ($i = 0; $i < $quantity; $i++) {
+ $connections[] = new Connection($params);
+ }
+
+ return $connections;
+ }
+
+ protected function createPool()
+ {
+ $connections = $this->getConnections();
+ $strategy = StrategyFactory::create('Simple');
+
+ $pool = new ConnectionPool($connections, $strategy);
+
+ return $pool;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTest.php
new file mode 100644
index 00000000..de8290ae
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTest.php
@@ -0,0 +1,97 @@
+<?php
+namespace Elastica\Test\Connection\Strategy;
+
+use Elastica\Connection\Strategy\CallbackStrategy;
+use Elastica\Test\Base;
+
+/**
+ * Description of CallbackStrategyTest.
+ *
+ * @author chabior
+ */
+class CallbackStrategyTest extends Base
+{
+ /**
+ * @group unit
+ */
+ public function testInvoke()
+ {
+ $count = 0;
+
+ $callback = function ($connections) use (&$count) {
+ $count++;
+ };
+
+ $strategy = new CallbackStrategy($callback);
+ $strategy->getConnection(array());
+
+ $this->assertEquals(1, $count);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsValid()
+ {
+ // closure is valid
+ $isValid = CallbackStrategy::isValid(function () {});
+ $this->assertTrue($isValid);
+
+ // object implementing __invoke
+ $isValid = CallbackStrategy::isValid(new CallbackStrategyTestHelper());
+ $this->assertTrue($isValid);
+
+ // static method as string
+ $isValid = CallbackStrategy::isValid('Elastica\Test\Connection\Strategy\CallbackStrategyTestHelper::getFirstConnectionStatic');
+ $this->assertTrue($isValid);
+
+ // static method as array
+ $isValid = CallbackStrategy::isValid(array('Elastica\Test\Connection\Strategy\CallbackStrategyTestHelper', 'getFirstConnectionStatic'));
+ $this->assertTrue($isValid);
+
+ // object method
+ $isValid = CallbackStrategy::isValid(array(new CallbackStrategyTestHelper(), 'getFirstConnectionStatic'));
+ $this->assertTrue($isValid);
+
+ // function name
+ $isValid = CallbackStrategy::isValid('array_pop');
+ $this->assertTrue($isValid);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFailIsValid()
+ {
+ $isValid = CallbackStrategy::isValid(new \stdClass());
+ $this->assertFalse($isValid);
+
+ $isValid = CallbackStrategy::isValid('array_pop_pop_pop_pop_pop_pop');
+ $this->assertFalse($isValid);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testConnection()
+ {
+ $count = 0;
+
+ $config = array('connectionStrategy' => function ($connections) use (&$count) {
+ ++$count;
+
+ return current($connections);
+ });
+
+ $client = $this->_getClient($config);
+ $response = $client->request('/_aliases');
+
+ $this->assertEquals(1, $count);
+
+ $this->assertTrue($response->isOk());
+
+ $strategy = $client->getConnectionStrategy();
+
+ $this->assertInstanceOf('Elastica\Connection\Strategy\CallbackStrategy', $strategy);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTestHelper.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTestHelper.php
new file mode 100644
index 00000000..b15efe91
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/CallbackStrategyTestHelper.php
@@ -0,0 +1,20 @@
+<?php
+namespace Elastica\Test\Connection\Strategy;
+
+class CallbackStrategyTestHelper
+{
+ public function __invoke($connections)
+ {
+ return $connections[0];
+ }
+
+ public function getFirstConnection($connections)
+ {
+ return $connections[0];
+ }
+
+ public static function getFirstConnectionStatic($connections)
+ {
+ return $connections[0];
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/EmptyStrategy.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/EmptyStrategy.php
new file mode 100644
index 00000000..8d2aa5df
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/EmptyStrategy.php
@@ -0,0 +1,17 @@
+<?php
+namespace Elastica\Test\Connection\Strategy;
+
+use Elastica\Connection\Strategy\StrategyInterface;
+
+/**
+ * Description of EmptyStrategy.
+ *
+ * @author chabior
+ */
+class EmptyStrategy implements StrategyInterface
+{
+ public function getConnection($connections)
+ {
+ return;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/RoundRobinTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/RoundRobinTest.php
new file mode 100644
index 00000000..0dedbc22
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/RoundRobinTest.php
@@ -0,0 +1,128 @@
+<?php
+namespace Elastica\Test\Connection\Strategy;
+
+use Elastica\Connection;
+use Elastica\Connection\Strategy\RoundRobin;
+use Elastica\Exception\ConnectionException;
+use Elastica\Response;
+use Elastica\Test\Base;
+
+/**
+ * Description of RoundRobinTest.
+ *
+ * @author chabior
+ */
+class RoundRobinTest extends Base
+{
+ /**
+ * @var int Number of seconds to wait before timeout is called. Is set low for tests to have fast tests.
+ */
+ protected $_timeout = 1;
+
+ /**
+ * @group functional
+ */
+ public function testConnection()
+ {
+ $config = array('connectionStrategy' => 'RoundRobin');
+ $client = $this->_getClient($config);
+ $response = $client->request('/_aliases');
+ /* @var $response Response */
+
+ $this->_checkResponse($response);
+
+ $this->_checkStrategy($client);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testOldStrategySetted()
+ {
+ $config = array('roundRobin' => true);
+ $client = $this->_getClient($config);
+
+ $this->_checkStrategy($client);
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\ConnectionException
+ */
+ public function testFailConnection()
+ {
+ $config = array('connectionStrategy' => 'RoundRobin', 'host' => '255.255.255.0', 'timeout' => $this->_timeout);
+ $client = $this->_getClient($config);
+
+ $this->_checkStrategy($client);
+
+ $client->request('/_aliases');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithOneFailConnection()
+ {
+ $connections = array(
+ new Connection(array('host' => '255.255.255.0', 'timeout' => $this->_timeout)),
+ new Connection(array('host' => $this->_getHost(), 'timeout' => $this->_timeout)),
+ );
+
+ $count = 0;
+ $callback = function ($connection, $exception, $client) use (&$count) {
+ ++$count;
+ };
+
+ $client = $this->_getClient(array('connectionStrategy' => 'RoundRobin'), $callback);
+ $client->setConnections($connections);
+
+ $response = $client->request('/_aliases');
+ /* @var $response Response */
+
+ $this->_checkResponse($response);
+
+ $this->_checkStrategy($client);
+
+ $this->assertLessThan(count($connections), $count);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithNoValidConnection()
+ {
+ $connections = array(
+ new Connection(array('host' => '255.255.255.0', 'timeout' => $this->_timeout)),
+ new Connection(array('host' => '45.45.45.45', 'port' => '80', 'timeout' => $this->_timeout)),
+ new Connection(array('host' => '10.123.213.123', 'timeout' => $this->_timeout)),
+ );
+
+ $count = 0;
+ $client = $this->_getClient(array('roundRobin' => true), function () use (&$count) {
+ ++$count;
+ });
+
+ $client->setConnections($connections);
+
+ try {
+ $client->request('/_aliases');
+ $this->fail('Should throw exception as no connection valid');
+ } catch (ConnectionException $e) {
+ $this->assertEquals(count($connections), $count);
+ $this->_checkStrategy($client);
+ }
+ }
+
+ protected function _checkStrategy($client)
+ {
+ $strategy = $client->getConnectionStrategy();
+
+ $this->assertInstanceOf('Elastica\Connection\Strategy\RoundRobin', $strategy);
+ }
+
+ protected function _checkResponse($response)
+ {
+ $this->assertTrue($response->isOk());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/SimpleTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/SimpleTest.php
new file mode 100644
index 00000000..3b6ac89d
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/SimpleTest.php
@@ -0,0 +1,113 @@
+<?php
+namespace Elastica\Test\Connection\Strategy;
+
+use Elastica\Connection;
+use Elastica\Exception\ConnectionException;
+use Elastica\Test\Base;
+
+/**
+ * Description of SimplyTest.
+ *
+ * @author chabior
+ */
+class SimpleTest extends Base
+{
+ /**
+ * @var int Number of seconds to wait before timeout is called. Is set low for tests to have fast tests.
+ */
+ protected $_timeout = 1;
+
+ /**
+ * @group functional
+ */
+ public function testConnection()
+ {
+ $client = $this->_getClient();
+ $response = $client->request('/_aliases');
+ /* @var $response \Elastica\Response */
+
+ $this->_checkResponse($response);
+
+ $this->_checkStrategy($client);
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\ConnectionException
+ */
+ public function testFailConnection()
+ {
+ $config = array('host' => '255.255.255.0', 'timeout' => $this->_timeout);
+ $client = $this->_getClient($config);
+
+ $this->_checkStrategy($client);
+
+ $client->request('/_aliases');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithOneFailConnection()
+ {
+ $connections = array(
+ new Connection(array('host' => '255.255.255.0', 'timeout' => $this->_timeout)),
+ new Connection(array('host' => $this->_getHost(), 'timeout' => $this->_timeout)),
+ );
+
+ $count = 0;
+ $callback = function ($connection, $exception, $client) use (&$count) {
+ ++$count;
+ };
+
+ $client = $this->_getClient(array(), $callback);
+ $client->setConnections($connections);
+
+ $response = $client->request('/_aliases');
+ /* @var $response Response */
+
+ $this->_checkResponse($response);
+
+ $this->_checkStrategy($client);
+
+ $this->assertLessThan(count($connections), $count);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithNoValidConnection()
+ {
+ $connections = array(
+ new Connection(array('host' => '255.255.255.0', 'timeout' => $this->_timeout)),
+ new Connection(array('host' => '45.45.45.45', 'port' => '80', 'timeout' => $this->_timeout)),
+ new Connection(array('host' => '10.123.213.123', 'timeout' => $this->_timeout)),
+ );
+
+ $count = 0;
+ $client = $this->_getClient(array(), function () use (&$count) {
+ ++$count;
+ });
+
+ $client->setConnections($connections);
+
+ try {
+ $client->request('/_aliases');
+ $this->fail('Should throw exception as no connection valid');
+ } catch (ConnectionException $e) {
+ $this->assertEquals(count($connections), $count);
+ }
+ }
+
+ protected function _checkStrategy($client)
+ {
+ $strategy = $client->getConnectionStrategy();
+
+ $this->assertInstanceOf('Elastica\Connection\Strategy\Simple', $strategy);
+ }
+
+ protected function _checkResponse($response)
+ {
+ $this->assertTrue($response->isOk());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/StrategyFactoryTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/StrategyFactoryTest.php
new file mode 100644
index 00000000..978f8fd5
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Connection/Strategy/StrategyFactoryTest.php
@@ -0,0 +1,84 @@
+<?php
+namespace Elastica\Test\Connection\Strategy;
+
+use Elastica\Connection\Strategy\StrategyFactory;
+use Elastica\Test\Base;
+
+/**
+ * Description of StrategyFactoryTest.
+ *
+ * @author chabior
+ */
+class StrategyFactoryTest extends Base
+{
+ /**
+ * @group unit
+ */
+ public function testCreateCallbackStrategy()
+ {
+ $callback = function ($connections) {
+ };
+
+ $strategy = StrategyFactory::create($callback);
+
+ $this->assertInstanceOf('Elastica\Connection\Strategy\CallbackStrategy', $strategy);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreateByName()
+ {
+ $strategyName = 'Simple';
+
+ $strategy = StrategyFactory::create($strategyName);
+
+ $this->assertInstanceOf('Elastica\Connection\Strategy\Simple', $strategy);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreateByClass()
+ {
+ $strategy = new EmptyStrategy();
+
+ $this->assertEquals($strategy, StrategyFactory::create($strategy));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreateByClassName()
+ {
+ $strategyName = '\\Elastica\Test\Connection\Strategy\\EmptyStrategy';
+
+ $strategy = StrategyFactory::create($strategyName);
+
+ $this->assertInstanceOf($strategyName, $strategy);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \InvalidArgumentException
+ */
+ public function testFailCreate()
+ {
+ $strategy = new \stdClass();
+
+ StrategyFactory::create($strategy);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testNoCollisionWithGlobalNamespace()
+ {
+ // create collision
+ if (!class_exists('Simple')) {
+ class_alias('Elastica\Util', 'Simple');
+ }
+ $strategy = StrategyFactory::create('Simple');
+ $this->assertInstanceOf('Elastica\Connection\Strategy\Simple', $strategy);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ConnectionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ConnectionTest.php
new file mode 100644
index 00000000..7600524b
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ConnectionTest.php
@@ -0,0 +1,121 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Connection;
+use Elastica\Request;
+use Elastica\Test\Base as BaseTest;
+
+class ConnectionTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testEmptyConstructor()
+ {
+ $connection = new Connection();
+ $this->assertEquals(Connection::DEFAULT_HOST, $connection->getHost());
+ $this->assertEquals(Connection::DEFAULT_PORT, $connection->getPort());
+ $this->assertEquals(Connection::DEFAULT_TRANSPORT, $connection->getTransport());
+ $this->assertInstanceOf('Elastica\Transport\AbstractTransport', $connection->getTransportObject());
+ $this->assertEquals(Connection::TIMEOUT, $connection->getTimeout());
+ $this->assertEquals(Connection::CONNECT_TIMEOUT, $connection->getConnectTimeout());
+ $this->assertEquals(array(), $connection->getConfig());
+ $this->assertTrue($connection->isEnabled());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testEnabledDisable()
+ {
+ $connection = new Connection();
+ $this->assertTrue($connection->isEnabled());
+ $connection->setEnabled(false);
+ $this->assertFalse($connection->isEnabled());
+ $connection->setEnabled(true);
+ $this->assertTrue($connection->isEnabled());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\ConnectionException
+ */
+ public function testInvalidConnection()
+ {
+ $connection = new Connection(array('port' => 9999));
+
+ $request = new Request('_status', Request::GET);
+ $request->setConnection($connection);
+
+ // Throws exception because no valid connection
+ $request->send();
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreate()
+ {
+ $connection = Connection::create();
+ $this->assertInstanceOf('Elastica\Connection', $connection);
+
+ $connection = Connection::create(array());
+ $this->assertInstanceOf('Elastica\Connection', $connection);
+
+ $port = 9999;
+ $connection = Connection::create(array('port' => $port));
+ $this->assertInstanceOf('Elastica\Connection', $connection);
+ $this->assertEquals($port, $connection->getPort());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testCreateInvalid()
+ {
+ Connection::create('test');
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetConfig()
+ {
+ $url = 'test';
+ $connection = new Connection(array('config' => array('url' => $url)));
+ $this->assertTrue($connection->hasConfig('url'));
+ $this->assertEquals($url, $connection->getConfig('url'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetConfigWithArrayUsedForTransport()
+ {
+ $connection = new Connection(array('transport' => array('type' => 'Http')));
+ $this->assertInstanceOf('Elastica\Transport\Http', $connection->getTransportObject());
+ }
+
+ /**
+ * @group unit
+ * @expectedException Elastica\Exception\InvalidException
+ * @expectedExceptionMessage Invalid transport
+ */
+ public function testGetInvalidConfigWithArrayUsedForTransport()
+ {
+ $connection = new Connection(array('transport' => array('type' => 'invalidtransport')));
+ $connection->getTransportObject();
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testGetConfigInvalidValue()
+ {
+ $connection = new Connection();
+ $connection->getConfig('url');
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/DocumentTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/DocumentTest.php
new file mode 100644
index 00000000..969c5b22
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/DocumentTest.php
@@ -0,0 +1,349 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Exception\InvalidException;
+use Elastica\Index;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+
+class DocumentTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testAddFile()
+ {
+ $fileName = '/dev/null';
+ if (!file_exists($fileName)) {
+ $this->markTestSkipped("File {$fileName} does not exist.");
+ }
+ $doc = new Document();
+ $returnValue = $doc->addFile('key', $fileName);
+ $this->assertInstanceOf('Elastica\Document', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddGeoPoint()
+ {
+ $doc = new Document();
+ $returnValue = $doc->addGeoPoint('point', 38.89859, -77.035971);
+ $this->assertInstanceOf('Elastica\Document', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetData()
+ {
+ $doc = new Document();
+ $returnValue = $doc->setData(array('data'));
+ $this->assertInstanceOf('Elastica\Document', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $id = 17;
+ $data = array('hello' => 'world');
+ $type = 'testtype';
+ $index = 'textindex';
+
+ $doc = new Document($id, $data, $type, $index);
+
+ $result = array('_index' => $index, '_type' => $type, '_id' => $id, '_source' => $data);
+ $this->assertEquals($result, $doc->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetType()
+ {
+ $document = new Document();
+ $document->setType('type');
+
+ $this->assertEquals('type', $document->getType());
+
+ $index = new Index($this->_getClient(), 'index');
+ $type = $index->getType('type');
+
+ $document->setIndex('index2');
+ $this->assertEquals('index2', $document->getIndex());
+
+ $document->setType($type);
+
+ $this->assertEquals('index', $document->getIndex());
+ $this->assertEquals('type', $document->getType());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetIndex()
+ {
+ $document = new Document();
+ $document->setIndex('index2');
+ $document->setType('type2');
+
+ $this->assertEquals('index2', $document->getIndex());
+ $this->assertEquals('type2', $document->getType());
+
+ $index = new Index($this->_getClient(), 'index');
+
+ $document->setIndex($index);
+
+ $this->assertEquals('index', $document->getIndex());
+ $this->assertEquals('type2', $document->getType());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testHasId()
+ {
+ $document = new Document();
+ $this->assertFalse($document->hasId());
+ $document->setId('');
+ $this->assertFalse($document->hasId());
+ $document->setId(0);
+ $this->assertTrue($document->hasId());
+ $document->setId('hello');
+ $this->assertTrue($document->hasId());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetOptions()
+ {
+ $document = new Document();
+ $document->setIndex('index');
+ $document->setOpType('create');
+ $document->setParent('2');
+ $document->setId(1);
+
+ $options = $document->getOptions(array('index', 'type', 'id', 'parent'));
+
+ $this->assertInternalType('array', $options);
+ $this->assertEquals(3, count($options));
+ $this->assertArrayHasKey('index', $options);
+ $this->assertArrayHasKey('id', $options);
+ $this->assertArrayHasKey('parent', $options);
+ $this->assertEquals('index', $options['index']);
+ $this->assertEquals(1, $options['id']);
+ $this->assertEquals('2', $options['parent']);
+ $this->assertArrayNotHasKey('type', $options);
+ $this->assertArrayNotHasKey('op_type', $options);
+ $this->assertArrayNotHasKey('_index', $options);
+ $this->assertArrayNotHasKey('_id', $options);
+ $this->assertArrayNotHasKey('_parent', $options);
+
+ $options = $document->getOptions(array('parent', 'op_type', 'percolate'), true);
+
+ $this->assertInternalType('array', $options);
+ $this->assertEquals(2, count($options));
+ $this->assertArrayHasKey('_parent', $options);
+ $this->assertArrayHasKey('_op_type', $options);
+ $this->assertEquals('2', $options['_parent']);
+ $this->assertEquals('create', $options['_op_type']);
+ $this->assertArrayNotHasKey('percolate', $options);
+ $this->assertArrayNotHasKey('op_type', $options);
+ $this->assertArrayNotHasKey('parent', $options);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetSetHasRemove()
+ {
+ $document = new Document(1, array('field1' => 'value1', 'field2' => 'value2', 'field3' => 'value3', 'field4' => null));
+
+ $this->assertEquals('value1', $document->get('field1'));
+ $this->assertEquals('value2', $document->get('field2'));
+ $this->assertEquals('value3', $document->get('field3'));
+ $this->assertNull($document->get('field4'));
+ try {
+ $document->get('field5');
+ $this->fail('Undefined field get should throw exception');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+
+ $this->assertTrue($document->has('field1'));
+ $this->assertTrue($document->has('field2'));
+ $this->assertTrue($document->has('field3'));
+ $this->assertTrue($document->has('field4'));
+ $this->assertFalse($document->has('field5'), 'Field5 should not be isset, because it is not set');
+
+ $data = $document->getData();
+
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('value2', $data['field2']);
+ $this->assertArrayHasKey('field3', $data);
+ $this->assertEquals('value3', $data['field3']);
+ $this->assertArrayHasKey('field4', $data);
+ $this->assertNull($data['field4']);
+
+ $returnValue = $document->set('field1', 'changed1');
+ $this->assertInstanceOf('Elastica\Document', $returnValue);
+ $returnValue = $document->remove('field3');
+ $this->assertInstanceOf('Elastica\Document', $returnValue);
+ try {
+ $document->remove('field5');
+ $this->fail('Undefined field unset should throw exception');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+
+ $this->assertEquals('changed1', $document->get('field1'));
+ $this->assertFalse($document->has('field3'));
+
+ $newData = $document->getData();
+
+ $this->assertNotEquals($data, $newData);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testDataPropertiesOverloading()
+ {
+ $document = new Document(1, array('field1' => 'value1', 'field2' => 'value2', 'field3' => 'value3', 'field4' => null));
+
+ $this->assertEquals('value1', $document->field1);
+ $this->assertEquals('value2', $document->field2);
+ $this->assertEquals('value3', $document->field3);
+ $this->assertNull($document->field4);
+ try {
+ $document->field5;
+ $this->fail('Undefined field get should throw exception');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+
+ $this->assertTrue(isset($document->field1));
+ $this->assertTrue(isset($document->field2));
+ $this->assertTrue(isset($document->field3));
+ $this->assertFalse(isset($document->field4), 'Field4 should not be isset, because it is null');
+ $this->assertFalse(isset($document->field5), 'Field5 should not be isset, because it is not set');
+
+ $data = $document->getData();
+
+ $this->assertArrayHasKey('field1', $data);
+ $this->assertEquals('value1', $data['field1']);
+ $this->assertArrayHasKey('field2', $data);
+ $this->assertEquals('value2', $data['field2']);
+ $this->assertArrayHasKey('field3', $data);
+ $this->assertEquals('value3', $data['field3']);
+ $this->assertArrayHasKey('field4', $data);
+ $this->assertNull($data['field4']);
+
+ $document->field1 = 'changed1';
+ unset($document->field3);
+ try {
+ unset($document->field5);
+ $this->fail('Undefined field unset should throw exception');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+
+ $this->assertEquals('changed1', $document->field1);
+ $this->assertFalse(isset($document->field3));
+
+ $newData = $document->getData();
+
+ $this->assertNotEquals($data, $newData);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetTtl()
+ {
+ $document = new Document();
+
+ $this->assertFalse($document->hasTtl());
+ $options = $document->getOptions();
+ $this->assertArrayNotHasKey('ttl', $options);
+
+ $document->setTtl('1d');
+
+ $newOptions = $document->getOptions();
+
+ $this->assertArrayHasKey('ttl', $newOptions);
+ $this->assertEquals('1d', $newOptions['ttl']);
+ $this->assertNotEquals($options, $newOptions);
+
+ $this->assertTrue($document->hasTtl());
+ $this->assertEquals('1d', $document->getTtl());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSerializedData()
+ {
+ $data = '{"user":"rolf"}';
+ $document = new Document(1, $data);
+
+ $this->assertFalse($document->has('user'));
+
+ try {
+ $document->get('user');
+ $this->fail('User field should not be available');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $document->remove('user');
+ $this->fail('User field should not be available for removal');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $document->set('name', 'shawn');
+ $this->fail('Document should not allow to set new data');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testUpsert()
+ {
+ $document = new Document();
+
+ $upsert = new Document();
+ $upsert->setData(array('someproperty' => 'somevalue'));
+
+ $this->assertFalse($document->hasUpsert());
+
+ $document->setUpsert($upsert);
+
+ $this->assertTrue($document->hasUpsert());
+ $this->assertSame($upsert, $document->getUpsert());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testDocAsUpsert()
+ {
+ $document = new Document();
+
+ $this->assertFalse($document->getDocAsUpsert());
+ $this->assertSame($document, $document->setDocAsUpsert(true));
+ $this->assertTrue($document->getDocAsUpsert());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ExampleTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ExampleTest.php
new file mode 100644
index 00000000..efdc04eb
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ExampleTest.php
@@ -0,0 +1,61 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Test\Base as BaseTest;
+
+/**
+ * Tests the example code.
+ */
+class ExampleTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testBasicGettingStarted()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('ruflin');
+ $type = $index->getType('users');
+
+ $id = 2;
+ $data = array('firstname' => 'Nicolas', 'lastname' => 'Ruflin');
+ $doc = new Document($id, $data);
+
+ $type->addDocument($doc);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testExample()
+ {
+ // Creates a new index 'xodoa' and a type 'user' inside this index
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_test');
+ $index->create(array(), true);
+
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc1 = new Document(1,
+ array('username' => 'hans', 'test' => array('2', '3', '5'))
+ );
+ $type->addDocument($doc1);
+
+ // Adds a list of documents with _bulk upload to the index
+ $docs = array();
+ $docs[] = new Document(2,
+ array('username' => 'john', 'test' => array('1', '3', '6'))
+ );
+ $docs[] = new Document(3,
+ array('username' => 'rolf', 'test' => array('2', '3', '7'))
+ );
+ $type->addDocuments($docs);
+
+ // Refresh index
+ $index->refresh();
+
+ $resultSet = $type->search('rolf');
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/AbstractExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/AbstractExceptionTest.php
new file mode 100644
index 00000000..ea84218a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/AbstractExceptionTest.php
@@ -0,0 +1,31 @@
+<?php
+namespace Elastica\Test\Exception;
+
+use Elastica\Test\Base as BaseTest;
+
+abstract class AbstractExceptionTest extends BaseTest
+{
+ protected function _getExceptionClass()
+ {
+ $reflection = new \ReflectionObject($this);
+
+ // Elastica\Test\Exception\RuntimeExceptionTest => Elastica\Exception\RuntimeExceptionTest
+ $name = preg_replace('/^Elastica\\\\Test/', 'Elastica', $reflection->getName());
+
+ // Elastica\Exception\RuntimeExceptionTest => Elastica\Exception\RuntimeException
+ $name = preg_replace('/Test$/', '', $name);
+
+ return $name;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testInheritance()
+ {
+ $className = $this->_getExceptionClass();
+ $reflection = new \ReflectionClass($className);
+ $this->assertTrue($reflection->isSubclassOf('Exception'));
+ $this->assertTrue($reflection->implementsInterface('Elastica\Exception\ExceptionInterface'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/Response/ActionExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/Response/ActionExceptionTest.php
new file mode 100644
index 00000000..38a2f873
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/Response/ActionExceptionTest.php
@@ -0,0 +1,8 @@
+<?php
+namespace Elastica\Test\Exception\Bulk\Response;
+
+use Elastica\Test\Exception\AbstractExceptionTest;
+
+class ActionExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/ResponseExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/ResponseExceptionTest.php
new file mode 100644
index 00000000..2164f0e3
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/ResponseExceptionTest.php
@@ -0,0 +1,8 @@
+<?php
+namespace Elastica\Test\Exception\Bulk;
+
+use Elastica\Test\Exception\AbstractExceptionTest;
+
+class ResponseExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/UdpExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/UdpExceptionTest.php
new file mode 100644
index 00000000..2b7660bf
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Bulk/UdpExceptionTest.php
@@ -0,0 +1,8 @@
+<?php
+namespace Elastica\Test\Exception\Bulk;
+
+use Elastica\Test\Exception\AbstractExceptionTest;
+
+class UdpExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/BulkExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/BulkExceptionTest.php
new file mode 100644
index 00000000..1bd07689
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/BulkExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class BulkExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ClientExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ClientExceptionTest.php
new file mode 100644
index 00000000..3f75e456
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ClientExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class ClientExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/GuzzleExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/GuzzleExceptionTest.php
new file mode 100644
index 00000000..48a39de4
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/GuzzleExceptionTest.php
@@ -0,0 +1,14 @@
+<?php
+namespace Elastica\Test\Exception\Connection;
+
+use Elastica\Test\Exception\AbstractExceptionTest;
+
+class GuzzleExceptionTest extends AbstractExceptionTest
+{
+ public static function setUpBeforeClass()
+ {
+ if (!class_exists('GuzzleHttp\\Client')) {
+ self::markTestSkipped('guzzlehttp/guzzle package should be installed to run guzzle transport tests');
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/HttpExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/HttpExceptionTest.php
new file mode 100644
index 00000000..39d58013
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/HttpExceptionTest.php
@@ -0,0 +1,8 @@
+<?php
+namespace Elastica\Test\Exception\Connection;
+
+use Elastica\Test\Exception\AbstractExceptionTest;
+
+class HttpExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/MemcacheExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/MemcacheExceptionTest.php
new file mode 100644
index 00000000..5bf8fd35
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/MemcacheExceptionTest.php
@@ -0,0 +1,8 @@
+<?php
+namespace Elastica\Test\Exception\Connection;
+
+use Elastica\Test\Exception\AbstractExceptionTest;
+
+class MemcacheExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/ThriftExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/ThriftExceptionTest.php
new file mode 100644
index 00000000..5cef43be
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/Connection/ThriftExceptionTest.php
@@ -0,0 +1,14 @@
+<?php
+namespace Elastica\Test\Exception\Connection;
+
+use Elastica\Test\Exception\AbstractExceptionTest;
+
+class ThriftExceptionTest extends AbstractExceptionTest
+{
+ public static function setUpBeforeClass()
+ {
+ if (!class_exists('Elasticsearch\\RestClient')) {
+ self::markTestSkipped('munkie/elasticsearch-thrift-php package should be installed to run thrift exception tests');
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ConnectionExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ConnectionExceptionTest.php
new file mode 100644
index 00000000..5196b29e
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ConnectionExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class ConnectionExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ElasticsearchExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ElasticsearchExceptionTest.php
new file mode 100644
index 00000000..d11894f7
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ElasticsearchExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class ElasticsearchExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/InvalidExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/InvalidExceptionTest.php
new file mode 100644
index 00000000..e6e11899
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/InvalidExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class InvalidExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/JSONParseExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/JSONParseExceptionTest.php
new file mode 100644
index 00000000..4fd01c49
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/JSONParseExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class JSONParseExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotFoundExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotFoundExceptionTest.php
new file mode 100644
index 00000000..ff80a708
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotFoundExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class NotFoundExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotImplementedExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotImplementedExceptionTest.php
new file mode 100644
index 00000000..117aa012
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/NotImplementedExceptionTest.php
@@ -0,0 +1,19 @@
+<?php
+namespace Elastica\Test\Exception;
+
+use Elastica\Exception\NotImplementedException;
+
+class NotImplementedExceptionTest extends AbstractExceptionTest
+{
+ /**
+ * @group unit
+ */
+ public function testInstance()
+ {
+ $code = 4;
+ $message = 'Hello world';
+ $exception = new NotImplementedException($message, $code);
+ $this->assertEquals($message, $exception->getMessage());
+ $this->assertEquals($code, $exception->getCode());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/PartialShardFailureExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/PartialShardFailureExceptionTest.php
new file mode 100644
index 00000000..afcca1ec
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/PartialShardFailureExceptionTest.php
@@ -0,0 +1,54 @@
+<?php
+namespace Elastica\Test\Exception;
+
+use Elastica\Document;
+use Elastica\Exception\PartialShardFailureException;
+use Elastica\Query;
+use Elastica\ResultSet;
+
+class PartialShardFailureExceptionTest extends AbstractExceptionTest
+{
+ /**
+ * @group functional
+ */
+ public function testPartialFailure()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_partial_failure');
+ $index->create(array(
+ 'index' => array(
+ 'number_of_shards' => 5,
+ 'number_of_replicas' => 0,
+ ),
+ ), true);
+
+ $type = $index->getType('folks');
+
+ $type->addDocument(new Document('', array('name' => 'ruflin')));
+ $type->addDocument(new Document('', array('name' => 'bobrik')));
+ $type->addDocument(new Document('', array('name' => 'kimchy')));
+
+ $index->refresh();
+
+ $query = Query::create(array(
+ 'query' => array(
+ 'filtered' => array(
+ 'filter' => array(
+ 'script' => array(
+ 'script' => 'doc["undefined"] > 8', // compiles, but doesn't work
+ ),
+ ),
+ ),
+ ),
+ ));
+
+ try {
+ $index->search($query);
+
+ $this->fail('PartialShardFailureException should have been thrown');
+ } catch (PartialShardFailureException $e) {
+ $resultSet = new ResultSet($e->getResponse(), $query);
+ $this->assertEquals(0, count($resultSet->getResults()));
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/QueryBuilderExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/QueryBuilderExceptionTest.php
new file mode 100644
index 00000000..375731ba
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/QueryBuilderExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class QueryBuilderExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ResponseExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ResponseExceptionTest.php
new file mode 100644
index 00000000..6fc975e7
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/ResponseExceptionTest.php
@@ -0,0 +1,65 @@
+<?php
+namespace Elastica\Test\Exception;
+
+use Elastica\Document;
+use Elastica\Exception\ResponseException;
+
+class ResponseExceptionTest extends AbstractExceptionTest
+{
+ /**
+ * @group functional
+ */
+ public function testCreateExistingIndex()
+ {
+ $this->_createIndex('woo', true);
+
+ try {
+ $this->_createIndex('woo', false);
+ $this->fail('Index created when it should fail');
+ } catch (ResponseException $ex) {
+ $this->assertEquals('IndexAlreadyExistsException', $ex->getElasticsearchException()->getExceptionName());
+ $this->assertEquals(400, $ex->getElasticsearchException()->getCode());
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testBadType()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(array(
+ 'num' => array(
+ 'type' => 'long',
+ ),
+ ));
+
+ try {
+ $type->addDocument(new Document('', array(
+ 'num' => 'not number at all',
+ )));
+ $this->fail('Indexing with wrong type should fail');
+ } catch (ResponseException $ex) {
+ $this->assertEquals('MapperParsingException', $ex->getElasticsearchException()->getExceptionName());
+ $this->assertEquals(400, $ex->getElasticsearchException()->getCode());
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWhatever()
+ {
+ $index = $this->_createIndex();
+ $index->delete();
+
+ try {
+ $index->search();
+ } catch (ResponseException $ex) {
+ $this->assertEquals('IndexMissingException', $ex->getElasticsearchException()->getExceptionName());
+ $this->assertEquals(404, $ex->getElasticsearchException()->getCode());
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/RuntimeExceptionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/RuntimeExceptionTest.php
new file mode 100644
index 00000000..9dd18951
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Exception/RuntimeExceptionTest.php
@@ -0,0 +1,6 @@
+<?php
+namespace Elastica\Test\Exception;
+
+class RuntimeExceptionTest extends AbstractExceptionTest
+{
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/DateHistogramTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/DateHistogramTest.php
new file mode 100644
index 00000000..96d30aa2
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/DateHistogramTest.php
@@ -0,0 +1,106 @@
+<?php
+namespace Elastica\Test\Facet;
+
+use Elastica\Document;
+use Elastica\Facet\DateHistogram;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class DateHistogramTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testClassHierarchy()
+ {
+ $facet = new DateHistogram('dateHist1');
+ $this->assertInstanceOf('Elastica\Facet\Histogram', $facet);
+ $this->assertInstanceOf('Elastica\Facet\AbstractFacet', $facet);
+ unset($facet);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no'),
+ 'dtmPosted' => array('type' => 'date', 'store' => 'no', 'format' => 'yyyy-MM-dd HH:mm:ss'),
+ ));
+ $type->setMapping($mapping);
+
+ $doc = new Document(1, array('name' => 'nicolas ruflin', 'dtmPosted' => '2011-06-23 21:53:00'));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('name' => 'raul martinez jr', 'dtmPosted' => '2011-06-23 09:53:00'));
+ $type->addDocument($doc);
+ $doc = new Document(3, array('name' => 'rachelle clemente', 'dtmPosted' => '2011-07-08 08:53:00'));
+ $type->addDocument($doc);
+ $doc = new Document(4, array('name' => 'elastica search', 'dtmPosted' => '2011-07-08 01:53:00'));
+ $type->addDocument($doc);
+
+ $facet = new DateHistogram('dateHist1');
+ $facet->setInterval('day');
+ $facet->setField('dtmPosted');
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(4, $response->getTotalHits());
+ $this->assertEquals(2, count($facets['dateHist1']['entries']));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFactor()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no'),
+ 'dtmPosted' => array('type' => 'long', 'store' => 'no'),
+ ));
+ $type->setMapping($mapping);
+
+ $doc = new Document(1, array('name' => 'nicolas ruflin', 'dtmPosted' => 1308865980));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('name' => 'raul martinez jr', 'dtmPosted' => 1308822780));
+ $type->addDocument($doc);
+ $doc = new Document(3, array('name' => 'rachelle clemente', 'dtmPosted' => 1310115180));
+ $type->addDocument($doc);
+ $doc = new Document(4, array('name' => 'elastica search', 'dtmPosted' => 1310089980));
+ $type->addDocument($doc);
+
+ $facet = new DateHistogram('dateHist1');
+ $facet->setInterval('day');
+ $facet->setField('dtmPosted');
+ $facet->setFactor(1000);
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(4, $response->getTotalHits());
+ $this->assertEquals(2, count($facets['dateHist1']['entries']));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/FilterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/FilterTest.php
new file mode 100644
index 00000000..622923fe
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/FilterTest.php
@@ -0,0 +1,42 @@
+<?php
+namespace Elastica\Test\Facet;
+
+use Elastica\Document;
+use Elastica\Facet\Filter;
+use Elastica\Filter\Term;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+
+class FilterTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testFilter()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $type->addDocument(new Document(1, array('color' => 'red')));
+ $type->addDocument(new Document(2, array('color' => 'green')));
+ $type->addDocument(new Document(3, array('color' => 'blue')));
+
+ $index->refresh();
+
+ $filter = new Term(array('color' => 'red'));
+
+ $facet = new Filter('test');
+ $facet->setFilter($filter);
+
+ $query = new Query();
+ $query->addFacet($facet);
+
+ $resultSet = $type->search($query);
+
+ $facets = $resultSet->getFacets();
+
+ $this->assertEquals(1, $facets['test']['count']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/GeoClusterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/GeoClusterTest.php
new file mode 100644
index 00000000..f771ac32
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/GeoClusterTest.php
@@ -0,0 +1,57 @@
+<?php
+namespace Elastica\Test\Facet;
+
+use Elastica\Document;
+use Elastica\Facet\GeoCluster;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class GeoClusterTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $client = $this->_getClient();
+ $nodes = $client->getCluster()->getNodes();
+ if (!$nodes[0]->getInfo()->hasPlugin('geocluster-facet')) {
+ $this->markTestSkipped('geocluster-facet plugin not installed');
+ }
+
+ $index = $this->_createIndex();
+ $type = $index->getType('testQuery');
+ $geoField = 'location';
+
+ $type->setMapping(new Mapping($type, array(
+ $geoField => array('type' => 'geo_point', 'lat_lon' => true),
+ )));
+
+ $doc = new Document(1, array('name' => 'item1', 'location' => array(20, 20)));
+ $type->addDocument($doc);
+
+ $doc = new Document(2, array('name' => 'item2', 'location' => array(20, 20)));
+ $type->addDocument($doc);
+
+ $doc = new Document(3, array('name' => 'item3', 'location' => array(20, 20)));
+ $type->addDocument($doc);
+
+ $index->refresh();
+
+ $facet = new GeoCluster('clusters');
+ $facet
+ ->setField($geoField)
+ ->setFactor(1)
+ ->setShowIds(false);
+ $query = new Query();
+ $query->setFacets(array($facet));
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(1, count($facets['clusters']['clusters']));
+
+ $index->delete();
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/QueryTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/QueryTest.php
new file mode 100644
index 00000000..8e0231aa
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/QueryTest.php
@@ -0,0 +1,42 @@
+<?php
+namespace Elastica\Test\Facet;
+
+use Elastica\Document;
+use Elastica\Facet\Query as FacetQuery;
+use Elastica\Query;
+use Elastica\Query\Term;
+use Elastica\Test\Base as BaseTest;
+
+class QueryTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testFilter()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $type->addDocument(new Document(1, array('color' => 'red')));
+ $type->addDocument(new Document(2, array('color' => 'green')));
+ $type->addDocument(new Document(3, array('color' => 'blue')));
+
+ $index->refresh();
+
+ $termQuery = new Term(array('color' => 'red'));
+
+ $facet = new FacetQuery('test');
+ $facet->setQuery($termQuery);
+
+ $query = new Query();
+ $query->addFacet($facet);
+
+ $resultSet = $type->search($query);
+
+ $facets = $resultSet->getFacets();
+
+ $this->assertEquals(1, $facets['test']['count']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/StatisticalTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/StatisticalTest.php
new file mode 100644
index 00000000..dc374289
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/StatisticalTest.php
@@ -0,0 +1,82 @@
+<?php
+namespace Elastica\Test\Facet;
+
+use Elastica\Document;
+use Elastica\Facet\Statistical;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+/**
+ * @todo Add test for Statistical with setScript
+ */
+class StatisticalTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testStatisticalWithSetField()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('price' => 10));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('price' => 35));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('price' => 45));
+ $type->addDocument($doc);
+
+ $facet = new Statistical('stats');
+ $facet->setField('price');
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(55, $facets['stats']['total']);
+ $this->assertEquals(10, $facets['stats']['min']);
+ $this->assertEquals(45, $facets['stats']['max']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testStatisticalWithSetFields()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('price' => 10, 'price2' => 20));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('price' => 35, 'price2' => 70));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('price' => 45, 'price2' => 90));
+ $type->addDocument($doc);
+
+ $facet = new Statistical('stats');
+ $facet->setFields(array('price', 'price2'));
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(165, $facets['stats']['total']);
+ $this->assertEquals(10, $facets['stats']['min']);
+ $this->assertEquals(90, $facets['stats']['max']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsStatsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsStatsTest.php
new file mode 100644
index 00000000..e3377930
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsStatsTest.php
@@ -0,0 +1,113 @@
+<?php
+namespace Elastica\Test\Facet;
+
+use Elastica\Document;
+use Elastica\Facet\TermsStats;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class TermsStatsTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testOrder()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('name' => 'tom', 'paid' => 7));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('name' => 'tom', 'paid' => 2));
+ $type->addDocument($doc);
+ $doc = new Document(3, array('name' => 'tom', 'paid' => 5));
+ $type->addDocument($doc);
+ $doc = new Document(4, array('name' => 'mike', 'paid' => 13));
+ $type->addDocument($doc);
+ $doc = new Document(5, array('name' => 'mike', 'paid' => 1));
+ $type->addDocument($doc);
+ $doc = new Document(6, array('name' => 'mike', 'paid' => 15));
+ $type->addDocument($doc);
+
+ $facet = new TermsStats('test');
+ $facet->setKeyField('name');
+ $facet->setValueField('paid');
+ $facet->setOrder('reverse_total');
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(14, $facets[ 'test' ][ 'terms' ][0]['total']);
+ $this->assertEquals(29, $facets[ 'test' ][ 'terms' ][1]['total']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('name' => 'tom', 'paid' => 7));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('name' => 'tom', 'paid' => 2));
+ $type->addDocument($doc);
+ $doc = new Document(3, array('name' => 'tom', 'paid' => 5));
+ $type->addDocument($doc);
+ $doc = new Document(4, array('name' => 'mike', 'paid' => 13));
+ $type->addDocument($doc);
+ $doc = new Document(5, array('name' => 'mike', 'paid' => 1));
+ $type->addDocument($doc);
+ $doc = new Document(6, array('name' => 'mike', 'paid' => 15));
+ $type->addDocument($doc);
+
+ $facet = new TermsStats('test');
+ $facet->setKeyField('name');
+ $facet->setValueField('paid');
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(2, count($facets[ 'test' ][ 'terms' ]));
+ foreach ($facets[ 'test' ][ 'terms' ] as $facet) {
+ if ($facet[ 'term' ] === 'tom') {
+ $this->assertEquals(14, $facet[ 'total' ]);
+ }
+ if ($facet[ 'term' ] === 'mike') {
+ $this->assertEquals(29, $facet[ 'total' ]);
+ }
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSize()
+ {
+ $facet = new TermsStats('test');
+ $facet->setSize(100);
+
+ $data = $facet->toArray();
+
+ $this->assertArrayHasKey('size', $data['terms_stats']);
+ $this->assertEquals(100, $data['terms_stats']['size']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsTest.php
new file mode 100644
index 00000000..f4c95796
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Facet/TermsTest.php
@@ -0,0 +1,74 @@
+<?php
+namespace Elastica\Test\Facet;
+
+use Elastica\Document;
+use Elastica\Facet\Terms;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class TermsTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('name' => 'nicolas ruflin'));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('name' => 'ruflin test'));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('name' => 'nicolas helloworld'));
+ $type->addDocument($doc);
+
+ $facet = new Terms('test');
+ $facet->setField('name');
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(3, count($facets['test']['terms']));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFacetScript()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('name' => 'rodolfo', 'last_name' => 'moraes'));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('name' => 'jose', 'last_name' => 'honjoya'));
+ $type->addDocument($doc);
+
+ $facet = new Terms('test');
+ $facet->setField('name');
+ $facet->setScript('term + " "+doc["last_name"].value');
+
+ $query = new Query();
+ $query->addFacet($facet);
+ $query->setQuery(new MatchAll());
+
+ $index->refresh();
+
+ $response = $type->search($query);
+ $facets = $response->getFacets();
+
+ $this->assertEquals(2, count($facets['test']['terms']));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/AbstractTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/AbstractTest.php
new file mode 100644
index 00000000..3ba64dd1
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/AbstractTest.php
@@ -0,0 +1,81 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Test\Base as BaseTest;
+
+class AbstractTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testSetCached()
+ {
+ $stubFilter = $this->getStub();
+
+ $stubFilter->setCached(true);
+ $arrayFilter = current($stubFilter->toArray());
+ $this->assertTrue($arrayFilter['_cache']);
+
+ $stubFilter->setCached(false);
+ $arrayFilter = current($stubFilter->toArray());
+ $this->assertFalse($arrayFilter['_cache']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetCachedDefaultValue()
+ {
+ $stubFilter = $this->getStub();
+
+ $stubFilter->setCached();
+ $arrayFilter = current($stubFilter->toArray());
+ $this->assertTrue($arrayFilter['_cache']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetCacheKey()
+ {
+ $stubFilter = $this->getStub();
+
+ $cacheKey = 'myCacheKey';
+
+ $stubFilter->setCacheKey($cacheKey);
+ $arrayFilter = current($stubFilter->toArray());
+ $this->assertEquals($cacheKey, $arrayFilter['_cache_key']);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testSetCacheKeyEmptyKey()
+ {
+ $stubFilter = $this->getStub();
+
+ $cacheKey = '';
+
+ $stubFilter->setCacheKey($cacheKey);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetName()
+ {
+ $stubFilter = $this->getStub();
+
+ $name = 'myFilter';
+
+ $stubFilter->setName($name);
+ $arrayFilter = current($stubFilter->toArray());
+ $this->assertEquals($name, $arrayFilter['_name']);
+ }
+
+ private function getStub()
+ {
+ return $this->getMockForAbstractClass('Elastica\Filter\AbstractFilter');
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolAndTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolAndTest.php
new file mode 100644
index 00000000..a8f47633
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolAndTest.php
@@ -0,0 +1,86 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\BoolAnd;
+use Elastica\Filter\Ids;
+use Elastica\Test\Base as BaseTest;
+
+class BoolAndTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $and = new BoolAnd();
+ $this->assertEquals(array('and' => array()), $and->toArray());
+
+ $idsFilter = new Ids();
+ $idsFilter->setIds(12);
+
+ $and->addFilter($idsFilter);
+ $and->addFilter($idsFilter);
+
+ $expectedArray = array(
+ 'and' => array(
+ $idsFilter->toArray(),
+ $idsFilter->toArray(),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $and->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetCache()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'hello world')),
+ new Document(2, array('name' => 'nicolas ruflin')),
+ new Document(3, array('name' => 'ruflin')),
+ ));
+
+ $and = new BoolAnd();
+
+ $idsFilter1 = new Ids();
+ $idsFilter1->setIds(1);
+
+ $idsFilter2 = new Ids();
+ $idsFilter2->setIds(1);
+
+ $and->addFilter($idsFilter1);
+ $and->addFilter($idsFilter2);
+
+ $index->refresh();
+ $and->setCached(true);
+
+ $resultSet = $type->search($and);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $ids1 = new Ids('foo', array(1, 2));
+ $ids2 = new Ids('bar', array(3, 4));
+
+ $and1 = new BoolAnd(array($ids1, $ids2));
+
+ $and2 = new BoolAnd();
+ $and2->addFilter($ids1);
+ $and2->addFilter($ids2);
+
+ $this->assertEquals($and1->toArray(), $and2->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolFilterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolFilterTest.php
new file mode 100644
index 00000000..ec7728af
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolFilterTest.php
@@ -0,0 +1,200 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\BoolFilter;
+use Elastica\Filter\Ids;
+use Elastica\Filter\Term;
+use Elastica\Filter\Terms;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+
+class BoolFilterTest extends BaseTest
+{
+ /**
+ * @return array
+ */
+ public function getTestToArrayData()
+ {
+ $out = array();
+
+ // case #0
+ $mainBool = new BoolFilter();
+
+ $idsFilter1 = new Ids();
+ $idsFilter1->setIds(1);
+ $idsFilter2 = new Ids();
+ $idsFilter2->setIds(2);
+ $idsFilter3 = new Ids();
+ $idsFilter3->setIds(3);
+
+ $childBool = new BoolFilter();
+ $childBool->addShould(array($idsFilter1, $idsFilter2));
+ $mainBool->addShould(array($childBool, $idsFilter3));
+
+ $expectedArray = array(
+ 'bool' => array(
+ 'should' => array(
+ array(
+ array(
+ 'bool' => array(
+ 'should' => array(
+ array(
+ $idsFilter1->toArray(),
+ $idsFilter2->toArray(),
+ ),
+ ),
+ ),
+ ),
+ $idsFilter3->toArray(),
+ ),
+ ),
+ ),
+ );
+ $out[] = array($mainBool, $expectedArray);
+
+ // case #1 _cache parameter should be supported
+ $bool = new BoolFilter();
+ $terms = new Terms('field1', array('value1', 'value2'));
+ $termsNot = new Terms('field2', array('value1', 'value2'));
+ $bool->addMust($terms);
+ $bool->addMustNot($termsNot);
+ $bool->setCached(true);
+ $bool->setCacheKey('my-cache-key');
+ $expected = array(
+ 'bool' => array(
+ 'must' => array(
+ $terms->toArray(),
+ ),
+ 'must_not' => array(
+ $termsNot->toArray(),
+ ),
+ '_cache' => true,
+ '_cache_key' => 'my-cache-key',
+ ),
+ );
+ $out[] = array($bool, $expected);
+
+ return $out;
+ }
+
+ /**
+ * @group unit
+ * @dataProvider getTestToArrayData()
+ *
+ * @param Bool $bool
+ * @param array $expectedArray
+ */
+ public function testToArray(BoolFilter $bool, $expectedArray)
+ {
+ $this->assertEquals($expectedArray, $bool->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testBoolFilter()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('book');
+
+ //index some test data
+ $type->addDocuments(array(
+ new Document(1, array('author' => 'Michael Shermer', 'title' => 'The Believing Brain', 'publisher' => 'Robinson')),
+ new Document(2, array('author' => 'Jared Diamond', 'title' => 'Guns, Germs and Steel', 'publisher' => 'Vintage')),
+ new Document(3, array('author' => 'Jared Diamond', 'title' => 'Collapse', 'publisher' => 'Penguin')),
+ new Document(4, array('author' => 'Richard Dawkins', 'title' => 'The Selfish Gene', 'publisher' => 'OUP Oxford')),
+ new Document(5, array('author' => 'Anthony Burges', 'title' => 'A Clockwork Orange', 'publisher' => 'Penguin')),
+ ));
+
+ $index->refresh();
+
+ //use the terms lookup feature to query for some data
+ //build query
+ //must
+ // should
+ // author = jared
+ // author = richard
+ // must_not
+ // publisher = penguin
+
+ //construct the query
+ $query = new Query();
+ $mainBoolFilter = new BoolFilter();
+ $shouldFilter = new BoolFilter();
+ $authorFilter1 = new Term();
+ $authorFilter1->setTerm('author', 'jared');
+ $authorFilter2 = new Term();
+ $authorFilter2->setTerm('author', 'richard');
+ $shouldFilter->addShould(array($authorFilter1, $authorFilter2));
+
+ $mustNotFilter = new BoolFilter();
+ $publisherFilter = new Term();
+ $publisherFilter->setTerm('publisher', 'penguin');
+ $mustNotFilter->addMustNot($publisherFilter);
+
+ $mainBoolFilter->addMust(array($shouldFilter, $mustNotFilter));
+ $query->setPostFilter($mainBoolFilter);
+ //execute the query
+ $results = $index->search($query);
+
+ //check the number of results
+ $this->assertEquals($results->count(), 2, 'Bool filter with child Bool filters: number of results check');
+
+ //count compare the id's
+ $ids = array();
+ /** @var \Elastica\Result $result **/
+ foreach ($results as $result) {
+ $ids[] = $result->getId();
+ }
+ $this->assertEquals($ids, array('2', '4'), 'Bool filter with child Bool filters: result ID check');
+
+ $index->delete();
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testAddMustInvalidException()
+ {
+ $filter = new BoolFilter();
+ $filter->addMust('fail!');
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testAddMustNotInvalidException()
+ {
+ $filter = new BoolFilter();
+ $filter->addMustNot('fail!');
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testAddShouldInvalidException()
+ {
+ $filter = new BoolFilter();
+ $filter->addShould('fail!');
+ }
+
+ /**
+ * Small unit test to check if also the old object name works.
+ *
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testOldObject()
+ {
+ if (version_compare(phpversion(), 7, '>=')) {
+ self::markTestSkipped('These objects are not supported in PHP 7');
+ }
+
+ $filter = new \Elastica\Filter\Bool();
+ $filter->addShould('fail!');
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolNotTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolNotTest.php
new file mode 100644
index 00000000..75461496
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolNotTest.php
@@ -0,0 +1,27 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\BoolNot;
+use Elastica\Filter\Ids;
+use Elastica\Test\Base as BaseTest;
+
+class BoolNotTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $idsFilter = new Ids();
+ $idsFilter->setIds(12);
+ $filter = new BoolNot($idsFilter);
+
+ $expectedArray = array(
+ 'not' => array(
+ 'filter' => $idsFilter->toArray(),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolOrTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolOrTest.php
new file mode 100644
index 00000000..6462d1fa
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/BoolOrTest.php
@@ -0,0 +1,90 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\BoolOr;
+use Elastica\Filter\Ids;
+use Elastica\Test\Base as BaseTest;
+
+class BoolOrTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testAddFilter()
+ {
+ $filter = $this->getMockForAbstractClass('Elastica\Filter\AbstractFilter');
+ $orFilter = new BoolOr();
+ $returnValue = $orFilter->addFilter($filter);
+ $this->assertInstanceOf('Elastica\Filter\BoolOr', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $orFilter = new BoolOr();
+
+ $filter1 = new Ids();
+ $filter1->setIds('1');
+
+ $filter2 = new Ids();
+ $filter2->setIds('2');
+
+ $orFilter->addFilter($filter1);
+ $orFilter->addFilter($filter2);
+
+ $expectedArray = array(
+ 'or' => array(
+ $filter1->toArray(),
+ $filter2->toArray(),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $orFilter->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $ids1 = new Ids('foo', array(1, 2));
+ $ids2 = new Ids('bar', array(3, 4));
+
+ $and1 = new BoolOr(array($ids1, $ids2));
+
+ $and2 = new BoolOr();
+ $and2->addFilter($ids1);
+ $and2->addFilter($ids2);
+
+ $this->assertEquals($and1->toArray(), $and2->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testOrFilter()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $doc1 = new Document('', array('categoryId' => 1));
+ $doc2 = new Document('', array('categoryId' => 2));
+ $doc3 = new Document('', array('categoryId' => 3));
+
+ $type->addDocument($doc1);
+ $type->addDocument($doc2);
+ $type->addDocument($doc3);
+
+ $index->refresh();
+
+ $boolOr = new \Elastica\Filter\BoolOr();
+ $boolOr->addFilter(new \Elastica\Filter\Term(array('categoryId' => '1')));
+ $boolOr->addFilter(new \Elastica\Filter\Term(array('categoryId' => '2')));
+
+ $resultSet = $type->search($boolOr);
+ $this->assertEquals(2, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ExistsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ExistsTest.php
new file mode 100644
index 00000000..25afa724
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ExistsTest.php
@@ -0,0 +1,36 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Exists;
+use Elastica\Test\Base as BaseTest;
+
+class ExistsTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $field = 'test';
+ $filter = new Exists($field);
+
+ $expectedArray = array('exists' => array('field' => $field));
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetField()
+ {
+ $field = 'test';
+ $filter = new Exists($field);
+
+ $this->assertEquals($field, $filter->getParam('field'));
+
+ $newField = 'hello world';
+ $this->assertInstanceOf('Elastica\Filter\Exists', $filter->setField($newField));
+
+ $this->assertEquals($newField, $filter->getParam('field'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoBoundingBoxTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoBoundingBoxTest.php
new file mode 100644
index 00000000..8fdde965
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoBoundingBoxTest.php
@@ -0,0 +1,55 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\GeoBoundingBox;
+use Elastica\Test\Base as BaseTest;
+
+class GeoBoundingBoxTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testAddCoordinates()
+ {
+ $key = 'pin.location';
+ $coords = array('40.73, -74.1', '40.01, -71.12');
+ $filter = new GeoBoundingBox($key, array('1,2', '3,4'));
+
+ $filter->addCoordinates($key, $coords);
+ $expectedArray = array('top_left' => $coords[0], 'bottom_right' => $coords[1]);
+ $this->assertEquals($expectedArray, $filter->getParam($key));
+
+ $returnValue = $filter->addCoordinates($key, $coords);
+ $this->assertInstanceOf('Elastica\Filter\GeoBoundingBox', $returnValue);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testAddCoordinatesInvalidException()
+ {
+ $filter = new GeoBoundingBox('foo', array());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $key = 'pin.location';
+ $coords = array('40.73, -74.1', '40.01, -71.12');
+ $filter = new GeoBoundingBox($key, $coords);
+
+ $expectedArray = array(
+ 'geo_bounding_box' => array(
+ $key => array(
+ 'top_left' => $coords[0],
+ 'bottom_right' => $coords[1],
+ ),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceRangeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceRangeTest.php
new file mode 100644
index 00000000..203a45de
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceRangeTest.php
@@ -0,0 +1,220 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\GeoDistanceRange;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class GeoDistanceRangeTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGeoPoint()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ // Set mapping
+ $type->setMapping(array('point' => array('type' => 'geo_point')));
+
+ // Add doc 1
+ $doc1 = new Document(1,
+ array(
+ 'name' => 'ruflin',
+ )
+ );
+
+ $doc1->addGeoPoint('point', 17, 19);
+ $type->addDocument($doc1);
+
+ // Add doc 2
+ $doc2 = new Document(2,
+ array(
+ 'name' => 'ruflin',
+ )
+ );
+
+ $doc2->addGeoPoint('point', 30, 40);
+ $type->addDocument($doc2);
+
+ $index->optimize();
+ $index->refresh();
+
+ // Only one point should be in radius
+ $query = new Query();
+ $geoFilter = new GeoDistanceRange(
+ 'point',
+ array('lat' => 30, 'lon' => 40),
+ array('from' => '0km', 'to' => '2km')
+ );
+
+ $query = new Query(new MatchAll());
+ $query->setPostFilter($geoFilter);
+ $this->assertEquals(1, $type->search($query)->count());
+
+ // Both points should be inside
+ $query = new Query();
+ $geoFilter = new GeoDistanceRange(
+ 'point',
+ array('lat' => 30, 'lon' => 40),
+ array('gte' => '0km', 'lte' => '40000km')
+ );
+ $query = new Query(new MatchAll());
+ $query->setPostFilter($geoFilter);
+ $index->refresh();
+
+ $this->assertEquals(2, $type->search($query)->count());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testInvalidRange()
+ {
+ $geoFilter = new GeoDistanceRange(
+ 'point',
+ array('lat' => 30, 'lon' => 40),
+ array('invalid' => '0km', 'lte' => '40000km')
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider invalidLocationDataProvider
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testInvalidLocation($location)
+ {
+ $geoFilter = new GeoDistanceRange(
+ 'point',
+ $location,
+ array('gt' => '0km', 'lte' => '40000km')
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider constructDataProvider
+ */
+ public function testConstruct($key, $location, $ranges, $expected)
+ {
+ $filter = new GeoDistanceRange($key, $location, $ranges);
+
+ $data = $filter->toArray();
+
+ $this->assertEquals($expected, $data);
+ }
+
+ public function invalidLocationDataProvider()
+ {
+ return array(
+ array(
+ array('lat' => 1.0),
+ ),
+ array(
+ array('lon' => 1.0),
+ ),
+ array(
+ array(),
+ ),
+ array(
+ new \stdClass(),
+ ),
+ array(
+ null,
+ ),
+ array(
+ true,
+ ),
+ array(
+ false,
+ ),
+ );
+ }
+
+ public function constructDataProvider()
+ {
+ return array(
+ array(
+ 'location',
+ 'u09tvqx',
+ array(
+ 'from' => '10km',
+ 'to' => '20km',
+ ),
+ array(
+ 'geo_distance_range' => array(
+ 'from' => '10km',
+ 'to' => '20km',
+ 'location' => 'u09tvqx',
+ ),
+ ),
+ ),
+ array(
+ 'location',
+ 'u09tvqx',
+ array(
+ 'to' => '20km',
+ 'include_upper' => 0,
+ 'from' => '10km',
+ 'include_lower' => 1,
+ ),
+ array(
+ 'geo_distance_range' => array(
+ 'to' => '20km',
+ 'include_upper' => false,
+ 'from' => '10km',
+ 'include_lower' => true,
+ 'location' => 'u09tvqx',
+ ),
+ ),
+ ),
+ array(
+ 'location',
+ array(
+ 'lon' => 2.35,
+ 'lat' => 48.86,
+ ),
+ array(
+ 'lte' => '20km',
+ 'gt' => '10km',
+ ),
+ array(
+ 'geo_distance_range' => array(
+ 'lte' => '20km',
+ 'gt' => '10km',
+ 'location' => array(
+ 'lat' => 48.86,
+ 'lon' => 2.35,
+ ),
+ ),
+ ),
+ ),
+ array(
+ 'location',
+ array(
+ 'lat' => 48.86,
+ 'lon' => 2.35,
+ ),
+ array(
+ 'lt' => '20km',
+ 'gte' => '10km',
+ ),
+ array(
+ 'geo_distance_range' => array(
+ 'lt' => '20km',
+ 'gte' => '10km',
+ 'location' => array(
+ 'lat' => 48.86,
+ 'lon' => 2.35,
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceTest.php
new file mode 100644
index 00000000..b61b4adc
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoDistanceTest.php
@@ -0,0 +1,141 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\GeoDistance;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class GeoDistanceTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGeoPoint()
+ {
+ $index = $this->_createIndex();
+
+ $type = $index->getType('test');
+
+ // Set mapping
+ $type->setMapping(array('point' => array('type' => 'geo_point')));
+
+ // Add doc 1
+ $doc1 = new Document(1,
+ array(
+ 'name' => 'ruflin',
+ )
+ );
+
+ $doc1->addGeoPoint('point', 17, 19);
+ $type->addDocument($doc1);
+
+ // Add doc 2
+ $doc2 = new Document(2,
+ array(
+ 'name' => 'ruflin',
+ )
+ );
+
+ $doc2->addGeoPoint('point', 30, 40);
+ $type->addDocument($doc2);
+
+ $index->optimize();
+ $index->refresh();
+
+ // Only one point should be in radius
+ $query = new Query();
+ $geoFilter = new GeoDistance('point', array('lat' => 30, 'lon' => 40), '1km');
+
+ $query = new Query(new MatchAll());
+ $query->setPostFilter($geoFilter);
+ $this->assertEquals(1, $type->search($query)->count());
+
+ // Both points should be inside
+ $query = new Query();
+ $geoFilter = new GeoDistance('point', array('lat' => 30, 'lon' => 40), '40000km');
+ $query = new Query(new MatchAll());
+ $query->setPostFilter($geoFilter);
+ $index->refresh();
+
+ $this->assertEquals(2, $type->search($query)->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstructLatlon()
+ {
+ $key = 'location';
+ $location = array(
+ 'lat' => 48.86,
+ 'lon' => 2.35,
+ );
+ $distance = '10km';
+
+ $filter = new GeoDistance($key, $location, $distance);
+
+ $expected = array(
+ 'geo_distance' => array(
+ $key => $location,
+ 'distance' => $distance,
+ ),
+ );
+
+ $data = $filter->toArray();
+
+ $this->assertEquals($expected, $data);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstructGeohash()
+ {
+ $key = 'location';
+ $location = 'u09tvqx';
+ $distance = '10km';
+
+ $filter = new GeoDistance($key, $location, $distance);
+
+ $expected = array(
+ 'geo_distance' => array(
+ $key => $location,
+ 'distance' => $distance,
+ ),
+ );
+
+ $data = $filter->toArray();
+
+ $this->assertEquals($expected, $data);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetDistanceType()
+ {
+ $filter = new GeoDistance('location', array('lat' => 48.86, 'lon' => 2.35), '10km');
+ $distanceType = GeoDistance::DISTANCE_TYPE_ARC;
+ $filter->setDistanceType($distanceType);
+
+ $data = $filter->toArray();
+
+ $this->assertEquals($distanceType, $data['geo_distance']['distance_type']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetOptimizeBbox()
+ {
+ $filter = new GeoDistance('location', array('lat' => 48.86, 'lon' => 2.35), '10km');
+ $optimizeBbox = GeoDistance::OPTIMIZE_BBOX_MEMORY;
+ $filter->setOptimizeBbox($optimizeBbox);
+
+ $data = $filter->toArray();
+
+ $this->assertEquals($optimizeBbox, $data['geo_distance']['optimize_bbox']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoPolygonTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoPolygonTest.php
new file mode 100644
index 00000000..b56f73b0
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoPolygonTest.php
@@ -0,0 +1,65 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\GeoPolygon;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class GeoPolygonTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGeoPoint()
+ {
+ $index = $this->_createIndex();
+
+ $type = $index->getType('test');
+
+ // Set mapping
+ $type->setMapping(array('location' => array('type' => 'geo_point')));
+
+ // Add doc 1
+ $doc1 = new Document(1,
+ array(
+ 'name' => 'ruflin',
+ )
+ );
+
+ $doc1->addGeoPoint('location', 17, 19);
+ $type->addDocument($doc1);
+
+ // Add doc 2
+ $doc2 = new Document(2,
+ array(
+ 'name' => 'ruflin',
+ )
+ );
+
+ $doc2->addGeoPoint('location', 30, 40);
+ $type->addDocument($doc2);
+
+ $index->refresh();
+
+ // Only one point should be in polygon
+ $query = new Query();
+ $points = array(array(16, 16), array(16, 20), array(20, 20), array(20, 16), array(16, 16));
+ $geoFilter = new GeoPolygon('location', $points);
+
+ $query = new Query(new MatchAll());
+ $query->setPostFilter($geoFilter);
+ $this->assertEquals(1, $type->search($query)->count());
+
+ // Both points should be inside
+ $query = new Query();
+ $points = array(array(16, 16), array(16, 40), array(40, 40), array(40, 16), array(16, 16));
+ $geoFilter = new GeoPolygon('location', $points);
+
+ $query = new Query(new MatchAll());
+ $query->setPostFilter($geoFilter);
+
+ $this->assertEquals(2, $type->search($query)->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapePreIndexedTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapePreIndexedTest.php
new file mode 100644
index 00000000..96453527
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapePreIndexedTest.php
@@ -0,0 +1,102 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\AbstractGeoShape;
+use Elastica\Filter\GeoShapePreIndexed;
+use Elastica\Query\Filtered;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class GeoShapePreIndexedTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGeoProvided()
+ {
+ $index = $this->_createIndex();
+ $indexName = $index->getName();
+ $type = $index->getType('type');
+ $otherType = $index->getType('other_type');
+
+ // create mapping
+ $mapping = new \Elastica\Type\Mapping($type, array(
+ 'location' => array(
+ 'type' => 'geo_shape',
+ ),
+ ));
+ $type->setMapping($mapping);
+
+ // create other type mapping
+ $otherMapping = new \Elastica\Type\Mapping($type, array(
+ 'location' => array(
+ 'type' => 'geo_shape',
+ ),
+ ));
+ $otherType->setMapping($otherMapping);
+
+ // add type docs
+ $type->addDocument(new \Elastica\Document('1', array(
+ 'location' => array(
+ 'type' => 'envelope',
+ 'coordinates' => array(
+ array(0.0, 50.0),
+ array(50.0, 0.0),
+ ),
+ ),
+ )));
+
+ // add other type docs
+ $otherType->addDocument(new \Elastica\Document('2', array(
+ 'location' => array(
+ 'type' => 'envelope',
+ 'coordinates' => array(
+ array(25.0, 75.0),
+ array(75.0, 25.0),
+ ),
+ ),
+ )));
+
+ $index->optimize();
+ $index->refresh();
+
+ $gsp = new GeoShapePreIndexed(
+ 'location', '1', 'type', $indexName, 'location'
+ );
+ $gsp->setRelation(AbstractGeoShape::RELATION_INTERSECT);
+
+ $expected = array(
+ 'geo_shape' => array(
+ 'location' => array(
+ 'indexed_shape' => array(
+ 'id' => '1',
+ 'type' => 'type',
+ 'index' => $indexName,
+ 'path' => 'location',
+ ),
+ 'relation' => $gsp->getRelation(),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $gsp->toArray());
+
+ $query = new Filtered(new MatchAll(), $gsp);
+ $results = $index->getType('type')->search($query);
+
+ $this->assertEquals(1, $results->count());
+
+ $index->delete();
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetRelation()
+ {
+ $gsp = new GeoShapePreIndexed('location', '1', 'type', 'indexName', 'location');
+ $gsp->setRelation(AbstractGeoShape::RELATION_INTERSECT);
+ $this->assertEquals(AbstractGeoShape::RELATION_INTERSECT, $gsp->getRelation());
+ $this->assertInstanceOf('Elastica\Filter\GeoShapePreIndexed', $gsp->setRelation(AbstractGeoShape::RELATION_INTERSECT));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapeProvidedTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapeProvidedTest.php
new file mode 100644
index 00000000..d631e44e
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeoShapeProvidedTest.php
@@ -0,0 +1,103 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\AbstractGeoShape;
+use Elastica\Filter\GeoShapeProvided;
+use Elastica\Query\Filtered;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class GeoShapeProvidedTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testConstructEnvelope()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ // create mapping
+ $mapping = new Mapping($type, array(
+ 'location' => array(
+ 'type' => 'geo_shape',
+ ),
+ ));
+ $type->setMapping($mapping);
+
+ // add docs
+ $type->addDocument(new Document(1, array(
+ 'location' => array(
+ 'type' => 'envelope',
+ 'coordinates' => array(
+ array(-50.0, 50.0),
+ array(50.0, -50.0),
+ ),
+ ),
+ )));
+
+ $index->optimize();
+ $index->refresh();
+
+ $envelope = array(
+ array(25.0, 75.0),
+ array(75.0, 25.0),
+ );
+ $gsp = new GeoShapeProvided('location', $envelope);
+
+ $expected = array(
+ 'geo_shape' => array(
+ 'location' => array(
+ 'shape' => array(
+ 'type' => GeoShapeProvided::TYPE_ENVELOPE,
+ 'coordinates' => $envelope,
+ ),
+ 'relation' => AbstractGeoShape::RELATION_INTERSECT,
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $gsp->toArray());
+
+ $query = new Filtered(new MatchAll(), $gsp);
+ $results = $type->search($query);
+
+ $this->assertEquals(1, $results->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstructPolygon()
+ {
+ $polygon = array(array(102.0, 2.0), array(103.0, 2.0), array(103.0, 3.0), array(103.0, 3.0), array(102.0, 2.0));
+ $gsp = new GeoShapeProvided('location', $polygon, GeoShapeProvided::TYPE_POLYGON);
+
+ $expected = array(
+ 'geo_shape' => array(
+ 'location' => array(
+ 'shape' => array(
+ 'type' => GeoShapeProvided::TYPE_POLYGON,
+ 'coordinates' => $polygon,
+ ),
+ 'relation' => $gsp->getRelation(),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $gsp->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetRelation()
+ {
+ $gsp = new GeoShapeProvided('location', array(array(25.0, 75.0), array(75.0, 25.0)));
+ $gsp->setRelation(AbstractGeoShape::RELATION_INTERSECT);
+ $this->assertEquals(AbstractGeoShape::RELATION_INTERSECT, $gsp->getRelation());
+ $this->assertInstanceOf('Elastica\Filter\GeoShapeProvided', $gsp->setRelation(AbstractGeoShape::RELATION_INTERSECT));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeohashCellTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeohashCellTest.php
new file mode 100644
index 00000000..7ef0d04f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/GeohashCellTest.php
@@ -0,0 +1,68 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\GeohashCell;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class GeohashCellTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new GeohashCell('pin', array('lat' => 37.789018, 'lon' => -122.391506), '50m');
+ $expected = array(
+ 'geohash_cell' => array(
+ 'pin' => array(
+ 'lat' => 37.789018,
+ 'lon' => -122.391506,
+ ),
+ 'precision' => '50m',
+ 'neighbors' => false,
+ ),
+ );
+ $this->assertEquals($expected, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilter()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $mapping = new Mapping($type, array(
+ 'pin' => array(
+ 'type' => 'geo_point',
+ 'geohash' => true,
+ 'geohash_prefix' => true,
+ ),
+ ));
+ $type->setMapping($mapping);
+
+ $type->addDocument(new Document(1, array('pin' => '9q8yyzm0zpw8')));
+ $type->addDocument(new Document(2, array('pin' => '9mudgb0yued0')));
+ $index->refresh();
+
+ $filter = new GeohashCell('pin', array('lat' => 32.828326, 'lon' => -117.255854));
+ $query = new Query();
+ $query->setPostFilter($filter);
+ $results = $type->search($query);
+
+ $this->assertEquals(1, $results->count());
+
+ //test precision parameter
+ $filter = new GeohashCell('pin', '9', 1);
+ $query = new Query();
+ $query->setPostFilter($filter);
+ $results = $type->search($query);
+
+ $this->assertEquals(2, $results->count());
+
+ $index->delete();
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasChildTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasChildTest.php
new file mode 100644
index 00000000..00af1def
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasChildTest.php
@@ -0,0 +1,213 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\HasChild;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class HasChildTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $q = new MatchAll();
+
+ $type = 'test';
+
+ $filter = new HasChild($q, $type);
+
+ $expectedArray = array(
+ 'has_child' => array(
+ 'query' => $q->toArray(),
+ 'type' => $type,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetType()
+ {
+ $index = $this->prepareSearchData();
+
+ $filter = new HasChild(new MatchAll(), 'type_name');
+ $this->assertEquals('type_name', $filter->getParam('type'));
+
+ $filter->setType('new_type_name');
+ $this->assertEquals('new_type_name', $filter->getParam('type'));
+
+ $type = $index->getType('foo');
+ $filter = new HasChild(new MatchAll(), $type);
+ $this->assertEquals('foo', $filter->getParam('type'));
+
+ $type = $index->getType('bar');
+ $filter->setType($type);
+ $this->assertEquals('bar', $filter->getParam('type'));
+
+ $returnValue = $filter->setType('last');
+ $this->assertInstanceOf('Elastica\Filter\HasChild', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMinimumChildrenCount()
+ {
+ $query = new MatchAll();
+ $filter = new HasChild($query, 'test');
+
+ $filter->setMinimumChildrenCount(2);
+ $this->assertEquals(2, $filter->getParam('min_children'));
+
+ $returnValue = $filter->setMinimumChildrenCount(2);
+ $this->assertInstanceOf('Elastica\Filter\HasChild', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMaximumChildrenCount()
+ {
+ $query = new MatchAll();
+ $filter = new HasChild($query, 'test');
+
+ $filter->setMaximumChildrenCount(10);
+ $this->assertEquals(10, $filter->getParam('max_children'));
+
+ $returnValue = $filter->setMaximumChildrenCount(10);
+ $this->assertInstanceOf('Elastica\Filter\HasChild', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFilterInsideHasChild()
+ {
+ $f = new \Elastica\Filter\MatchAll();
+
+ $type = 'test';
+
+ $filter = new HasChild($f, $type);
+
+ $expectedArray = array(
+ 'has_child' => array(
+ 'filter' => $f->toArray(),
+ 'type' => $type,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilterInsideHasChildSearch()
+ {
+ $index = $this->prepareSearchData();
+
+ $f = new \Elastica\Filter\Term();
+ $f->setTerm('user', 'child1');
+ $filter = new HasChild($f, 'child');
+
+ $searchQuery = new \Elastica\Query();
+ $searchQuery->setPostFilter($filter);
+ $searchResults = $index->search($searchQuery);
+
+ $this->assertEquals(1, $searchResults->count());
+
+ $result = $searchResults->current()->getData();
+ $expected = array('id' => 'parent1', 'user' => 'parent1', 'email' => 'parent1@test.com');
+
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQueryInsideHasChildSearch()
+ {
+ $index = $this->prepareSearchData();
+
+ $f = new \Elastica\Query\Term();
+ $f->setTerm('user', 'child1');
+ $filter = new HasChild($f, 'child');
+
+ $searchQuery = new \Elastica\Query();
+ $searchQuery->setPostFilter($filter);
+ $searchResults = $index->search($searchQuery);
+
+ $this->assertEquals(1, $searchResults->count());
+
+ $result = $searchResults->current()->getData();
+ $expected = array('id' => 'parent1', 'user' => 'parent1', 'email' => 'parent1@test.com');
+
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testTypeInsideHasChildSearch()
+ {
+ $index = $this->prepareSearchData();
+
+ $f = new \Elastica\Query\Match();
+ $f->setField('alt.name', 'testname');
+ $filter = new HasChild($f, 'child');
+
+ $searchQuery = new \Elastica\Query();
+ $searchQuery->setPostFilter($filter);
+ $searchResults = $index->search($searchQuery);
+
+ $this->assertEquals(1, $searchResults->count());
+
+ $result = $searchResults->current()->getData();
+ $expected = array('id' => 'parent2', 'user' => 'parent2', 'email' => 'parent2@test.com');
+
+ $this->assertEquals($expected, $result);
+ }
+
+ private function prepareSearchData()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('has_child_test');
+ $index->create(array(), true);
+
+ $parentType = $index->getType('parent');
+
+ $childType = $index->getType('child');
+ $childMapping = new \Elastica\Type\Mapping($childType);
+ $childMapping->setParent('parent');
+ $childMapping->send();
+
+ $altType = $index->getType('alt');
+ $altDoc = new Document('alt1', array('name' => 'altname'));
+ $altType->addDocument($altDoc);
+
+ $parent1 = new Document('parent1', array('id' => 'parent1', 'user' => 'parent1', 'email' => 'parent1@test.com'));
+ $parentType->addDocument($parent1);
+ $parent2 = new Document('parent2', array('id' => 'parent2', 'user' => 'parent2', 'email' => 'parent2@test.com'));
+ $parentType->addDocument($parent2);
+
+ $child1 = new Document('child1', array('id' => 'child1', 'user' => 'child1', 'email' => 'child1@test.com'));
+ $child1->setParent('parent1');
+ $childType->addDocument($child1);
+ $child2 = new Document('child2', array('id' => 'child2', 'user' => 'child2', 'email' => 'child2@test.com'));
+ $child2->setParent('parent2');
+ $childType->addDocument($child2);
+ $child3 = new Document('child3', array('id' => 'child3', 'user' => 'child3', 'email' => 'child3@test.com', 'alt' => array(array('name' => 'testname'))));
+ $child3->setParent('parent2');
+ $childType->addDocument($child3);
+
+ $index->refresh();
+
+ return $index;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasParentTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasParentTest.php
new file mode 100644
index 00000000..50143dda
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/HasParentTest.php
@@ -0,0 +1,153 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\HasParent;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class HasParentTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $q = new MatchAll();
+
+ $type = 'test';
+
+ $filter = new HasParent($q, $type);
+
+ $expectedArray = array(
+ 'has_parent' => array(
+ 'query' => $q->toArray(),
+ 'type' => $type,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetType()
+ {
+ $index = $this->prepareSearchData();
+
+ $filter = new HasParent(new MatchAll(), 'type_name');
+ $this->assertEquals('type_name', $filter->getParam('type'));
+
+ $filter->setType('new_type_name');
+ $this->assertEquals('new_type_name', $filter->getParam('type'));
+
+ $type = $index->getType('foo');
+ $filter = new HasParent(new MatchAll(), $type);
+ $this->assertEquals('foo', $filter->getParam('type'));
+
+ $type = $index->getType('bar');
+ $filter->setType($type);
+ $this->assertEquals('bar', $filter->getParam('type'));
+
+ $returnValue = $filter->setType('last');
+ $this->assertInstanceOf('Elastica\Filter\HasParent', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFilterInsideHasParent()
+ {
+ $f = new \Elastica\Filter\MatchAll();
+
+ $type = 'test';
+
+ $filter = new HasParent($f, $type);
+
+ $expectedArray = array(
+ 'has_parent' => array(
+ 'filter' => $f->toArray(),
+ 'type' => $type,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilterInsideHasParentSearch()
+ {
+ $index = $this->prepareSearchData();
+
+ $f = new \Elastica\Filter\Term();
+ $f->setTerm('user', 'parent1');
+ $filter = new HasParent($f, 'parent');
+
+ $searchQuery = new \Elastica\Query();
+ $searchQuery->setPostFilter($filter);
+ $searchResults = $index->search($searchQuery);
+
+ $this->assertEquals(1, $searchResults->count());
+
+ $result = $searchResults->current()->getData();
+ $expected = array('id' => 'child1', 'user' => 'child1', 'email' => 'child1@test.com');
+
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQueryInsideHasParentSearch()
+ {
+ $index = $this->prepareSearchData();
+
+ $f = new \Elastica\Query\Term();
+ $f->setTerm('user', 'parent1');
+ $filter = new HasParent($f, 'parent');
+
+ $searchQuery = new \Elastica\Query();
+ $searchQuery->setPostFilter($filter);
+ $searchResults = $index->search($searchQuery);
+
+ $this->assertEquals(1, $searchResults->count());
+
+ $result = $searchResults->current()->getData();
+ $expected = array('id' => 'child1', 'user' => 'child1', 'email' => 'child1@test.com');
+
+ $this->assertEquals($expected, $result);
+ }
+
+ private function prepareSearchData()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('has_parent_test');
+ $index->create(array(), true);
+
+ $parentType = $index->getType('parent');
+
+ $childType = $index->getType('child');
+ $childMapping = new \Elastica\Type\Mapping($childType);
+ $childMapping->setParent('parent');
+ $childMapping->send();
+
+ $parent1 = new Document('parent1', array('id' => 'parent1', 'user' => 'parent1', 'email' => 'parent1@test.com'));
+ $parentType->addDocument($parent1);
+ $parent2 = new Document('parent2', array('id' => 'parent2', 'user' => 'parent2', 'email' => 'parent2@test.com'));
+ $parentType->addDocument($parent2);
+
+ $child1 = new Document('child1', array('id' => 'child1', 'user' => 'child1', 'email' => 'child1@test.com'));
+ $child1->setParent('parent1');
+ $childType->addDocument($child1);
+ $child2 = new Document('child2', array('id' => 'child2', 'user' => 'child2', 'email' => 'child2@test.com'));
+ $child2->setParent('parent2');
+ $childType->addDocument($child2);
+
+ $index->refresh();
+
+ return $index;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IdsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IdsTest.php
new file mode 100644
index 00000000..8395f39a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IdsTest.php
@@ -0,0 +1,244 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\Ids;
+use Elastica\Filter\Type;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+
+class IdsTest extends BaseTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+
+ // Add documents to first type
+ $docs = array();
+ for ($i = 1; $i < 100; $i++) {
+ $docs[] = new Document($i, array('name' => 'ruflin'));
+ }
+ $index->getType('helloworld1')->addDocuments($docs);
+
+ // Add documents to second type
+ $docs = array();
+ for ($i = 1; $i < 100; $i++) {
+ $docs[] = new Document($i, array('name' => 'ruflin'));
+ }
+ // This is a special id that will only be in the second type
+ $docs[] = new Document(101, array('name' => 'ruflin'));
+ $index->getType('helloworld2')->addDocuments($docs);
+
+ $index->optimize();
+ $index->refresh();
+
+ return $index;
+ }
+
+ protected function _getTypeForTest()
+ {
+ return $this->_getIndexForTest()->getType('helloworld1');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetIdsSearchSingle()
+ {
+ $filter = new Ids();
+ $filter->setIds('1');
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getTypeForTest()->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetIdsSearchArray()
+ {
+ $filter = new Ids();
+ $filter->setIds(array(1, 7, 13));
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getTypeForTest()->search($query);
+
+ $this->assertEquals(3, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddIdsSearchSingle()
+ {
+ $filter = new Ids();
+ $filter->addId('39');
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getTypeForTest()->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddIdsSearchSingleNotInType()
+ {
+ $filter = new Ids();
+ $filter->addId('39');
+
+ // Add an ID that is not in the index
+ $filter->addId(104);
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getTypeForTest()->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testComboIdsSearchArray()
+ {
+ $filter = new Ids();
+ $filter->setIds(array(1, 7, 13));
+ $filter->addId('39');
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getTypeForTest()->search($query);
+
+ $this->assertEquals(4, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchSingle()
+ {
+ $filter = new Ids();
+ $filter->setIds('1');
+ $filter->setType('helloworld1');
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getIndexForTest()->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchArray()
+ {
+ $filter = new Ids();
+ $filter->setIds(array('1', '2'));
+ $filter->setType('helloworld1');
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getIndexForTest()->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchSingleDocInOtherType()
+ {
+ $filter = new Ids();
+
+ // Doc 4 is in the second type...
+ $filter->setIds('101');
+ $filter->setType('helloworld1');
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getTypeForTest()->search($query);
+
+ // ...therefore 0 results should be returned
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchArrayDocInOtherType()
+ {
+ $filter = new Ids();
+
+ // Doc 4 is in the second type...
+ $filter->setIds(array('1', '101'));
+ $filter->setType('helloworld1');
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getTypeForTest()->search($query);
+
+ // ...therefore only 1 result should be returned
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeArraySearchArray()
+ {
+ $filter = new Ids();
+ $filter->setIds(array('1', '4'));
+ $filter->setType(array('helloworld1', 'helloworld2'));
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getIndexForTest()->search($query);
+
+ $this->assertEquals(4, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeArraySearchSingle()
+ {
+ $filter = new Ids();
+ $filter->setIds('4');
+ $filter->setType(array('helloworld1', 'helloworld2'));
+
+ $query = Query::create($filter);
+ $resultSet = $this->_getIndexForTest()->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFilterTypeAndTypeCollision()
+ {
+ // This test ensures that Elastica\Type and Elastica\Filter\Type
+ // do not collide when used together, which at one point
+ // happened because of a use statement in Elastica\Filter\Ids
+ // Test goal is to make sure a Fatal Error is not triggered
+ $filterType = new Type();
+ $filter = new Ids();
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddType()
+ {
+ $type = $this->_getClient()->getIndex('indexname')->getType('typename');
+
+ $filter = new Ids();
+
+ $filter->addType('foo');
+ $this->assertEquals(array('foo'), $filter->getParam('type'));
+
+ $filter->addType($type);
+ $this->assertEquals(array('foo', $type->getName()), $filter->getParam('type'));
+
+ $returnValue = $filter->addType('bar');
+ $this->assertInstanceOf('Elastica\Filter\Ids', $returnValue);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IndicesTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IndicesTest.php
new file mode 100644
index 00000000..bc78aa6b
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/IndicesTest.php
@@ -0,0 +1,125 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\BoolNot;
+use Elastica\Filter\Indices;
+use Elastica\Filter\Term;
+use Elastica\Index;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+
+class IndicesTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $expected = array(
+ 'indices' => array(
+ 'indices' => array('index1', 'index2'),
+ 'filter' => array(
+ 'term' => array('tag' => 'wow'),
+ ),
+ 'no_match_filter' => array(
+ 'term' => array('tag' => 'such filter'),
+ ),
+ ),
+ );
+ $filter = new Indices(new Term(array('tag' => 'wow')), array('index1', 'index2'));
+ $filter->setNoMatchFilter(new Term(array('tag' => 'such filter')));
+ $this->assertEquals($expected, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testIndicesFilter()
+ {
+ $docs = array(
+ new Document(1, array('color' => 'blue')),
+ new Document(2, array('color' => 'green')),
+ new Document(3, array('color' => 'blue')),
+ new Document(4, array('color' => 'yellow')),
+ );
+
+ $index1 = $this->_createIndex();
+ $index1->addAlias('indices_filter');
+ $index1->getType('test')->addDocuments($docs);
+ $index1->refresh();
+
+ $index2 = $this->_createIndex();
+ $index2->addAlias('indices_filter');
+ $index2->getType('test')->addDocuments($docs);
+ $index2->refresh();
+
+ $filter = new Indices(new BoolNot(new Term(array('color' => 'blue'))), array($index1->getName()));
+ $filter->setNoMatchFilter(new BoolNot(new Term(array('color' => 'yellow'))));
+ $query = new Query();
+ $query->setPostFilter($filter);
+
+ // search over the alias
+ $index = $this->_getClient()->getIndex('indices_filter');
+ $results = $index->search($query);
+
+ // ensure that the proper docs have been filtered out for each index
+ $this->assertEquals(5, $results->count());
+ foreach ($results->getResults() as $result) {
+ $data = $result->getData();
+ $color = $data['color'];
+ if ($result->getIndex() === $index1->getName()) {
+ $this->assertNotEquals('blue', $color);
+ } else {
+ $this->assertNotEquals('yellow', $color);
+ }
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetIndices()
+ {
+ $client = $this->_getClient();
+ $index1 = $client->getIndex('index1');
+ $index2 = $client->getIndex('index2');
+
+ $indices = array('one', 'two');
+ $filter = new Indices(new Term(array('color' => 'blue')), $indices);
+ $this->assertEquals($indices, $filter->getParam('indices'));
+
+ $indices[] = 'three';
+ $filter->setIndices($indices);
+ $this->assertEquals($indices, $filter->getParam('indices'));
+
+ $filter->setIndices(array($index1, $index2));
+ $expected = array($index1->getName(), $index2->getName());
+ $this->assertEquals($expected, $filter->getParam('indices'));
+
+ $returnValue = $filter->setIndices($indices);
+ $this->assertInstanceOf('Elastica\Filter\Indices', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddIndex()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('someindex');
+
+ $filter = new Indices(new Term(array('color' => 'blue')), array());
+
+ $filter->addIndex($index);
+ $expected = array($index->getName());
+ $this->assertEquals($expected, $filter->getParam('indices'));
+
+ $filter->addIndex('foo');
+ $expected = array($index->getName(), 'foo');
+ $this->assertEquals($expected, $filter->getParam('indices'));
+
+ $returnValue = $filter->addIndex('bar');
+ $this->assertInstanceOf('Elastica\Filter\Indices', $returnValue);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/LimitTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/LimitTest.php
new file mode 100644
index 00000000..0cdfee39
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/LimitTest.php
@@ -0,0 +1,34 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Limit;
+use Elastica\Test\Base as BaseTest;
+
+class LimitTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testSetType()
+ {
+ $filter = new Limit(10);
+ $this->assertEquals(10, $filter->getParam('value'));
+
+ $this->assertInstanceOf('Elastica\Filter\Limit', $filter->setLimit(20));
+ $this->assertEquals(20, $filter->getParam('value'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new Limit(15);
+
+ $expectedArray = array(
+ 'limit' => array('value' => 15),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MatchAllTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MatchAllTest.php
new file mode 100644
index 00000000..9bfd511f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MatchAllTest.php
@@ -0,0 +1,20 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class MatchAllTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new MatchAll();
+
+ $expectedArray = array('match_all' => new \stdClass());
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MissingTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MissingTest.php
new file mode 100644
index 00000000..f87df790
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MissingTest.php
@@ -0,0 +1,78 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Missing;
+use Elastica\Test\Base as BaseTest;
+
+class MissingTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new Missing('field_name');
+ $expectedArray = array('missing' => array('field' => 'field_name'));
+ $this->assertEquals($expectedArray, $filter->toArray());
+
+ $filter = new Missing('field_name');
+ $filter->setExistence(true);
+ $expectedArray = array('missing' => array('field' => 'field_name', 'existence' => true));
+ $this->assertEquals($expectedArray, $filter->toArray());
+
+ $filter = new Missing('field_name');
+ $filter->setNullValue(true);
+ $expectedArray = array('missing' => array('field' => 'field_name', 'null_value' => true));
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetField()
+ {
+ $filter = new Missing('field_name');
+
+ $this->assertEquals('field_name', $filter->getParam('field'));
+
+ $filter->setField('new_field_name');
+ $this->assertEquals('new_field_name', $filter->getParam('field'));
+
+ $returnValue = $filter->setField('very_new_field_name');
+ $this->assertInstanceOf('Elastica\Filter\Missing', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetExistence()
+ {
+ $filter = new Missing('field_name');
+
+ $filter->setExistence(true);
+ $this->assertTrue($filter->getParam('existence'));
+
+ $filter->setExistence(false);
+ $this->assertFalse($filter->getParam('existence'));
+
+ $returnValue = $filter->setExistence(true);
+ $this->assertInstanceOf('Elastica\Filter\Missing', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetNullValue()
+ {
+ $filter = new Missing('field_name');
+
+ $filter->setNullValue(true);
+ $this->assertTrue($filter->getParam('null_value'));
+
+ $filter->setNullValue(false);
+ $this->assertFalse($filter->getParam('null_value'));
+
+ $returnValue = $filter->setNullValue(true);
+ $this->assertInstanceOf('Elastica\Filter\Missing', $returnValue);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MultiTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MultiTest.php
new file mode 100644
index 00000000..cc8a56e8
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/MultiTest.php
@@ -0,0 +1,109 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\AbstractMulti;
+use Elastica\Filter\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class AbstractMultiTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $stub = $this->getStub();
+
+ $this->assertEmpty($stub->getFilters());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddFilter()
+ {
+ $stub = $this->getStub();
+
+ $filter = new MatchAll();
+ $stub->addFilter($filter);
+
+ $expected = array(
+ $filter->toArray(),
+ );
+
+ $this->assertEquals($expected, $stub->getFilters());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetFilters()
+ {
+ $stub = $this->getStub();
+
+ $filter = new MatchAll();
+ $stub->setFilters(array($filter));
+
+ $expected = array(
+ $filter->toArray(),
+ );
+
+ $this->assertEquals($expected, $stub->getFilters());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $stub = $this->getStub();
+
+ $filter = new MatchAll();
+ $stub->addFilter($filter);
+
+ $expected = array(
+ $stub->getBaseName() => array(
+ $filter->toArray(),
+ ),
+ );
+
+ $this->assertEquals($expected, $stub->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArrayWithParam()
+ {
+ $stub = $this->getStub();
+
+ $stub->setCached(true);
+
+ $filter = new MatchAll();
+ $stub->addFilter($filter);
+
+ $expected = array(
+ $stub->getBaseName() => array(
+ '_cache' => true,
+ 'filters' => array(
+ $filter->toArray(),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $stub->toArray());
+ }
+
+ private function getStub()
+ {
+ return $this->getMockForAbstractClass('Elastica\Test\Filter\AbstractMultiDebug');
+ }
+}
+
+class AbstractMultiDebug extends AbstractMulti
+{
+ public function getBaseName()
+ {
+ return parent::_getBaseName();
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedFilterWithSetFilterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedFilterWithSetFilterTest.php
new file mode 100644
index 00000000..96a49a77
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedFilterWithSetFilterTest.php
@@ -0,0 +1,110 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\Nested;
+use Elastica\Filter\Terms;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class NestedFilterWithSetFilterTest extends BaseTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('user');
+
+ $type->setMapping(new Mapping(null, array(
+ 'firstname' => array('type' => 'string', 'store' => 'yes'),
+ // default is store => no expected
+ 'lastname' => array('type' => 'string'),
+ 'hobbies' => array(
+ 'type' => 'nested',
+ 'include_in_parent' => true,
+ 'properties' => array('hobby' => array('type' => 'string')),
+ ),
+ )));
+
+ $type->addDocuments(array(
+ new Document(1, array(
+ 'firstname' => 'Nicolas',
+ 'lastname' => 'Ruflin',
+ 'hobbies' => array(
+ array('hobby' => 'opensource'),
+ ),
+ )),
+ new Document(2, array(
+ 'firstname' => 'Nicolas',
+ 'lastname' => 'Ippolito',
+ 'hobbies' => array(
+ array('hobby' => 'opensource'),
+ array('hobby' => 'guitar'),
+ ),
+ )),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new Nested();
+ $this->assertEquals(array('nested' => array()), $filter->toArray());
+ $query = new Terms();
+ $query->setTerms('hobby', array('guitar'));
+ $filter->setPath('hobbies');
+ $filter->setFilter($query);
+
+ $expectedArray = array(
+ 'nested' => array(
+ 'path' => 'hobbies',
+ 'filter' => array('terms' => array(
+ 'hobby' => array('guitar'),
+ )),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testShouldReturnTheRightNumberOfResult()
+ {
+ $filter = new Nested();
+ $this->assertEquals(array('nested' => array()), $filter->toArray());
+ $query = new Terms();
+ $query->setTerms('hobby', array('guitar'));
+ $filter->setPath('hobbies');
+ $filter->setFilter($query);
+
+ $client = $this->_getClient();
+ $search = new Search($client);
+ $index = $this->_getIndexForTest();
+ $search->addIndex($index);
+ $resultSet = $search->search($filter);
+
+ $this->assertEquals(1, $resultSet->getTotalHits());
+
+ $filter = new Nested();
+ $this->assertEquals(array('nested' => array()), $filter->toArray());
+ $query = new Terms();
+ $query->setTerms('hobby', array('opensource'));
+ $filter->setPath('hobbies');
+ $filter->setFilter($query);
+
+ $client = $this->_getClient();
+ $search = new Search($client);
+ $index = $this->_getIndexForTest();
+ $search->addIndex($index);
+ $resultSet = $search->search($filter);
+ $this->assertEquals(2, $resultSet->getTotalHits());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedTest.php
new file mode 100644
index 00000000..8eb42d37
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NestedTest.php
@@ -0,0 +1,127 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\Nested;
+use Elastica\Query\Terms;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class NestedTest extends BaseTest
+{
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex('elastica_test_filter_nested');
+ $type = $index->getType('user');
+ $mapping = new Mapping();
+ $mapping->setProperties(
+ array(
+ 'firstname' => array('type' => 'string', 'store' => 'yes'),
+ // default is store => no expected
+ 'lastname' => array('type' => 'string'),
+ 'hobbies' => array(
+ 'type' => 'nested',
+ 'include_in_parent' => true,
+ 'properties' => array('hobby' => array('type' => 'string')),
+ ),
+ )
+ );
+ $type->setMapping($mapping);
+
+ $response = $type->addDocuments(array(
+ new Document(1,
+ array(
+ 'firstname' => 'Nicolas',
+ 'lastname' => 'Ruflin',
+ 'hobbies' => array(
+ array('hobby' => 'opensource'),
+ ),
+ )
+ ),
+ new Document(2,
+ array(
+ 'firstname' => 'Nicolas',
+ 'lastname' => 'Ippolito',
+ 'hobbies' => array(
+ array('hobby' => 'opensource'),
+ array('hobby' => 'guitar'),
+ ),
+ )
+ ),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new Nested();
+ $this->assertEquals(array('nested' => array()), $filter->toArray());
+ $query = new Terms();
+ $query->setTerms('hobby', array('guitar'));
+ $filter->setPath('hobbies');
+ $filter->setQuery($query);
+
+ $expectedArray = array(
+ 'nested' => array(
+ 'path' => 'hobbies',
+ 'query' => array('terms' => array(
+ 'hobby' => array('guitar'),
+ )),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testShouldReturnTheRightNumberOfResult()
+ {
+ $filter = new Nested();
+ $this->assertEquals(array('nested' => array()), $filter->toArray());
+ $query = new Terms();
+ $query->setTerms('hobby', array('guitar'));
+ $filter->setPath('hobbies');
+ $filter->setQuery($query);
+
+ $search = new Search($this->_getClient());
+ $search->addIndex($this->_getIndexForTest());
+ $resultSet = $search->search($filter);
+ $this->assertEquals(1, $resultSet->getTotalHits());
+
+ $filter = new Nested();
+ $this->assertEquals(array('nested' => array()), $filter->toArray());
+ $query = new Terms();
+ $query->setTerms('hobby', array('opensource'));
+ $filter->setPath('hobbies');
+ $filter->setQuery($query);
+
+ $search = new Search($this->_getClient());
+ $search->addIndex($this->_getIndexForTest());
+ $resultSet = $search->search($filter);
+ $this->assertEquals(2, $resultSet->getTotalHits());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetJoin()
+ {
+ $filter = new Nested();
+
+ $this->assertTrue($filter->setJoin(true)->getParam('join'));
+
+ $this->assertFalse($filter->setJoin(false)->getParam('join'));
+
+ $returnValue = $filter->setJoin(true);
+ $this->assertInstanceOf('Elastica\Filter\Nested', $returnValue);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NumericRangeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NumericRangeTest.php
new file mode 100644
index 00000000..590b5137
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/NumericRangeTest.php
@@ -0,0 +1,37 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\NumericRange;
+use Elastica\Test\Base as BaseTest;
+
+class NumericRangeTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testAddField()
+ {
+ $rangeFilter = new NumericRange();
+ $returnValue = $rangeFilter->addField('fieldName', array('to' => 'value'));
+ $this->assertInstanceOf('Elastica\Filter\NumericRange', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new NumericRange();
+
+ $fromTo = array('from' => 'ra', 'to' => 'ru');
+ $filter->addField('name', $fromTo);
+
+ $expectedArray = array(
+ 'numeric_range' => array(
+ 'name' => $fromTo,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/PrefixTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/PrefixTest.php
new file mode 100644
index 00000000..aab37615
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/PrefixTest.php
@@ -0,0 +1,138 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\Prefix;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class PrefixTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $field = 'name';
+ $prefix = 'ruf';
+
+ $filter = new Prefix($field, $prefix);
+
+ $expectedArray = array(
+ 'prefix' => array(
+ $field => $prefix,
+ ),
+ );
+
+ $this->assertequals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDifferentPrefixes()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no', 'index' => 'not_analyzed'),
+ )
+ );
+ $type->setMapping($mapping);
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ new Document(5, array('name' => 'New Orleans')),
+ ));
+
+ $index->refresh();
+
+ $query = new Prefix('name', 'Ba');
+ $resultSet = $index->search($query);
+ $this->assertEquals(3, $resultSet->count());
+
+ // Lower case should not return a result
+ $query = new Prefix('name', 'ba');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+
+ $query = new Prefix('name', 'Baden');
+ $resultSet = $index->search($query);
+ $this->assertEquals(2, $resultSet->count());
+
+ $query = new Prefix('name', 'Baden B');
+ $resultSet = $index->search($query);
+ $this->assertEquals(1, $resultSet->count());
+
+ $query = new Prefix('name', 'Baden Bas');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDifferentPrefixesLowercase()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $indexParams = array(
+ 'analysis' => array(
+ 'analyzer' => array(
+ 'lw' => array(
+ 'type' => 'custom',
+ 'tokenizer' => 'keyword',
+ 'filter' => array('lowercase'),
+ ),
+ ),
+ ),
+ );
+
+ $index->create($indexParams, true);
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no', 'analyzer' => 'lw'),
+ )
+ );
+ $type->setMapping($mapping);
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ new Document(5, array('name' => 'New Orleans')),
+ ));
+
+ $index->refresh();
+
+ $query = new Prefix('name', 'ba');
+ $resultSet = $index->search($query);
+ $this->assertEquals(3, $resultSet->count());
+
+ // Upper case should not return a result
+ $query = new Prefix('name', 'Ba');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+
+ $query = new Prefix('name', 'baden');
+ $resultSet = $index->search($query);
+ $this->assertEquals(2, $resultSet->count());
+
+ $query = new Prefix('name', 'baden b');
+ $resultSet = $index->search($query);
+ $this->assertEquals(1, $resultSet->count());
+
+ $query = new Prefix('name', 'baden bas');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/QueryTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/QueryTest.php
new file mode 100644
index 00000000..23754510
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/QueryTest.php
@@ -0,0 +1,51 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Query;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+
+class QueryTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testSimple()
+ {
+ $query = new QueryString('foo bar');
+ $filter = new Query($query);
+
+ $expected = array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'foo bar',
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $filter->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testExtended()
+ {
+ $query = new QueryString('foo bar');
+ $filter = new Query($query);
+ $filter->setCached(true);
+
+ $expected = array(
+ 'fquery' => array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'foo bar',
+ ),
+ ),
+ '_cache' => true,
+ ),
+ );
+
+ $this->assertEquals($expected, $filter->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RangeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RangeTest.php
new file mode 100644
index 00000000..b7cad3ac
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RangeTest.php
@@ -0,0 +1,61 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Range;
+use Elastica\Test\Base as BaseTest;
+
+class RangeTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testAddField()
+ {
+ $rangeFilter = new Range();
+ $returnValue = $rangeFilter->addField('fieldName', array('to' => 'value'));
+ $this->assertInstanceOf('Elastica\Filter\Range', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $field = 'field_name';
+ $range = array('gte' => 10, 'lte' => 99);
+
+ $filter = new Range();
+ $filter->addField($field, $range);
+ $expectedArray = array('range' => array($field => $range));
+ $this->assertEquals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetExecution()
+ {
+ $field = 'field_name';
+ $range = array('gte' => 10, 'lte' => 99);
+ $filter = new Range('field_name', $range);
+
+ $filter->setExecution('fielddata');
+ $this->assertEquals('fielddata', $filter->getParam('execution'));
+
+ $returnValue = $filter->setExecution('index');
+ $this->assertInstanceOf('Elastica\Filter\Range', $returnValue);
+ }
+
+ /**
+ * Tests that parent fields are not overwritten by the toArray method.
+ *
+ * @group unit
+ */
+ public function testSetCachedNotOverwritten()
+ {
+ $filter = new Range('field_name', array());
+ $filter->setCached(true);
+ $array = $filter->toArray();
+ $this->assertTrue($array['range']['_cache']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RegexpTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RegexpTest.php
new file mode 100644
index 00000000..6e3a0395
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/RegexpTest.php
@@ -0,0 +1,162 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\Regexp;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class RegexpTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $field = 'name';
+ $regexp = 'ruf';
+
+ $filter = new Regexp($field, $regexp);
+
+ $expectedArray = array(
+ 'regexp' => array(
+ $field => $regexp,
+ ),
+ );
+
+ $this->assertequals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArrayWithOptions()
+ {
+ $field = 'name';
+ $regexp = 'ruf';
+ $options = array(
+ 'flags' => 'ALL',
+ );
+
+ $filter = new Regexp($field, $regexp, $options);
+
+ $expectedArray = array(
+ 'regexp' => array(
+ $field => array(
+ 'value' => $regexp,
+ 'flags' => 'ALL',
+ ),
+ ),
+ );
+
+ $this->assertequals($expectedArray, $filter->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDifferentRegexp()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no', 'index' => 'not_analyzed'),
+ )
+ );
+ $type->setMapping($mapping);
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ new Document(5, array('name' => 'New Orleans')),
+ ));
+
+ $index->refresh();
+
+ $query = new Regexp('name', 'Ba.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(3, $resultSet->count());
+
+ // Lower case should not return a result
+ $query = new Regexp('name', 'ba.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+
+ $query = new Regexp('name', 'Baden.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(2, $resultSet->count());
+
+ $query = new Regexp('name', 'Baden B.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(1, $resultSet->count());
+
+ $query = new Regexp('name', 'Baden Bas.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDifferentRegexpLowercase()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $indexParams = array(
+ 'analysis' => array(
+ 'analyzer' => array(
+ 'lw' => array(
+ 'type' => 'custom',
+ 'tokenizer' => 'keyword',
+ 'filter' => array('lowercase'),
+ ),
+ ),
+ ),
+ );
+
+ $index->create($indexParams, true);
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no', 'analyzer' => 'lw'),
+ )
+ );
+ $type->setMapping($mapping);
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ new Document(5, array('name' => 'New Orleans')),
+ ));
+
+ $index->refresh();
+
+ $query = new Regexp('name', 'ba.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(3, $resultSet->count());
+
+ // Upper case should not return a result
+ $query = new Regexp('name', 'Ba.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+
+ $query = new Regexp('name', 'baden.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(2, $resultSet->count());
+
+ $query = new Regexp('name', 'baden b.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(1, $resultSet->count());
+
+ $query = new Regexp('name', 'baden bas.*');
+ $resultSet = $index->search($query);
+ $this->assertEquals(0, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ScriptTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ScriptTest.php
new file mode 100644
index 00000000..fdec0381
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/ScriptTest.php
@@ -0,0 +1,57 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Script as ScriptFilter;
+use Elastica\Script;
+use Elastica\Test\Base as BaseTest;
+
+class ScriptTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $string = '_score * 2.0';
+
+ $filter = new ScriptFilter($string);
+
+ $array = $filter->toArray();
+ $this->assertInternalType('array', $array);
+
+ $expected = array(
+ 'script' => array(
+ 'script' => $string,
+ ),
+ );
+ $this->assertEquals($expected, $array);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScript()
+ {
+ $string = '_score * 2.0';
+ $params = array(
+ 'param1' => 'one',
+ 'param2' => 1,
+ );
+ $lang = 'mvel';
+ $script = new Script($string, $params, $lang);
+
+ $filter = new ScriptFilter();
+ $filter->setScript($script);
+
+ $array = $filter->toArray();
+
+ $expected = array(
+ 'script' => array(
+ 'script' => $string,
+ 'params' => $params,
+ 'lang' => $lang,
+ ),
+ );
+ $this->assertEquals($expected, $array);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermTest.php
new file mode 100644
index 00000000..9c8f5a2a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermTest.php
@@ -0,0 +1,24 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Term;
+use Elastica\Test\Base as BaseTest;
+
+class TermTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new Term();
+ $key = 'name';
+ $value = 'ruflin';
+ $query->setTerm($key, $value);
+
+ $data = $query->toArray();
+
+ $this->assertInternalType('array', $data['term']);
+ $this->assertEquals(array($key => $value), $data['term']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermsTest.php
new file mode 100644
index 00000000..bb37ba96
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TermsTest.php
@@ -0,0 +1,129 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Document;
+use Elastica\Filter\Terms;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+
+class TermsTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testLookup()
+ {
+ $index = $this->_createIndex();
+ $type1 = $index->getType('musicians');
+ $type2 = $index->getType('bands');
+
+ //index some test data
+ $type1->addDocuments(array(
+ new Document(1, array('name' => 'robert', 'lastName' => 'plant')),
+ new Document(2, array('name' => 'jimmy', 'lastName' => 'page')),
+ new Document(3, array('name' => 'john paul', 'lastName' => 'jones')),
+ new Document(4, array('name' => 'john', 'lastName' => 'bonham')),
+ new Document(5, array('name' => 'jimi', 'lastName' => 'hendrix')),
+ ));
+
+ $type2->addDocument(new Document('led zeppelin', array('members' => array('plant', 'page', 'jones', 'bonham'))));
+ $index->refresh();
+
+ //use the terms lookup feature to query for some data
+ $termsFilter = new Terms();
+ $termsFilter->setLookup('lastName', $type2, 'led zeppelin', 'members', null);
+ $query = new Query();
+ $query->setPostFilter($termsFilter);
+ $results = $index->search($query);
+ $this->assertEquals($results->count(), 4, 'Terms lookup with null index');
+
+ $termsFilter->setLookup('lastName', $type2, 'led zeppelin', 'members', $index);
+ $query->setPostFilter($termsFilter);
+ $results = $index->search($query);
+ $this->assertEquals($results->count(), 4, 'Terms lookup with index as object');
+
+ //Query with index given as string
+ $termsFilter->setLookup('lastName', $type2, 'led zeppelin', 'members', $index->getName());
+ $query->setPostFilter($termsFilter);
+ $results = $index->search($query);
+ $this->assertEquals($results->count(), 4, 'Terms lookup with index as string');
+
+ //Query with array of options
+ $termsFilter->setLookup('lastName', $type2, 'led zeppelin', 'members', array('index' => $index, 'cache' => false));
+ $query->setPostFilter($termsFilter);
+ $results = $index->search($query);
+ $this->assertEquals($results->count(), 4, 'Terms lookup with options array');
+
+ $index->delete();
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetExecution()
+ {
+ $filter = new Terms('color', array('blue', 'green'));
+
+ $filter->setExecution('bool');
+ $this->assertEquals('bool', $filter->getParam('execution'));
+
+ $returnValue = $filter->setExecution('bool');
+ $this->assertInstanceOf('Elastica\Filter\Terms', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetTerms()
+ {
+ $field = 'color';
+ $terms = array('blue', 'green');
+
+ $filter = new Terms();
+ $filter->setTerms($field, $terms);
+ $expected = array('terms' => array($field => $terms));
+ $this->assertEquals($expected, $filter->toArray());
+
+ $returnValue = $filter->setTerms($field, $terms);
+ $this->assertInstanceOf('Elastica\Filter\Terms', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddTerm()
+ {
+ $filter = new Terms('color', array('blue'));
+
+ $filter->addTerm('green');
+ $expected = array('terms' => array('color' => array('blue', 'green')));
+ $this->assertEquals($expected, $filter->toArray());
+
+ $returnValue = $filter->addTerm('cyan');
+ $this->assertInstanceOf('Elastica\Filter\Terms', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $filter = new Terms('color', array());
+ $expected = array('terms' => array('color' => array()));
+ $this->assertEquals($expected, $filter->toArray());
+
+ $filter = new Terms('color', array('cyan'));
+ $expected = array('terms' => array('color' => array('cyan')));
+ $this->assertEquals($expected, $filter->toArray());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testToArrayInvalidException()
+ {
+ $filter = new Terms();
+ $filter->toArray();
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TypeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TypeTest.php
new file mode 100644
index 00000000..8da19273
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Filter/TypeTest.php
@@ -0,0 +1,32 @@
+<?php
+namespace Elastica\Test\Filter;
+
+use Elastica\Filter\Type;
+use Elastica\Test\Base as BaseTest;
+
+class TypeTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testSetType()
+ {
+ $typeFilter = new Type();
+ $returnValue = $typeFilter->setType('type_name');
+ $this->assertInstanceOf('Elastica\Filter\Type', $returnValue);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $typeFilter = new Type('type_name');
+
+ $expectedArray = array(
+ 'type' => array('value' => 'type_name'),
+ );
+
+ $this->assertEquals($expectedArray, $typeFilter->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/SettingsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/SettingsTest.php
new file mode 100644
index 00000000..1562c7a0
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/SettingsTest.php
@@ -0,0 +1,338 @@
+<?php
+namespace Elastica\Test\Index;
+
+use Elastica\Document;
+use Elastica\Exception\ResponseException;
+use Elastica\Index;
+use Elastica\Index\Settings as IndexSettings;
+use Elastica\Test\Base as BaseTest;
+
+class SettingsTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGet()
+ {
+ $indexName = 'elasticatest';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $index->refresh();
+ $settings = $index->getSettings();
+
+ $this->assertInternalType('array', $settings->get());
+ $this->assertNotNull($settings->get('number_of_replicas'));
+ $this->assertNotNull($settings->get('number_of_shards'));
+ $this->assertNull($settings->get('kjqwerjlqwer'));
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetWithAlias()
+ {
+ $indexName = 'elasticatest';
+ $aliasName = 'elasticatest_alias';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $index->refresh();
+
+ $index->addAlias($aliasName);
+ $index = $client->getIndex($aliasName);
+ $settings = $index->getSettings();
+
+ $this->assertInternalType('array', $settings->get());
+ $this->assertNotNull($settings->get('number_of_replicas'));
+ $this->assertNotNull($settings->get('number_of_shards'));
+ $this->assertNull($settings->get('kjqwerjlqwer'));
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetNumberOfReplicas()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $settings = $index->getSettings();
+
+ $settings->setNumberOfReplicas(2);
+ $index->refresh();
+ $this->assertEquals(2, $settings->get('number_of_replicas'));
+
+ $settings->setNumberOfReplicas(3);
+ $index->refresh();
+ $this->assertEquals(3, $settings->get('number_of_replicas'));
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetRefreshInterval()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+
+ $settings = $index->getSettings();
+
+ $settings->setRefreshInterval('2s');
+ $index->refresh();
+ $this->assertEquals('2s', $settings->get('refresh_interval'));
+
+ $settings->setRefreshInterval('5s');
+ $index->refresh();
+ $this->assertEquals('5s', $settings->get('refresh_interval'));
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetRefreshInterval()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+
+ $settings = $index->getSettings();
+
+ $this->assertEquals(IndexSettings::DEFAULT_REFRESH_INTERVAL, $settings->getRefreshInterval());
+
+ $interval = '2s';
+ $settings->setRefreshInterval($interval);
+ $index->refresh();
+ $this->assertEquals($interval, $settings->getRefreshInterval());
+ $this->assertEquals($interval, $settings->get('refresh_interval'));
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetMergePolicy()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ //wait for the shards to be allocated
+ $this->_waitForAllocation($index);
+
+ $settings = $index->getSettings();
+
+ $settings->setMergePolicy('expunge_deletes_allowed', 15);
+ $this->assertEquals(15, $settings->getMergePolicy('expunge_deletes_allowed'));
+
+ $settings->setMergePolicy('expunge_deletes_allowed', 10);
+ $this->assertEquals(10, $settings->getMergePolicy('expunge_deletes_allowed'));
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetMergeFactor()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+
+ //wait for the shards to be allocated
+ $this->_waitForAllocation($index);
+
+ $settings = $index->getSettings();
+
+ $response = $settings->setMergePolicy('merge_factor', 15);
+ $this->assertEquals(15, $settings->getMergePolicy('merge_factor'));
+ $this->assertInstanceOf('Elastica\Response', $response);
+ $this->assertTrue($response->isOk());
+
+ $settings->setMergePolicy('merge_factor', 10);
+ $this->assertEquals(10, $settings->getMergePolicy('merge_factor'));
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetMergePolicyType()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+
+ //wait for the shards to be allocated
+ $this->_waitForAllocation($index);
+
+ $settings = $index->getSettings();
+
+ $settings->setMergePolicyType('log_byte_size');
+ $this->assertEquals('log_byte_size', $settings->getMergePolicyType());
+
+ $response = $settings->setMergePolicy('merge_factor', 15);
+ $this->assertEquals(15, $settings->getMergePolicy('merge_factor'));
+ $this->assertInstanceOf('Elastica\Response', $response);
+ $this->assertTrue($response->isOk());
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetReadOnly()
+ {
+ $index = $this->_createIndex();
+ //wait for the shards to be allocated
+ $this->_waitForAllocation($index);
+ $index->getSettings()->setReadOnly(false);
+
+ // Add document to normal index
+ $doc1 = new Document(null, array('hello' => 'world'));
+ $doc2 = new Document(null, array('hello' => 'world'));
+ $doc3 = new Document(null, array('hello' => 'world'));
+
+ $type = $index->getType('test');
+ $type->addDocument($doc1);
+ $this->assertFalse($index->getSettings()->getReadOnly());
+
+ // Try to add doc to read only index
+ $index->getSettings()->setReadOnly(true);
+ $this->assertTrue($index->getSettings()->getReadOnly());
+
+ try {
+ $type->addDocument($doc2);
+ $this->fail('Should throw exception because of read only');
+ } catch (ResponseException $e) {
+ $message = $e->getMessage();
+ $this->assertContains('ClusterBlockException', $message);
+ $this->assertContains('index write', $message);
+ }
+
+ // Remove read only, add document
+ $response = $index->getSettings()->setReadOnly(false);
+ $this->assertTrue($response->isOk());
+
+ $type->addDocument($doc3);
+ $index->refresh();
+
+ $this->assertEquals(2, $type->count());
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetSetBlocksRead()
+ {
+ $index = $this->_createIndex();
+ $index->refresh();
+ $settings = $index->getSettings();
+
+ $this->assertFalse($settings->getBlocksRead());
+
+ $settings->setBlocksRead(true);
+ $this->assertTrue($settings->getBlocksRead());
+
+ $settings->setBlocksRead(false);
+ $this->assertFalse($settings->getBlocksRead());
+
+ $settings->setBlocksRead();
+ $this->assertTrue($settings->getBlocksRead());
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetSetBlocksWrite()
+ {
+ $index = $this->_createIndex();
+ $index->refresh();
+ $settings = $index->getSettings();
+
+ $this->assertFalse($settings->getBlocksWrite());
+
+ $settings->setBlocksWrite(true);
+ $this->assertTrue($settings->getBlocksWrite());
+
+ $settings->setBlocksWrite(false);
+ $this->assertFalse($settings->getBlocksWrite());
+
+ $settings->setBlocksWrite();
+ $this->assertTrue($settings->getBlocksWrite());
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetSetBlocksMetadata()
+ {
+ $index = $this->_createIndex();
+ $index->refresh();
+ $settings = $index->getSettings();
+
+ $this->assertFalse($settings->getBlocksMetadata());
+
+ $settings->setBlocksMetadata(true);
+ $this->assertTrue($settings->getBlocksMetadata());
+
+ $settings->setBlocksMetadata(false);
+ $this->assertFalse($settings->getBlocksMetadata());
+
+ $settings->setBlocksMetadata();
+ $this->assertTrue($settings->getBlocksMetadata());
+
+ $settings->setBlocksMetadata(false); // Cannot delete index otherwise
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testNotFoundIndex()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('not_found_index');
+ //wait for the shards to be allocated
+
+ try {
+ $settings = $index->getSettings()->get();
+ $this->fail('Should throw exception because of index not found');
+ } catch (ResponseException $e) {
+ $message = $e->getMessage();
+ $this->assertContains('IndexMissingException', $message);
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatsTest.php
new file mode 100644
index 00000000..d0bb7838
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatsTest.php
@@ -0,0 +1,24 @@
+<?php
+namespace Elastica\Test\Index;
+
+use Elastica\Test\Base as BaseTest;
+
+class StatsTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGetSettings()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $stats = $index->getStats();
+ $this->assertInstanceOf('Elastica\Index\Stats', $stats);
+
+ $this->assertTrue($stats->getResponse()->isOk());
+ $this->assertEquals(0, $stats->get('_all', 'indices', 'test', 'primaries', 'docs', 'count'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatusTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatusTest.php
new file mode 100644
index 00000000..24f22ffd
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Index/StatusTest.php
@@ -0,0 +1,74 @@
+<?php
+namespace Elastica\Test\Index;
+
+use Elastica\Index\Status as IndexStatus;
+use Elastica\Test\Base as BaseTest;
+
+class StatusTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGetAliases()
+ {
+ $indexName = 'test';
+ $aliasName = 'test-alias';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+
+ $status = new IndexStatus($index);
+
+ $aliases = $status->getAliases();
+
+ $this->assertTrue(empty($aliases));
+ $this->assertInternalType('array', $aliases);
+
+ $index->addAlias($aliasName);
+ $status->refresh();
+
+ $aliases = $status->getAliases();
+
+ $this->assertTrue(in_array($aliasName, $aliases));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testHasAlias()
+ {
+ $indexName = 'test';
+ $aliasName = 'test-alias';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+
+ $status = new IndexStatus($index);
+
+ $this->assertFalse($status->hasAlias($aliasName));
+
+ $index->addAlias($aliasName);
+ $status->refresh();
+
+ $this->assertTrue($status->hasAlias($aliasName));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetSettings()
+ {
+ $indexName = 'test';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $status = $index->getStatus();
+
+ $settings = $status->getSettings();
+ $this->assertInternalType('array', $settings);
+ $this->assertTrue(isset($settings['index']['number_of_shards']));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/IndexTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/IndexTest.php
new file mode 100644
index 00000000..25ac53c2
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/IndexTest.php
@@ -0,0 +1,901 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Exception\ResponseException;
+use Elastica\Index;
+use Elastica\Query\HasChild;
+use Elastica\Query\QueryString;
+use Elastica\Query\SimpleQueryString;
+use Elastica\Query\Term;
+use Elastica\Status;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Type\Mapping;
+
+class IndexTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testMapping()
+ {
+ $index = $this->_createIndex();
+ $doc = new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'hanswurst', 'test' => array('2', '3', '5')));
+
+ $type = $index->getType('test');
+
+ $mapping = array('id' => array('type' => 'integer', 'store' => true), 'email' => array('type' => 'string', 'store' => 'no'),
+ 'username' => array('type' => 'string', 'store' => 'no'), 'test' => array('type' => 'integer', 'store' => 'no'),);
+ $type->setMapping($mapping);
+
+ $type->addDocument($doc);
+ $index->optimize();
+
+ $storedMapping = $index->getMapping();
+
+ $this->assertEquals($storedMapping['test']['properties']['id']['type'], 'integer');
+ $this->assertEquals($storedMapping['test']['properties']['id']['store'], true);
+ $this->assertEquals($storedMapping['test']['properties']['email']['type'], 'string');
+ $this->assertEquals($storedMapping['test']['properties']['username']['type'], 'string');
+ $this->assertEquals($storedMapping['test']['properties']['test']['type'], 'integer');
+
+ $result = $type->search('hanswurst');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetMappingAlias()
+ {
+ $index = $this->_createIndex();
+ $indexName = $index->getName();
+
+ $aliasName = 'test-mapping-alias';
+ $index->addAlias($aliasName);
+
+ $type = new Type($index, 'test');
+ $mapping = new Mapping($type, array(
+ 'id' => array('type' => 'integer', 'store' => 'yes'),
+ ));
+ $type->setMapping($mapping);
+
+ $client = $index->getClient();
+
+ // Index mapping
+ $mapping1 = $client->getIndex($indexName)->getMapping();
+
+ // Alias mapping
+ $mapping2 = $client->getIndex($aliasName)->getMapping();
+
+ // Make sure, a mapping is set
+ $this->assertNotEmpty($mapping1);
+
+ // Alias and index mapping should be identical
+ $this->assertEquals($mapping1, $mapping2);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testParent()
+ {
+ $index = $this->_createIndex();
+
+ $typeBlog = new Type($index, 'blog');
+
+ $typeComment = new Type($index, 'comment');
+
+ $mapping = new Mapping();
+ $mapping->setParam('_parent', array('type' => 'blog'));
+ $typeComment->setMapping($mapping);
+
+ $entry1 = new Document(1);
+ $entry1->set('title', 'Hello world');
+ $typeBlog->addDocument($entry1);
+
+ $entry2 = new Document(2);
+ $entry2->set('title', 'Foo bar');
+ $typeBlog->addDocument($entry2);
+
+ $entry3 = new Document(3);
+ $entry3->set('title', 'Till dawn');
+ $typeBlog->addDocument($entry3);
+
+ $comment = new Document(1);
+ $comment->set('author', 'Max');
+ $comment->setParent(2); // Entry Foo bar
+ $typeComment->addDocument($comment);
+
+ $index->optimize();
+
+ $query = new HasChild('Max', 'comment');
+ $resultSet = $typeBlog->search($query);
+ $this->assertEquals(1, $resultSet->count());
+ $this->assertEquals(array('title' => 'Foo bar'), $resultSet->current()->getData());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddPdfFile()
+ {
+ $this->_checkAttachmentsPlugin();
+ $indexMapping = array('file' => array('type' => 'attachment', 'store' => 'no'), 'text' => array('type' => 'string', 'store' => 'no'));
+
+ $indexParams = array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0));
+
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+
+ $index->create($indexParams, true);
+ $type->setMapping($indexMapping);
+
+ $doc1 = new Document(1);
+ $doc1->addFile('file', BASE_PATH.'/data/test.pdf', 'application/pdf');
+ $doc1->set('text', 'basel world');
+ $type->addDocument($doc1);
+
+ $doc2 = new Document(2);
+ $doc2->set('text', 'running in basel');
+ $type->addDocument($doc2);
+
+ $index->optimize();
+
+ $resultSet = $type->search('xodoa');
+ $this->assertEquals(1, $resultSet->count());
+
+ $resultSet = $type->search('basel');
+ $this->assertEquals(2, $resultSet->count());
+
+ // Author is ruflin
+ $resultSet = $type->search('ruflin');
+ $this->assertEquals(1, $resultSet->count());
+
+ // String does not exist in file
+ $resultSet = $type->search('guschti');
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddPdfFileContent()
+ {
+ $this->_checkAttachmentsPlugin();
+ $indexMapping = array('file' => array('type' => 'attachment', 'store' => 'no'), 'text' => array('type' => 'string', 'store' => 'no'));
+
+ $indexParams = array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0));
+
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+
+ $index->create($indexParams, true);
+ $type->setMapping($indexMapping);
+
+ $doc1 = new Document(1);
+ $doc1->addFileContent('file', file_get_contents(BASE_PATH.'/data/test.pdf'));
+ $doc1->set('text', 'basel world');
+ $type->addDocument($doc1);
+
+ $doc2 = new Document(2);
+ $doc2->set('text', 'running in basel');
+ $type->addDocument($doc2);
+
+ $index->optimize();
+
+ $resultSet = $type->search('xodoa');
+ $this->assertEquals(1, $resultSet->count());
+
+ $resultSet = $type->search('basel');
+ $this->assertEquals(2, $resultSet->count());
+
+ // Author is ruflin
+ $resultSet = $type->search('ruflin');
+ $this->assertEquals(1, $resultSet->count());
+
+ // String does not exist in file
+ $resultSet = $type->search('guschti');
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddWordxFile()
+ {
+ $this->_checkAttachmentsPlugin();
+ $indexMapping = array('file' => array('type' => 'attachment'), 'text' => array('type' => 'string', 'store' => 'no'));
+
+ $indexParams = array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0));
+
+ $index = $this->_createIndex();
+ $type = new Type($index, 'content');
+
+ $index->create($indexParams, true);
+ $type->setMapping($indexMapping);
+
+ $doc1 = new Document(1);
+ $doc1->addFile('file', BASE_PATH.'/data/test.docx');
+ $doc1->set('text', 'basel world');
+ $type->addDocument($doc1);
+
+ $index->optimize();
+ $index->refresh();
+
+ $doc2 = new Document(2);
+ $doc2->set('text', 'running in basel');
+ $type->addDocument($doc2);
+
+ $index->optimize();
+ $index->refresh();
+
+ $resultSet = $type->search('basel');
+ $this->assertEquals(2, $resultSet->count());
+
+ $resultSet = $type->search('ruflin');
+ $this->assertEquals(0, $resultSet->count());
+
+ $resultSet = $type->search('xodoa');
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testExcludeFileSource()
+ {
+ $this->_checkAttachmentsPlugin();
+ $indexMapping = array('file' => array('type' => 'attachment', 'store' => 'yes'), 'text' => array('type' => 'string', 'store' => 'yes'),
+ 'title' => array('type' => 'string', 'store' => 'yes'),);
+
+ $indexParams = array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0));
+
+ $index = $this->_createIndex();
+ $type = new Type($index, 'content');
+
+ $mapping = Mapping::create($indexMapping);
+ $mapping->setSource(array('excludes' => array('file')));
+
+ $mapping->setType($type);
+
+ $index->create($indexParams, true);
+ $type->setMapping($mapping);
+
+ $docId = 1;
+ $text = 'Basel World';
+ $title = 'No Title';
+
+ $doc1 = new Document($docId);
+ $doc1->addFile('file', BASE_PATH.'/data/test.docx');
+ $doc1->set('text', $text);
+ $doc1->set('title', $title);
+ $type->addDocument($doc1);
+
+ // Optimization necessary, as otherwise source still in realtime get
+ $index->optimize();
+
+ $data = $type->getDocument($docId)->getData();
+ $this->assertEquals($data['title'], $title);
+ $this->assertEquals($data['text'], $text);
+ $this->assertFalse(isset($data['file']));
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\ResponseException
+ */
+ public function testAddRemoveAlias()
+ {
+ $client = $this->_getClient();
+
+ $indexName1 = 'test1';
+ $aliasName = 'test-alias';
+ $typeName = 'test';
+
+ $index = $client->getIndex($indexName1);
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $doc = new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'ruflin'));
+
+ $type = $index->getType($typeName);
+ $type->addDocument($doc);
+ $index->refresh();
+
+ $resultSet = $type->search('ruflin');
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $data = $index->addAlias($aliasName, true)->getData();
+ $this->assertTrue($data['acknowledged']);
+
+ $index2 = $client->getIndex($aliasName);
+ $type2 = $index2->getType($typeName);
+
+ $resultSet2 = $type2->search('ruflin');
+ $this->assertEquals(1, $resultSet2->count());
+
+ $response = $index->removeAlias($aliasName)->getData();
+ $this->assertTrue($response['acknowledged']);
+
+ $client->getIndex($aliasName)->getType($typeName)->search('ruflin');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCount()
+ {
+ $index = $this->_createIndex();
+
+ // Add document to normal index
+ $doc1 = new Document(null, array('name' => 'ruflin'));
+ $doc2 = new Document(null, array('name' => 'nicolas'));
+
+ $type = $index->getType('test');
+ $type->addDocument($doc1);
+ $type->addDocument($doc2);
+
+ $index->refresh();
+
+ $this->assertEquals(2, $index->count());
+
+ $query = new Term();
+ $key = 'name';
+ $value = 'nicolas';
+ $query->setTerm($key, $value);
+
+ $this->assertEquals(1, $index->count($query));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteByQueryWithQueryString()
+ {
+ $index = $this->_createIndex();
+ $type1 = new Type($index, 'test1');
+ $type1->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type1->addDocument(new Document(2, array('name' => 'ruflin')));
+ $type2 = new Type($index, 'test2');
+ $type2->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type2->addDocument(new Document(2, array('name' => 'ruflin')));
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(4, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(2, $response->count());
+
+ // Delete first document
+ $response = $index->deleteByQuery('nicolas');
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ // Makes sure, document is deleted
+ $response = $index->search('ruflin*');
+ $this->assertEquals(2, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(0, $response->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteByQueryWithQuery()
+ {
+ $index = $this->_createIndex();
+ $type1 = new Type($index, 'test1');
+ $type1->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type1->addDocument(new Document(2, array('name' => 'ruflin')));
+ $type2 = new Type($index, 'test2');
+ $type2->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type2->addDocument(new Document(2, array('name' => 'ruflin')));
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(4, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(2, $response->count());
+
+ // Delete first document
+ $response = $index->deleteByQuery(new SimpleQueryString('nicolas'));
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ // Makes sure, document is deleted
+ $response = $index->search('ruflin*');
+ $this->assertEquals(2, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(0, $response->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteByQueryWithQueryAndOptions()
+ {
+ $index = $this->_createIndex(null, true, 2);
+ $type1 = new Type($index, 'test1');
+ $type1->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type1->addDocument(new Document(2, array('name' => 'ruflin')));
+ $type2 = new Type($index, 'test2');
+ $type2->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type2->addDocument(new Document(2, array('name' => 'ruflin')));
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(4, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(2, $response->count());
+
+ // Route to the wrong document id; should not delete
+ $response = $index->deleteByQuery(new SimpleQueryString('nicolas'), array('routing' => '2'));
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(4, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(2, $response->count());
+
+ // Delete first document
+ $response = $index->deleteByQuery(new SimpleQueryString('nicolas'), array('routing' => '1'));
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ // Makes sure, document is deleted
+ $response = $index->search('ruflin*');
+ $this->assertEquals(2, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(0, $response->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteIndexDeleteAlias()
+ {
+ $indexName = 'test';
+ $aliasName = 'test-aliase';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+
+ $index->create(array(), true);
+ $index->addAlias($aliasName);
+
+ $status = new Status($client);
+ $this->assertTrue($status->indexExists($indexName));
+ $this->assertTrue($status->aliasExists($aliasName));
+
+ // Deleting index should also remove alias
+ $index->delete();
+
+ $status->refresh();
+ $this->assertFalse($status->indexExists($indexName));
+ $this->assertFalse($status->aliasExists($aliasName));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddAliasTwoIndices()
+ {
+ $indexName1 = 'test1';
+ $indexName2 = 'test2';
+ $aliasName = 'test-alias';
+
+ $client = $this->_getClient();
+ $index1 = $client->getIndex($indexName1);
+ $index2 = $client->getIndex($indexName2);
+
+ $index1->create(array(), true);
+ $this->_waitForAllocation($index1);
+ $index1->addAlias($aliasName);
+ $index2->create(array(), true);
+ $this->_waitForAllocation($index2);
+
+ $index1->refresh();
+ $index2->refresh();
+ $index1->optimize();
+ $index2->optimize();
+
+ $status = new Status($client);
+
+ $this->assertTrue($status->indexExists($indexName1));
+ $this->assertTrue($status->indexExists($indexName2));
+
+ $this->assertTrue($status->aliasExists($aliasName));
+ $this->assertTrue($index1->getStatus()->hasAlias($aliasName));
+ $this->assertFalse($index2->getStatus()->hasAlias($aliasName));
+
+ $index2->addAlias($aliasName);
+ $this->assertTrue($index1->getStatus()->hasAlias($aliasName));
+ $this->assertTrue($index2->getStatus()->hasAlias($aliasName));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testReplaceAlias()
+ {
+ $indexName1 = 'test1';
+ $indexName2 = 'test2';
+ $aliasName = 'test-alias';
+
+ $client = $this->_getClient();
+ $index1 = $client->getIndex($indexName1);
+ $index2 = $client->getIndex($indexName2);
+
+ $index1->create(array(), true);
+ $index1->addAlias($aliasName);
+ $index2->create(array(), true);
+
+ $index1->refresh();
+ $index2->refresh();
+
+ $status = new Status($client);
+
+ $this->assertTrue($status->indexExists($indexName1));
+ $this->assertTrue($status->indexExists($indexName2));
+ $this->assertTrue($status->aliasExists($aliasName));
+ $this->assertTrue($index1->getStatus()->hasAlias($aliasName));
+ $this->assertFalse($index2->getStatus()->hasAlias($aliasName));
+
+ $index2->addAlias($aliasName, true);
+ $this->assertFalse($index1->getStatus()->hasAlias($aliasName));
+ $this->assertTrue($index2->getStatus()->hasAlias($aliasName));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddDocumentVersion()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = new Type($index, 'test');
+
+ $doc1 = new Document(1);
+ $doc1->set('title', 'Hello world');
+
+ $return = $type->addDocument($doc1);
+ $data = $return->getData();
+ $this->assertEquals(1, $data['_version']);
+
+ $return = $type->addDocument($doc1);
+ $data = $return->getData();
+ $this->assertEquals(2, $data['_version']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testClearCache()
+ {
+ $index = $this->_createIndex();
+ $response = $index->clearCache();
+ $this->assertFalse($response->hasError());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFlush()
+ {
+ $index = $this->_createIndex();
+ $response = $index->flush();
+ $this->assertFalse($response->hasError());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testExists()
+ {
+ $index = $this->_createIndex();
+
+ $this->assertTrue($index->exists());
+
+ $index->delete();
+
+ $this->assertFalse($index->exists());
+ }
+
+ /**
+ * Test $index->delete() return value for unknown index.
+ *
+ * Tests if deleting an index that does not exist in Elasticsearch,
+ * correctly returns a boolean true from the hasError() method of
+ * the \Elastica\Response object
+ *
+ * @group functional
+ */
+ public function testDeleteMissingIndexHasError()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('index_does_not_exist');
+
+ try {
+ $index->delete();
+ $this->fail('This should never be reached. Deleting an unknown index will throw an exception');
+ } catch (ResponseException $error) {
+ $response = $error->getResponse();
+ $this->assertTrue($response->hasError());
+ $request = $error->getRequest();
+ $this->assertInstanceOf('Elastica\Request', $request);
+ }
+ }
+
+ /**
+ * Tests to see if the test type mapping exists when calling $index->getMapping().
+ *
+ * @group functional
+ */
+ public function testIndexGetMapping()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $mapping = array('id' => array('type' => 'integer', 'store' => true), 'email' => array('type' => 'string', 'store' => 'no'),
+ 'username' => array('type' => 'string', 'store' => 'no'), 'test' => array('type' => 'integer', 'store' => 'no'),);
+
+ $type->setMapping($mapping);
+ $index->refresh();
+ $indexMappings = $index->getMapping();
+
+ $this->assertEquals($indexMappings['test']['properties']['id']['type'], 'integer');
+ $this->assertEquals($indexMappings['test']['properties']['id']['store'], true);
+ $this->assertEquals($indexMappings['test']['properties']['email']['type'], 'string');
+ $this->assertEquals($indexMappings['test']['properties']['username']['type'], 'string');
+ $this->assertEquals($indexMappings['test']['properties']['test']['type'], 'integer');
+ }
+
+ /**
+ * Tests to see if the index is empty when there are no types set.
+ *
+ * @group functional
+ */
+ public function testEmptyIndexGetMapping()
+ {
+ $index = $this->_createIndex();
+ $indexMappings = $index->getMapping();
+
+ $this->assertTrue(empty($indexMappings['elastica_test']));
+ }
+
+ /**
+ * Test to see if search Default Limit works.
+ *
+ * @group functional
+ */
+ public function testLimitDefaultIndex()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $docs = array();
+
+ $docs[] = new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(2, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(3, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(4, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(5, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(6, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(7, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(8, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(9, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(10, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(11, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+
+ $type = $index->getType('zeroType');
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ // default limit results (default limit is 10)
+ $resultSet = $index->search('farrelley');
+ $this->assertEquals(10, $resultSet->count());
+
+ // limit = 1
+ $resultSet = $index->search('farrelley', 1);
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @expectedException \Elastica\Exception\InvalidException
+ *
+ * @group functional
+ */
+ public function testCreateArray()
+ {
+ $client = $this->_getClient();
+ $indexName = 'test';
+
+ //Testing recreate (backward compatibility)
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $this->_waitForAllocation($index);
+ $status = new Status($client);
+ $this->assertTrue($status->indexExists($indexName));
+
+ //Testing create index with array options
+ $opts = array('recreate' => true, 'routing' => 'r1,r2');
+ $index->create(array(), $opts);
+ $this->_waitForAllocation($index);
+ $status = new Status($client);
+ $this->assertTrue($status->indexExists($indexName));
+
+ //Testing invalid options
+ $opts = array('recreate' => true, 'routing' => 'r1,r2', 'testing_invalid_option' => true);
+ $index->create(array(), $opts);
+ $this->_waitForAllocation($index);
+ $status = new Status($client);
+ $this->assertTrue($status->indexExists($indexName));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCreateSearch()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test');
+
+ $query = new QueryString('test');
+ $options = 5;
+
+ $search = $index->createSearch($query, $options);
+
+ $expected = array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'test',
+ ),
+ ),
+ 'size' => 5,
+ );
+ $this->assertEquals($expected, $search->getQuery()->toArray());
+ $this->assertEquals(array('test'), $search->getIndices());
+ $this->assertTrue($search->hasIndices());
+ $this->assertTrue($search->hasIndex('test'));
+ $this->assertTrue($search->hasIndex($index));
+ $this->assertEquals(array(), $search->getTypes());
+ $this->assertFalse($search->hasTypes());
+ $this->assertFalse($search->hasType('test_type'));
+
+ $type = new Type($index, 'test_type2');
+ $this->assertFalse($search->hasType($type));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $index = $this->_createIndex();
+
+ $type = new Type($index, 'user');
+
+ $docs = array();
+ $docs[] = new Document(1, array('username' => 'hans', 'test' => array('2', '3', '5')));
+ $docs[] = new Document(2, array('username' => 'john', 'test' => array('1', '3', '6')));
+ $docs[] = new Document(3, array('username' => 'rolf', 'test' => array('2', '3', '7')));
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $resultSet = $index->search('rolf');
+ $this->assertEquals(1, $resultSet->count());
+
+ $count = $index->count('rolf');
+ $this->assertEquals(1, $count);
+
+ // Test if source is returned
+ $result = $resultSet->current();
+ $this->assertEquals(3, $result->getId());
+ $data = $result->getData();
+ $this->assertEquals('rolf', $data['username']);
+
+ $count = $index->count();
+ $this->assertEquals(3, $count);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testOptimize()
+ {
+ $index = $this->_createIndex();
+
+ $type = new Type($index, 'optimize');
+
+ $docs = array();
+ $docs[] = new Document(1, array('foo' => 'bar'));
+ $docs[] = new Document(2, array('foo' => 'bar'));
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $stats = $index->getStats()->getData();
+ $this->assertEquals(0, $stats['_all']['primaries']['docs']['deleted']);
+
+ $type->deleteById(1);
+ $index->refresh();
+
+ $stats = $index->getStats()->getData();
+ $this->assertEquals(1, $stats['_all']['primaries']['docs']['deleted']);
+
+ $index->optimize(array('max_num_segments' => 1));
+
+ $stats = $index->getStats()->getData();
+ $this->assertEquals(0, $stats['_all']['primaries']['docs']['deleted']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAnalyze()
+ {
+ $index = $this->_createIndex();
+ $index->optimize();
+ sleep(2);
+ $returnedTokens = $index->analyze('foo');
+
+ $tokens = array(
+ array(
+ 'token' => 'foo',
+ 'start_offset' => 0,
+ 'end_offset' => 3,
+ 'type' => '<ALPHANUM>',
+ 'position' => 1,
+ ),
+ );
+
+ $this->assertEquals($tokens, $returnedTokens);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testThrowExceptionIfNotScalar()
+ {
+ $client = $this->_getClient();
+ $client->getIndex(new \stdClass());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConvertScalarsToString()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex(1);
+
+ $this->assertEquals('1', $index->getName());
+ $this->assertInternalType('string', $index->getName());
+ }
+
+ /**
+ * Check for the presence of the mapper-attachments plugin and skip the current test if it is not found.
+ */
+ protected function _checkAttachmentsPlugin()
+ {
+ $nodes = $this->_getClient()->getCluster()->getNodes();
+ if (!$nodes[0]->getInfo()->hasPlugin('mapper-attachments')) {
+ $this->markTestSkipped('mapper-attachments plugin not installed');
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/LogTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/LogTest.php
new file mode 100644
index 00000000..fdfc5c00
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/LogTest.php
@@ -0,0 +1,196 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Log;
+use Elastica\Test\Base as BaseTest;
+use Psr\Log\LogLevel;
+
+class LogTest extends BaseTest
+{
+ private $_context = array();
+ private $_message = 'hello world';
+
+ public static function setUpBeforeClass()
+ {
+ if (!class_exists('Psr\Log\AbstractLogger')) {
+ self::markTestSkipped('The Psr extension is not available.');
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testLogInterface()
+ {
+ $log = new Log();
+ $this->assertInstanceOf('Psr\Log\LoggerInterface', $log);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetLogConfigPath()
+ {
+ $logPath = '/tmp/php.log';
+ $client = $this->_getClient(array('log' => $logPath));
+ $this->assertEquals($logPath, $client->getConfig('log'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetLogConfigEnable()
+ {
+ $client = $this->_getClient(array('log' => true));
+ $this->assertTrue($client->getConfig('log'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetLogConfigEnable1()
+ {
+ $client = $this->_getClient();
+ $client->setLogger(new Log());
+ $this->assertFalse($client->getConfig('log'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testEmptyLogConfig()
+ {
+ $client = $this->_getClient();
+ $this->assertEmpty($client->getConfig('log'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessage()
+ {
+ $log = new Log('/tmp/php.log');
+
+ $log->log(LogLevel::DEBUG, $this->_message, $this->_context);
+
+ $this->_context['error_message'] = $this->_message;
+ $message = json_encode($this->_context);
+
+ $this->assertEquals($message, $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessage2()
+ {
+ $client = $this->_getClient(array('log' => true));
+ $log = new Log($client);
+
+ // Set log path temp path as otherwise test fails with output
+ $errorLog = ini_get('error_log');
+ ini_set('error_log', sys_get_temp_dir().DIRECTORY_SEPARATOR.'php.log');
+
+ $this->_context['error_message'] = $this->_message;
+ $message = json_encode($this->_context);
+
+ $log->log(LogLevel::DEBUG, $this->_message, $this->_context);
+ ini_set('error_log', $errorLog);
+
+ $this->assertEquals($message, $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageInfo()
+ {
+ $log = $this->initLog();
+ $log->info($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageCritical()
+ {
+ $log = $this->initLog();
+ $log->critical($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageAlert()
+ {
+ $log = $this->initLog();
+ $log->alert($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageDebug()
+ {
+ $log = $this->initLog();
+ $log->debug($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageEmergency()
+ {
+ $log = $this->initLog();
+ $log->emergency($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageError()
+ {
+ $log = $this->initLog();
+ $log->error($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageNotice()
+ {
+ $log = $this->initLog();
+ $log->notice($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetLastMessageWarning()
+ {
+ $log = $this->initLog();
+ $log->warning($this->_message, $this->_context);
+ $this->assertEquals($this->getMessage(), $log->getLastMessage());
+ }
+
+ private function initLog()
+ {
+ $log = new Log('/tmp/php.log');
+
+ return $log;
+ }
+
+ private function getMessage()
+ {
+ $this->_context['error_message'] = $this->_message;
+
+ return json_encode($this->_context);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Multi/SearchTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Multi/SearchTest.php
new file mode 100644
index 00000000..765c8c1d
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Multi/SearchTest.php
@@ -0,0 +1,575 @@
+<?php
+namespace Elastica\Test\Multi;
+
+use Elastica\Document;
+use Elastica\Multi\Search as MultiSearch;
+use Elastica\Query;
+use Elastica\Query\Range;
+use Elastica\Query\Term;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+
+class SearchTest extends BaseTest
+{
+ /**
+ * @return \Elastica\Type
+ */
+ protected function _createType()
+ {
+ $client = $this->_getClient();
+
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $docs = array();
+ $docs[] = new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(2, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(3, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(4, array('id' => 1, 'email' => 'test@test.com', 'username' => 'kate'));
+ $docs[] = new Document(5, array('id' => 1, 'email' => 'test@test.com', 'username' => 'kate'));
+ $docs[] = new Document(6, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny'));
+ $docs[] = new Document(7, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny'));
+ $docs[] = new Document(8, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny'));
+ $docs[] = new Document(9, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny'));
+ $docs[] = new Document(10, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny'));
+ $docs[] = new Document(11, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny'));
+ $type = $index->getType('zeroType');
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ return $type;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $client = $this->_getClient();
+ $multiSearch = new MultiSearch($client);
+
+ $this->assertInstanceOf('Elastica\Multi\Search', $multiSearch);
+ $this->assertSame($client, $multiSearch->getClient());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSearches()
+ {
+ $client = $this->_getClient();
+ $multiSearch = new MultiSearch($client);
+
+ $search1 = new Search($client);
+ $search2 = new Search($client);
+ $search3 = new Search($client);
+
+ $multiSearch->setSearches(array($search1, $search2, $search3));
+
+ $searches = $multiSearch->getSearches();
+
+ $this->assertInternalType('array', $searches);
+ $this->assertCount(3, $searches);
+ $this->assertArrayHasKey(0, $searches);
+ $this->assertSame($search1, $searches[0]);
+ $this->assertArrayHasKey(1, $searches);
+ $this->assertSame($search2, $searches[1]);
+ $this->assertArrayHasKey(2, $searches);
+ $this->assertSame($search3, $searches[2]);
+
+ $multiSearch->clearSearches();
+ $searches = $multiSearch->getSearches();
+
+ $this->assertInternalType('array', $searches);
+ $this->assertCount(0, $searches);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSearchesByKeys()
+ {
+ $client = $this->_getClient();
+ $multiSearch = new MultiSearch($client);
+
+ $search1 = new Search($client);
+ $search2 = new Search($client);
+ $search3 = new Search($client);
+
+ $multiSearch->setSearches(array('search1' => $search1, 'search2' => $search2, $search3));
+
+ $searches = $multiSearch->getSearches();
+
+ $this->assertInternalType('array', $searches);
+ $this->assertCount(3, $searches);
+ $this->assertArrayHasKey('search1', $searches);
+ $this->assertSame($search1, $searches['search1']);
+ $this->assertArrayHasKey('search2', $searches);
+ $this->assertSame($search2, $searches['search2']);
+ $this->assertArrayHasKey(0, $searches);
+ $this->assertSame($search3, $searches[0]);
+
+ $multiSearch->clearSearches();
+ $searches = $multiSearch->getSearches();
+
+ $this->assertInternalType('array', $searches);
+ $this->assertCount(0, $searches);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $type = $this->_createType();
+ $index = $type->getIndex();
+ $client = $index->getClient();
+
+ $multiSearch = new MultiSearch($client);
+
+ $search1 = new Search($client);
+ $search1->addIndex($index)->addType($type);
+ $query1 = new Query();
+ $termQuery1 = new Term();
+ $termQuery1->setTerm('username', 'farrelley');
+ $query1->setQuery($termQuery1);
+ $query1->setSize(2);
+ $search1->setQuery($query1);
+
+ $multiSearch->addSearch($search1);
+
+ $this->assertCount(1, $multiSearch->getSearches());
+
+ $search2 = new Search($client);
+ $search2->addIndex($index)->addType($type);
+ $query2 = new Query();
+ $termQuery2 = new Term();
+ $termQuery2->setTerm('username', 'bunny');
+ $query2->setQuery($termQuery2);
+ $query2->setSize(3);
+ $search2->setQuery($query2);
+
+ $multiSearch->addSearch($search2);
+
+ $this->assertCount(2, $multiSearch->getSearches());
+
+ $searches = $multiSearch->getSearches();
+ $this->assertSame($search1, $searches[0]);
+ $this->assertSame($search2, $searches[1]);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ foreach ($multiResultSet as $resultSet) {
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSet);
+ }
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertCount(2, $resultSets[0]);
+ $this->assertSame($query1, $resultSets[0]->getQuery());
+ $this->assertEquals(3, $resultSets[0]->getTotalHits());
+
+ $this->assertArrayHasKey(1, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[1]);
+ $this->assertCount(3, $resultSets[1]);
+ $this->assertSame($query2, $resultSets[1]->getQuery());
+ $this->assertEquals(6, $resultSets[1]->getTotalHits());
+
+ $this->assertFalse($multiResultSet->hasError());
+
+ $search1->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_COUNT);
+ $search2->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_COUNT);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertCount(0, $resultSets[0]);
+ $this->assertSame($query1, $resultSets[0]->getQuery());
+ $this->assertEquals(3, $resultSets[0]->getTotalHits());
+
+ $this->assertArrayHasKey(1, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[1]);
+ $this->assertCount(0, $resultSets[1]);
+ $this->assertSame($query2, $resultSets[1]->getQuery());
+ $this->assertEquals(6, $resultSets[1]->getTotalHits());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchWithKeys()
+ {
+ $type = $this->_createType();
+ $index = $type->getIndex();
+ $client = $index->getClient();
+
+ $multiSearch = new MultiSearch($client);
+
+ $search1 = new Search($client);
+ $search1->addIndex($index)->addType($type);
+ $query1 = new Query();
+ $termQuery1 = new Term();
+ $termQuery1->setTerm('username', 'farrelley');
+ $query1->setQuery($termQuery1);
+ $query1->setSize(2);
+ $search1->setQuery($query1);
+
+ $multiSearch->addSearch($search1, 'search1');
+
+ $this->assertCount(1, $multiSearch->getSearches());
+
+ $search2 = new Search($client);
+ $search2->addIndex($index)->addType($type);
+ $query2 = new Query();
+ $termQuery2 = new Term();
+ $termQuery2->setTerm('username', 'bunny');
+ $query2->setQuery($termQuery2);
+ $query2->setSize(3);
+ $search2->setQuery($query2);
+
+ $multiSearch->addSearch($search2, 'search2');
+
+ $this->assertCount(2, $multiSearch->getSearches());
+
+ $searches = $multiSearch->getSearches();
+ $this->assertSame($search1, $searches['search1']);
+ $this->assertSame($search2, $searches['search2']);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ foreach ($multiResultSet as $resultSet) {
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSet);
+ }
+
+ $this->assertInstanceOf('Elastica\ResultSet', $multiResultSet['search1']);
+ $this->assertInstanceOf('Elastica\ResultSet', $multiResultSet['search2']);
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey('search1', $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets['search1']);
+ $this->assertCount(2, $resultSets['search1']);
+ $this->assertSame($query1, $resultSets['search1']->getQuery());
+ $this->assertEquals(3, $resultSets['search1']->getTotalHits());
+
+ $this->assertArrayHasKey('search2', $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets['search2']);
+ $this->assertCount(3, $resultSets['search2']);
+ $this->assertSame($query2, $resultSets['search2']->getQuery());
+ $this->assertEquals(6, $resultSets['search2']->getTotalHits());
+
+ $this->assertFalse($multiResultSet->hasError());
+
+ $search1->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_COUNT);
+ $search2->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_COUNT);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey('search1', $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets['search1']);
+ $this->assertCount(0, $resultSets['search1']);
+ $this->assertSame($query1, $resultSets['search1']->getQuery());
+ $this->assertEquals(3, $resultSets['search1']->getTotalHits());
+
+ $this->assertArrayHasKey('search2', $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets['search2']);
+ $this->assertCount(0, $resultSets['search2']);
+ $this->assertSame($query2, $resultSets['search2']->getQuery());
+ $this->assertEquals(6, $resultSets['search2']->getTotalHits());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchWithError()
+ {
+ $type = $this->_createType();
+ $index = $type->getIndex();
+ $client = $index->getClient();
+
+ $multiSearch = new MultiSearch($client);
+
+ $searchGood = new Search($client);
+ $searchGood->setQuery('bunny');
+ $searchGood->addIndex($index)->addType($type);
+
+ $multiSearch->addSearch($searchGood);
+
+ $searchBad = new Search($client);
+ $searchBadQuery = new Range();
+ $searchBadQuery->addField('bad', array('from' => 0));
+ $searchBadQuery->setParam('_cache', true);
+ $searchBad->setQuery($searchBadQuery);
+ $searchBad->addIndex($index)->addType($type);
+
+ $multiSearch->addSearch($searchBad);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $resultSets = $multiResultSet->getResultSets();
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertSame($searchGood->getQuery(), $resultSets[0]->getQuery());
+ $this->assertSame(6, $resultSets[0]->getTotalHits());
+ $this->assertCount(6, $resultSets[0]);
+
+ $this->assertArrayHasKey(1, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[1]);
+ $this->assertSame($searchBad->getQuery(), $resultSets[1]->getQuery());
+ $this->assertSame(0, $resultSets[1]->getTotalHits());
+ $this->assertCount(0, $resultSets[1]);
+ $this->assertTrue($resultSets[1]->getResponse()->hasError());
+
+ $this->assertTrue($multiResultSet->hasError());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchWithErrorWithKeys()
+ {
+ $type = $this->_createType();
+ $index = $type->getIndex();
+ $client = $index->getClient();
+
+ $multiSearch = new MultiSearch($client);
+
+ $searchGood = new Search($client);
+ $searchGood->setQuery('bunny');
+ $searchGood->addIndex($index)->addType($type);
+
+ $multiSearch->addSearch($searchGood, 'search1');
+
+ $searchBad = new Search($client);
+ $searchBadQuery = new Range();
+ $searchBadQuery->addField('bad', array('from' => 0));
+ $searchBadQuery->setParam('_cache', true);
+ $searchBad->setQuery($searchBadQuery);
+ $searchBad->addIndex($index)->addType($type);
+
+ $multiSearch->addSearch($searchBad);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $resultSets = $multiResultSet->getResultSets();
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey('search1', $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets['search1']);
+ $this->assertSame($searchGood->getQuery(), $resultSets['search1']->getQuery());
+ $this->assertSame(6, $resultSets['search1']->getTotalHits());
+ $this->assertCount(6, $resultSets['search1']);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertSame($searchBad->getQuery(), $resultSets[0]->getQuery());
+ $this->assertSame(0, $resultSets[0]->getTotalHits());
+ $this->assertCount(0, $resultSets[0]);
+ $this->assertTrue($resultSets[0]->getResponse()->hasError());
+
+ $this->assertTrue($multiResultSet->hasError());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGlobalSearchTypeSearch()
+ {
+ $type = $this->_createType();
+ $index = $type->getIndex();
+ $client = $index->getClient();
+
+ $multiSearch = new MultiSearch($client);
+
+ $search1 = new Search($client);
+ $search1->addIndex($index)->addType($type);
+ $query1 = new Query();
+ $termQuery1 = new Term();
+ $termQuery1->setTerm('username', 'farrelley');
+ $query1->setQuery($termQuery1);
+ $query1->setSize(2);
+ $search1->setQuery($query1);
+
+ $multiSearch->addSearch($search1);
+
+ $this->assertCount(1, $multiSearch->getSearches());
+
+ $search2 = new Search($client);
+ $search2->addIndex($index)->addType($type);
+ $query2 = new Query();
+ $termQuery2 = new Term();
+ $termQuery2->setTerm('username', 'bunny');
+ $query2->setQuery($termQuery2);
+ $query2->setSize(3);
+ $search2->setQuery($query2);
+
+ $multiSearch->addSearch($search2);
+
+ $multiSearch->setSearchType(Search::OPTION_SEARCH_TYPE_COUNT);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertCount(0, $resultSets[0]);
+ $this->assertSame($query1, $resultSets[0]->getQuery());
+ $this->assertEquals(3, $resultSets[0]->getTotalHits());
+
+ $this->assertArrayHasKey(1, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[1]);
+ $this->assertCount(0, $resultSets[1]);
+ $this->assertSame($query2, $resultSets[1]->getQuery());
+ $this->assertEquals(6, $resultSets[1]->getTotalHits());
+
+ $search1->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_QUERY_AND_FETCH);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertCount(2, $resultSets[0]);
+ $this->assertSame($query1, $resultSets[0]->getQuery());
+ $this->assertEquals(3, $resultSets[0]->getTotalHits());
+
+ $this->assertArrayHasKey(1, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[1]);
+ $this->assertCount(0, $resultSets[1]);
+ $this->assertSame($query2, $resultSets[1]->getQuery());
+ $this->assertEquals(6, $resultSets[1]->getTotalHits());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGlobalSearchTypeSearchWithKeys()
+ {
+ $type = $this->_createType();
+ $index = $type->getIndex();
+ $client = $index->getClient();
+
+ $multiSearch = new MultiSearch($client);
+
+ $search1 = new Search($client);
+ $search1->addIndex($index)->addType($type);
+ $query1 = new Query();
+ $termQuery1 = new Term();
+ $termQuery1->setTerm('username', 'farrelley');
+ $query1->setQuery($termQuery1);
+ $query1->setSize(2);
+ $search1->setQuery($query1);
+
+ $multiSearch->addSearch($search1);
+
+ $this->assertCount(1, $multiSearch->getSearches());
+
+ $search2 = new Search($client);
+ $search2->addIndex($index)->addType($type);
+ $query2 = new Query();
+ $termQuery2 = new Term();
+ $termQuery2->setTerm('username', 'bunny');
+ $query2->setQuery($termQuery2);
+ $query2->setSize(3);
+ $search2->setQuery($query2);
+
+ $multiSearch->addSearch($search2);
+
+ $multiSearch->setSearchType(Search::OPTION_SEARCH_TYPE_COUNT);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertCount(0, $resultSets[0]);
+ $this->assertSame($query1, $resultSets[0]->getQuery());
+ $this->assertEquals(3, $resultSets[0]->getTotalHits());
+
+ $this->assertArrayHasKey(1, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[1]);
+ $this->assertCount(0, $resultSets[1]);
+ $this->assertSame($query2, $resultSets[1]->getQuery());
+ $this->assertEquals(6, $resultSets[1]->getTotalHits());
+
+ $search1->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_QUERY_AND_FETCH);
+
+ $multiResultSet = $multiSearch->search();
+
+ $this->assertInstanceOf('Elastica\Multi\ResultSet', $multiResultSet);
+ $this->assertCount(2, $multiResultSet);
+ $this->assertInstanceOf('Elastica\Response', $multiResultSet->getResponse());
+
+ $resultSets = $multiResultSet->getResultSets();
+
+ $this->assertInternalType('array', $resultSets);
+
+ $this->assertArrayHasKey(0, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[0]);
+ $this->assertCount(2, $resultSets[0]);
+ $this->assertSame($query1, $resultSets[0]->getQuery());
+ $this->assertEquals(3, $resultSets[0]->getTotalHits());
+
+ $this->assertArrayHasKey(1, $resultSets);
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSets[1]);
+ $this->assertCount(0, $resultSets[1]);
+ $this->assertSame($query2, $resultSets[1]->getQuery());
+ $this->assertEquals(6, $resultSets[1]->getTotalHits());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Node/InfoTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Node/InfoTest.php
new file mode 100644
index 00000000..812f141e
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Node/InfoTest.php
@@ -0,0 +1,79 @@
+<?php
+namespace Elastica\Test\Node;
+
+use Elastica\Node;
+use Elastica\Node\Info as NodeInfo;
+use Elastica\Test\Base as BaseTest;
+
+class InfoTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGet()
+ {
+ $client = $this->_getClient();
+ $names = $client->getCluster()->getNodeNames();
+ $name = reset($names);
+
+ $node = new Node($name, $client);
+ $info = new NodeInfo($node);
+
+ $this->assertNull($info->get('os', 'mem', 'total'));
+
+ // Load os infos
+ $info = new NodeInfo($node, array('os'));
+
+ $this->assertNotNull($info->get('os', 'mem', 'total_in_bytes'));
+ $this->assertInternalType('array', $info->get('os', 'mem'));
+ $this->assertNull($info->get('test', 'notest', 'notexist'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testHasPlugin()
+ {
+ $client = $this->_getClient();
+ $nodes = $client->getCluster()->getNodes();
+ $node = $nodes[0];
+ $info = $node->getInfo();
+
+ $pluginName = 'mapper-attachments';
+
+ $this->assertTrue($info->hasPlugin($pluginName));
+ $this->assertFalse($info->hasPlugin('foo'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetId()
+ {
+ $client = $this->_getClient();
+ $nodes = $client->getCluster()->getNodes();
+
+ $ids = array();
+
+ foreach ($nodes as $node) {
+ $id = $node->getInfo()->getId();
+
+ // Checks that the ids are unique
+ $this->assertFalse(in_array($id, $ids));
+ $ids[] = $id;
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetName()
+ {
+ $client = $this->_getClient();
+ $nodes = $client->getCluster()->getNodes();
+
+ foreach ($nodes as $node) {
+ $this->assertEquals('Elastica', $node->getInfo()->getName());
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/NodeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/NodeTest.php
new file mode 100644
index 00000000..fbd2d297
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/NodeTest.php
@@ -0,0 +1,75 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Node;
+use Elastica\Test\Base as BaseTest;
+
+class NodeTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testCreateNode()
+ {
+ $client = $this->_getClient();
+ $names = $client->getCluster()->getNodeNames();
+ $name = reset($names);
+
+ $node = new Node($name, $client);
+ $this->assertInstanceOf('Elastica\Node', $node);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetInfo()
+ {
+ $client = $this->_getClient();
+ $names = $client->getCluster()->getNodeNames();
+ $name = reset($names);
+
+ $node = new Node($name, $client);
+
+ $info = $node->getInfo();
+
+ $this->assertInstanceOf('Elastica\Node\Info', $info);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetStats()
+ {
+ $client = $this->_getClient();
+ $names = $client->getCluster()->getNodeNames();
+ $name = reset($names);
+
+ $node = new Node($name, $client);
+
+ $stats = $node->getStats();
+
+ $this->assertInstanceOf('Elastica\Node\Stats', $stats);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetName()
+ {
+ $nodes = $this->_getClient()->getCluster()->getNodes();
+ // At least 1 instance must exist
+ $this->assertGreaterThan(0, $nodes);
+
+ foreach ($nodes as $node) {
+ $this->assertEquals($node->getName(), 'Elastica');
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetId()
+ {
+ $node = new Node('Elastica', $this->_getClient());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ParamTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ParamTest.php
new file mode 100644
index 00000000..eade8118
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ParamTest.php
@@ -0,0 +1,115 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Param;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Util;
+
+class ParamTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArrayEmpty()
+ {
+ $param = new Param();
+ $this->assertInstanceOf('Elastica\Param', $param);
+ $this->assertEquals(array($this->_getFilterName($param) => array()), $param->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetParams()
+ {
+ $param = new Param();
+ $params = array('hello' => 'word', 'nicolas' => 'ruflin');
+ $param->setParams($params);
+
+ $this->assertInstanceOf('Elastica\Param', $param);
+ $this->assertEquals(array($this->_getFilterName($param) => $params), $param->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetGetParam()
+ {
+ $param = new Param();
+
+ $key = 'name';
+ $value = 'nicolas ruflin';
+
+ $params = array($key => $value);
+ $param->setParam($key, $value);
+
+ $this->assertEquals($params, $param->getParams());
+ $this->assertEquals($value, $param->getParam($key));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddParam()
+ {
+ $param = new Param();
+
+ $key = 'name';
+ $value = 'nicolas ruflin';
+
+ $param->addParam($key, $value);
+
+ $this->assertEquals(array($key => array($value)), $param->getParams());
+ $this->assertEquals(array($value), $param->getParam($key));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddParam2()
+ {
+ $param = new Param();
+
+ $key = 'name';
+ $value1 = 'nicolas';
+ $value2 = 'ruflin';
+
+ $param->addParam($key, $value1);
+ $param->addParam($key, $value2);
+
+ $this->assertEquals(array($key => array($value1, $value2)), $param->getParams());
+ $this->assertEquals(array($value1, $value2), $param->getParam($key));
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testGetParamInvalid()
+ {
+ $param = new Param();
+
+ $param->getParam('notest');
+ }
+
+ /**
+ * @group unit
+ */
+ public function testHasParam()
+ {
+ $param = new Param();
+
+ $key = 'name';
+ $value = 'nicolas ruflin';
+
+ $this->assertFalse($param->hasParam($key));
+
+ $param->setParam($key, $value);
+ $this->assertTrue($param->hasParam($key));
+ }
+
+ protected function _getFilterName($filter)
+ {
+ return Util::getParamName($filter);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/PercolatorTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/PercolatorTest.php
new file mode 100644
index 00000000..2a5a88c3
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/PercolatorTest.php
@@ -0,0 +1,328 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Percolator;
+use Elastica\Query;
+use Elastica\Query\Term;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+
+class PercolatorTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testConstruct()
+ {
+ $index = $this->_createIndex();
+ $percolatorName = $index->getName();
+
+ $percolator = new Percolator($index);
+
+ $query = new Term(array('field1' => 'value1'));
+ $response = $percolator->registerQuery($percolatorName, $query);
+
+ $data = $response->getData();
+
+ $expectedArray = array(
+ '_type' => '.percolator',
+ '_index' => $index->getName(),
+ '_id' => $percolatorName,
+ '_version' => 1,
+ 'created' => 1,
+ );
+
+ $this->assertEquals($expectedArray, $data);
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchDoc()
+ {
+ $index = $this->_createIndex();
+
+ $percolator = new Percolator($index);
+
+ $percolatorName = $index->getName();
+
+ $query = new Term(array('name' => 'ruflin'));
+ $response = $percolator->registerQuery($percolatorName, $query);
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $doc1 = new Document();
+ $doc1->set('name', 'ruflin');
+
+ $doc2 = new Document();
+ $doc2->set('name', 'nicolas');
+
+ $index->refresh();
+
+ $matches1 = $percolator->matchDoc($doc1);
+
+ $this->assertCount(1, $matches1);
+ $firstPercolatorFound = false;
+ foreach ($matches1 as $match) {
+ if ($match['_id'] == $percolatorName) {
+ $firstPercolatorFound = true;
+ }
+ }
+ $this->assertTrue($firstPercolatorFound);
+
+ $matches2 = $percolator->matchDoc($doc2);
+ $this->assertEmpty($matches2);
+
+ $index->delete();
+ }
+
+ /**
+ * Test case for using filtered percolator queries based on the Elasticsearch documentation examples.
+ *
+ * @group functional
+ */
+ public function testFilteredMatchDoc()
+ {
+ // step one: register create index and setup the percolator query from the ES documentation.
+ $index = $this->_createIndex();
+ $percolator = new Percolator($index);
+ $baseQuery = new Term(array('field1' => 'value1'));
+ $fields = array('color' => 'blue');
+
+ $response = $percolator->registerQuery('kuku', $baseQuery, $fields);
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ // refreshing is required in order to ensure the query is really ready for execution.
+ $index->refresh();
+
+ // step two: match a document which should match the kuku query when filtered on the blue color
+ $doc = new Document();
+ $doc->set('field1', 'value1');
+
+ $matches = $percolator->matchDoc($doc, new Term(array('color' => 'blue')));
+ $this->assertCount(1, $matches, 'No or too much registered query matched.');
+ $this->assertEquals('kuku', $matches[0]['_id'], 'A wrong registered query has matched.');
+
+ // step three: validate that using a different color, no registered query matches.
+ $matches = $percolator->matchDoc($doc, new Term(array('color' => 'green')));
+ $this->assertCount(0, $matches, 'A registered query matched, although nothing should match at all.');
+
+ $index->delete();
+ }
+
+ /**
+ * Test case for using filtered percolator queries based on the Elasticsearch documentation examples.
+ *
+ * @group functional
+ */
+ public function testRegisterAndUnregisterPercolator()
+ {
+ // step one: register create index and setup the percolator query from the ES documentation.
+ $index = $this->_createIndex();
+ $percolator = new Percolator($index);
+ $baseQuery = new Term(array('field1' => 'value1'));
+ $fields = array('color' => 'blue');
+
+ $response = $percolator->registerQuery('kuku', $baseQuery, $fields);
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ // refreshing is required in order to ensure the query is really ready for execution.
+ $index->refresh();
+
+ // step two: match a document which should match the kuku query when filtered on the blue color
+ $doc = new Document();
+ $doc->set('field1', 'value1');
+
+ $matches = $percolator->matchDoc($doc, new Term(array('color' => 'blue')));
+ $this->assertCount(1, $matches, 'No or too much registered query matched.');
+ $this->assertEquals('kuku', $matches[0]['_id'], 'A wrong registered query has matched.');
+
+ // step three: validate that using a different color, no registered query matches.
+ $matches = $percolator->matchDoc($doc, new Term(array('color' => 'green')));
+ $this->assertCount(0, $matches, 'A registered query matched, although nothing should match at all.');
+
+ // unregister percolator query
+ $response = $percolator->unregisterQuery('kuku');
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ // refreshing is required in order to ensure the query is really ready for execution.
+ $index->refresh();
+
+ $matches = $percolator->matchDoc($doc, new Term(array('color' => 'blue')));
+ $this->assertCount(0, $matches, 'Percolator query did not get deleted.');
+
+ $index->delete();
+ }
+
+ protected function _getDefaultPercolator($percolatorName = 'existingDoc')
+ {
+ $index = $this->_createIndex();
+ $percolator = new Percolator($index);
+
+ $query = new Term(array('name' => 'foobar'));
+ $percolator->registerQuery($percolatorName, $query, array('field1' => array('tag1', 'tag2')));
+
+ return $percolator;
+ }
+
+ protected function _addDefaultDocuments($index, $type = 'testing')
+ {
+ $type = $index->getType('testing');
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'foobar')),
+ new Document(2, array('name' => 'barbaz')),
+ ));
+ $index->refresh();
+
+ return $type;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testPercolateExistingDocWithoutAnyParameter()
+ {
+ $percolator = $this->_getDefaultPercolator();
+ $index = $percolator->getIndex();
+ $type = $this->_addDefaultDocuments($index);
+
+ $matches = $percolator->matchExistingDoc(1, $type->getName());
+
+ $this->assertCount(1, $matches);
+ $this->assertEquals('existingDoc', $matches[0]['_id']);
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testPercolateExistingDocWithPercolateFormatIds()
+ {
+ $percolator = $this->_getDefaultPercolator();
+ $index = $percolator->getIndex();
+ $type = $this->_addDefaultDocuments($index);
+
+ $parameter = array('percolate_format' => 'ids');
+ $matches = $percolator->matchExistingDoc(1, $type->getName(), null, $parameter);
+
+ $this->assertCount(1, $matches);
+ $this->assertEquals('existingDoc', $matches[0]);
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testPercolateExistingDocWithIdThatShouldBeUrlEncoded()
+ {
+ $percolator = $this->_getDefaultPercolator();
+ $index = $percolator->getIndex();
+ $type = $this->_addDefaultDocuments($index);
+
+ // id with whitespace, should be urlencoded
+ $id = 'foo bar 1';
+
+ $type->addDocument(new Document($id, array('name' => 'foobar')));
+ $index->refresh();
+
+ $matches = $percolator->matchExistingDoc($id, $type->getName());
+
+ $this->assertCount(1, $matches);
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testPercolateWithAdditionalRequestBodyOptions()
+ {
+ $index = $this->_createIndex();
+ $percolator = new Percolator($index);
+
+ $query = new Term(array('name' => 'foo'));
+ $response = $percolator->registerQuery('percotest', $query, array('field1' => array('tag1', 'tag2')));
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $query = new Term(array('name' => 'foo'));
+ $response = $percolator->registerQuery('percotest1', $query, array('field1' => array('tag2')));
+
+ $this->assertTrue($response->isOk());
+ $this->assertFalse($response->hasError());
+
+ $doc1 = new Document();
+ $doc1->set('name', 'foo');
+
+ $index->refresh();
+
+ $options = array(
+ 'track_scores' => true,
+ 'sort' => array('_score' => 'desc'),
+ 'size' => 1,
+ );
+
+ $matches = $percolator->matchDoc($doc1, new Term(array('field1' => 'tag2')), 'type', $options);
+
+ $this->assertCount(1, $matches);
+ $this->assertEquals('percotest1', $matches[0]['_id']);
+ $this->assertArrayHasKey('_score', $matches[0]);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testPercolateExistingDocWithAdditionalRequestBodyOptions()
+ {
+ $percolatorName = 'existingDoc';
+ $percolator = $this->_getDefaultPercolator($percolatorName);
+
+ $query = new Term(array('name' => 'foobar'));
+ $percolator->registerQuery($percolatorName.'1', $query, array('field1' => array('tag2')));
+
+ $index = $percolator->getIndex();
+ $type = $this->_addDefaultDocuments($index);
+
+ $options = array(
+ 'track_scores' => true,
+ 'sort' => array('_score' => 'desc'),
+ 'size' => 1,
+ );
+
+ $matches = $percolator->matchExistingDoc(1, $type->getName(), new Term(array('field1' => 'tag2')), $options);
+
+ $this->assertCount(1, $matches);
+ $this->assertEquals('existingDoc1', $matches[0]['_id']);
+ $this->assertArrayHasKey('_score', $matches[0]);
+ $index->delete();
+ }
+
+ protected function _createIndex($name = null, $delete = true, $shards = 1)
+ {
+ $index = parent::_createIndex($name, $delete, $shards);
+ $type = $index->getType('.percolator');
+
+ $mapping = new Type\Mapping($type,
+ array(
+ 'name' => array('type' => 'string'),
+ 'field1' => array('type' => 'string'),
+ )
+ );
+ $mapping->disableSource();
+
+ $type->setMapping($mapping);
+
+ return $index;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoolQueryTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoolQueryTest.php
new file mode 100644
index 00000000..211d0c23
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoolQueryTest.php
@@ -0,0 +1,171 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query\BoolQuery;
+use Elastica\Query\Ids;
+use Elastica\Query\Term;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+
+class BoolQueryTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new BoolQuery();
+
+ $idsQuery1 = new Ids();
+ $idsQuery1->setIds(1);
+
+ $idsQuery2 = new Ids();
+ $idsQuery2->setIds(2);
+
+ $idsQuery3 = new Ids();
+ $idsQuery3->setIds(3);
+
+ $boost = 1.2;
+ $minMatch = 2;
+
+ $query->setBoost($boost);
+ $query->setMinimumNumberShouldMatch($minMatch);
+ $query->addMust($idsQuery1);
+ $query->addMustNot($idsQuery2);
+ $query->addShould($idsQuery3->toArray());
+
+ $expectedArray = array(
+ 'bool' => array(
+ 'must' => array($idsQuery1->toArray()),
+ 'should' => array($idsQuery3->toArray()),
+ 'minimum_number_should_match' => $minMatch,
+ 'must_not' => array($idsQuery2->toArray()),
+ 'boost' => $boost,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * Test to resolve the following issue.
+ *
+ * @link https://groups.google.com/forum/?fromgroups#!topic/elastica-php-client/zK_W_hClfvU
+ *
+ * @group unit
+ */
+ public function testToArrayStructure()
+ {
+ $boolQuery = new BoolQuery();
+
+ $term1 = new Term();
+ $term1->setParam('interests', 84);
+
+ $term2 = new Term();
+ $term2->setParam('interests', 92);
+
+ $boolQuery->addShould($term1)->addShould($term2);
+
+ $jsonString = '{"bool":{"should":[{"term":{"interests":84}},{"term":{"interests":92}}]}}';
+ $this->assertEquals($jsonString, json_encode($boolQuery->toArray()));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test');
+ $index->create(array(), true);
+
+ $type = new Type($index, 'helloworld');
+
+ $doc = new Document(1, array('id' => 1, 'email' => 'hans@test.com', 'username' => 'hans', 'test' => array('2', '3', '5')));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('id' => 2, 'email' => 'emil@test.com', 'username' => 'emil', 'test' => array('1', '3', '6')));
+ $type->addDocument($doc);
+ $doc = new Document(3, array('id' => 3, 'email' => 'ruth@test.com', 'username' => 'ruth', 'test' => array('2', '3', '7')));
+ $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $boolQuery = new BoolQuery();
+ $termQuery1 = new Term(array('test' => '2'));
+ $boolQuery->addMust($termQuery1);
+ $resultSet = $type->search($boolQuery);
+
+ $this->assertEquals(2, $resultSet->count());
+
+ $termQuery2 = new Term(array('test' => '5'));
+ $boolQuery->addMust($termQuery2);
+ $resultSet = $type->search($boolQuery);
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $termQuery3 = new Term(array('username' => 'hans'));
+ $boolQuery->addMust($termQuery3);
+ $resultSet = $type->search($boolQuery);
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $termQuery4 = new Term(array('username' => 'emil'));
+ $boolQuery->addMust($termQuery4);
+ $resultSet = $type->search($boolQuery);
+
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testEmptyBoolQuery()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+
+ $docNumber = 3;
+ for ($i = 0; $i < $docNumber; $i++) {
+ $doc = new Document($i, array('email' => 'test@test.com'));
+ $type->addDocument($doc);
+ }
+
+ $index->refresh();
+
+ $boolQuery = new BoolQuery();
+
+ $resultSet = $type->search($boolQuery);
+
+ $this->assertEquals($resultSet->count(), $docNumber);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testOldObject()
+ {
+ if (version_compare(phpversion(), 7, '>=')) {
+ self::markTestSkipped('These objects are not supported in PHP 7');
+ }
+
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+
+ $docNumber = 3;
+ for ($i = 0; $i < $docNumber; $i++) {
+ $doc = new Document($i, array('email' => 'test@test.com'));
+ $type->addDocument($doc);
+ }
+
+ $index->refresh();
+
+ $boolQuery = new \Elastica\Query\Bool();
+
+ $resultSet = $type->search($boolQuery);
+
+ $this->assertEquals($resultSet->count(), $docNumber);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoostingTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoostingTest.php
new file mode 100644
index 00000000..8133fd37
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BoostingTest.php
@@ -0,0 +1,89 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Boosting;
+use Elastica\Query\Term;
+use Elastica\Test\Base as BaseTest;
+
+class BoostingTest extends BaseTest
+{
+ /**
+ * @var array
+ */
+ protected $sampleData = array(
+ array('name' => 'Vital Lama', 'price' => 5.2),
+ array('name' => 'Vital Match', 'price' => 2.1),
+ array('name' => 'Mercury Vital', 'price' => 7.5),
+ array('name' => 'Fist Mercury', 'price' => 3.8),
+ array('name' => 'Lama Vital 2nd', 'price' => 3.2),
+ );
+
+ protected function _getTestIndex()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $type->setMapping(array(
+ 'name' => array('type' => 'string', 'index' => 'analyzed'),
+ 'price' => array('type' => 'float'),
+ ));
+ $docs = array();
+ foreach ($this->sampleData as $key => $value) {
+ $docs[] = new Document($key, $value);
+ }
+ $type->addDocuments($docs);
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $keyword = 'vital';
+ $negativeKeyword = 'Mercury';
+
+ $query = new Boosting();
+ $positiveQuery = new Term(array('name' => $keyword));
+ $negativeQuery = new Term(array('name' => $negativeKeyword));
+ $query->setPositiveQuery($positiveQuery);
+ $query->setNegativeQuery($negativeQuery);
+ $query->setNegativeBoost(0.3);
+
+ $expected = array(
+ 'boosting' => array(
+ 'positive' => $positiveQuery->toArray(),
+ 'negative' => $negativeQuery->toArray(),
+ 'negative_boost' => 0.3,
+ ),
+ );
+ $this->assertEquals($expected, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testNegativeBoost()
+ {
+ $keyword = 'vital';
+ $negativeKeyword = 'mercury';
+
+ $query = new Boosting();
+ $positiveQuery = new Term(array('name' => $keyword));
+ $negativeQuery = new Term(array('name' => $negativeKeyword));
+ $query->setPositiveQuery($positiveQuery);
+ $query->setNegativeQuery($negativeQuery);
+ $query->setNegativeBoost(0.2);
+
+ $response = $this->_getTestIndex()->search($query);
+ $results = $response->getResults();
+
+ $this->assertEquals($response->getTotalHits(), 4);
+
+ $lastResult = $results[3]->getData();
+ $this->assertEquals($lastResult['name'], $this->sampleData[2]['name']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BuilderTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BuilderTest.php
new file mode 100644
index 00000000..a96e8b3a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/BuilderTest.php
@@ -0,0 +1,273 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Query\Builder;
+use Elastica\Test\Base as BaseTest;
+
+class BuilderTest extends BaseTest
+{
+ /**
+ * @group unit
+ * @covers \Elastica\Query\Builder::factory
+ * @covers \Elastica\Query\Builder::__construct
+ */
+ public function testFactory()
+ {
+ $this->assertInstanceOf(
+ 'Elastica\Query\Builder',
+ Builder::factory('some string')
+ );
+ }
+
+ public function getQueryData()
+ {
+ return array(
+ array('allowLeadingWildcard', false, '{"allow_leading_wildcard":"false"}'),
+ array('allowLeadingWildcard', true, '{"allow_leading_wildcard":"true"}'),
+ array('analyzeWildcard', false, '{"analyze_wildcard":"false"}'),
+ array('analyzeWildcard', true, '{"analyze_wildcard":"true"}'),
+ array('analyzer', 'someAnalyzer', '{"analyzer":"someAnalyzer"}'),
+ array('autoGeneratePhraseQueries', true, '{"auto_generate_phrase_queries":"true"}'),
+ array('autoGeneratePhraseQueries', false, '{"auto_generate_phrase_queries":"false"}'),
+ array('boost', 2, '{"boost":"2"}'),
+ array('boost', 4.2, '{"boost":"4.2"}'),
+ array('defaultField', 'fieldName', '{"default_field":"fieldName"}'),
+ array('defaultOperator', 'OR', '{"default_operator":"OR"}'),
+ array('defaultOperator', 'AND', '{"default_operator":"AND"}'),
+ array('enablePositionIncrements', true, '{"enable_position_increments":"true"}'),
+ array('enablePositionIncrements', false, '{"enable_position_increments":"false"}'),
+ array('explain', true, '{"explain":"true"}'),
+ array('explain', false, '{"explain":"false"}'),
+ array('from', 42, '{"from":"42"}'),
+ array('fuzzyMinSim', 4.2, '{"fuzzy_min_sim":"4.2"}'),
+ array('fuzzyPrefixLength', 2, '{"fuzzy_prefix_length":"2"}'),
+ array('gt', 10, '{"gt":"10"}'),
+ array('gte', 11, '{"gte":"11"}'),
+ array('lowercaseExpandedTerms', true, '{"lowercase_expanded_terms":"true"}'),
+ array('lt', 10, '{"lt":"10"}'),
+ array('lte', 11, '{"lte":"11"}'),
+ array('minimumNumberShouldMatch', 21, '{"minimum_number_should_match":"21"}'),
+ array('phraseSlop', 6, '{"phrase_slop":"6"}'),
+ array('size', 7, '{"size":"7"}'),
+ array('tieBreakerMultiplier', 7, '{"tie_breaker_multiplier":"7"}'),
+ array('matchAll', 1.1, '{"match_all":{"boost":"1.1"}}'),
+ array('fields', array('age', 'sex', 'location'), '{"fields":["age","sex","location"]}'),
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider getQueryData
+ * @covers \Elastica\Query\Builder::__toString
+ * @covers \Elastica\Query\Builder::allowLeadingWildcard
+ * @covers \Elastica\Query\Builder::analyzeWildcard
+ * @covers \Elastica\Query\Builder::analyzer
+ * @covers \Elastica\Query\Builder::autoGeneratePhraseQueries
+ * @covers \Elastica\Query\Builder::boost
+ * @covers \Elastica\Query\Builder::defaultField
+ * @covers \Elastica\Query\Builder::defaultOperator
+ * @covers \Elastica\Query\Builder::enablePositionIncrements
+ * @covers \Elastica\Query\Builder::explain
+ * @covers \Elastica\Query\Builder::from
+ * @covers \Elastica\Query\Builder::fuzzyMinSim
+ * @covers \Elastica\Query\Builder::fuzzyPrefixLength
+ * @covers \Elastica\Query\Builder::gt
+ * @covers \Elastica\Query\Builder::gte
+ * @covers \Elastica\Query\Builder::lowercaseExpandedTerms
+ * @covers \Elastica\Query\Builder::lt
+ * @covers \Elastica\Query\Builder::lte
+ * @covers \Elastica\Query\Builder::minimumNumberShouldMatch
+ * @covers \Elastica\Query\Builder::phraseSlop
+ * @covers \Elastica\Query\Builder::size
+ * @covers \Elastica\Query\Builder::tieBreakerMultiplier
+ * @covers \Elastica\Query\Builder::matchAll
+ * @covers \Elastica\Query\Builder::fields
+ */
+ public function testAllowLeadingWildcard($method, $argument, $result)
+ {
+ $builder = new Builder();
+ $this->assertSame($builder, $builder->$method($argument));
+ $this->assertSame($result, (string) $builder);
+ }
+
+ public function getQueryTypes()
+ {
+ return array(
+ array('bool', 'bool'),
+ array('constantScore', 'constant_score'),
+ array('disMax', 'dis_max'),
+ array('facets', 'facets'),
+ array('filter', 'filter'),
+ array('filteredQuery', 'filtered'),
+ array('must', 'must'),
+ array('mustNot', 'must_not'),
+ array('prefix', 'prefix'),
+ array('query', 'query'),
+ array('queryString', 'query_string'),
+ array('range', 'range'),
+ array('should', 'should'),
+ array('sort', 'sort'),
+ array('term', 'term'),
+ array('textPhrase', 'text_phrase'),
+ array('wildcard', 'wildcard'),
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider getQueryTypes
+ * @covers \Elastica\Query\Builder::fieldClose
+ * @covers \Elastica\Query\Builder::close
+ * @covers \Elastica\Query\Builder::bool
+ * @covers \Elastica\Query\Builder::boolClose
+ * @covers \Elastica\Query\Builder::constantScore
+ * @covers \Elastica\Query\Builder::constantScoreClose
+ * @covers \Elastica\Query\Builder::disMax
+ * @covers \Elastica\Query\Builder::disMaxClose
+ * @covers \Elastica\Query\Builder::facets
+ * @covers \Elastica\Query\Builder::facetsClose
+ * @covers \Elastica\Query\Builder::filter
+ * @covers \Elastica\Query\Builder::filterClose
+ * @covers \Elastica\Query\Builder::filteredQuery
+ * @covers \Elastica\Query\Builder::filteredQueryClose
+ * @covers \Elastica\Query\Builder::must
+ * @covers \Elastica\Query\Builder::mustClose
+ * @covers \Elastica\Query\Builder::mustNot
+ * @covers \Elastica\Query\Builder::mustNotClose
+ * @covers \Elastica\Query\Builder::prefix
+ * @covers \Elastica\Query\Builder::prefixClose
+ * @covers \Elastica\Query\Builder::query
+ * @covers \Elastica\Query\Builder::queryClose
+ * @covers \Elastica\Query\Builder::queryString
+ * @covers \Elastica\Query\Builder::queryStringClose
+ * @covers \Elastica\Query\Builder::range
+ * @covers \Elastica\Query\Builder::rangeClose
+ * @covers \Elastica\Query\Builder::should
+ * @covers \Elastica\Query\Builder::shouldClose
+ * @covers \Elastica\Query\Builder::sort
+ * @covers \Elastica\Query\Builder::sortClose
+ * @covers \Elastica\Query\Builder::term
+ * @covers \Elastica\Query\Builder::termClose
+ * @covers \Elastica\Query\Builder::textPhrase
+ * @covers \Elastica\Query\Builder::textPhraseClose
+ * @covers \Elastica\Query\Builder::wildcard
+ * @covers \Elastica\Query\Builder::wildcardClose
+ */
+ public function testQueryTypes($method, $queryType)
+ {
+ $builder = new Builder();
+ $this->assertSame($builder, $builder->$method()); // open
+ $this->assertSame($builder, $builder->{$method.'Close'}()); // close
+ $this->assertSame('{"'.$queryType.'":{}}', (string) $builder);
+ }
+
+ /**
+ * @group unit
+ * @covers \Elastica\Query\Builder::fieldOpen
+ * @covers \Elastica\Query\Builder::fieldClose
+ * @covers \Elastica\Query\Builder::open
+ * @covers \Elastica\Query\Builder::close
+ */
+ public function testFieldOpenAndClose()
+ {
+ $builder = new Builder();
+ $this->assertSame($builder, $builder->fieldOpen('someField'));
+ $this->assertSame($builder, $builder->fieldClose());
+ $this->assertSame('{"someField":{}}', (string) $builder);
+ }
+
+ /**
+ * @group unit
+ * @covers \Elastica\Query\Builder::sortField
+ */
+ public function testSortField()
+ {
+ $builder = new Builder();
+ $this->assertSame($builder, $builder->sortField('name', true));
+ $this->assertSame('{"sort":{"name":{"reverse":"true"}}}', (string) $builder);
+ }
+
+ /**
+ * @group unit
+ * @covers \Elastica\Query\Builder::sortFields
+ */
+ public function testSortFields()
+ {
+ $builder = new Builder();
+ $this->assertSame($builder, $builder->sortFields(array('field1' => 'asc', 'field2' => 'desc', 'field3' => 'asc')));
+ $this->assertSame('{"sort":[{"field1":"asc"},{"field2":"desc"},{"field3":"asc"}]}', (string) $builder);
+ }
+
+ /**
+ * @group unit
+ * @covers \Elastica\Query\Builder::queries
+ */
+ public function testQueries()
+ {
+ $queries = array();
+
+ $builder = new Builder();
+ $b1 = clone $builder;
+ $b2 = clone $builder;
+
+ $queries[] = $b1->term()->field('age', 34)->termClose();
+ $queries[] = $b2->term()->field('name', 'christer')->termClose();
+
+ $this->assertSame($builder, $builder->queries($queries));
+ $this->assertSame('{"queries":[{"term":{"age":"34"}},{"term":{"name":"christer"}}]}', (string) $builder);
+ }
+
+ public function getFieldData()
+ {
+ return array(
+ array('name', 'value', '{"name":"value"}'),
+ array('name', true, '{"name":"true"}'),
+ array('name', false, '{"name":"false"}'),
+ array('name', array(1, 2, 3), '{"name":["1","2","3"]}'),
+ array('name', array('foo', 'bar', 'baz'), '{"name":["foo","bar","baz"]}'),
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider getFieldData
+ * @covers \Elastica\Query\Builder::field
+ */
+ public function testField($name, $value, $result)
+ {
+ $builder = new Builder();
+ $this->assertSame($builder, $builder->field($name, $value));
+ $this->assertSame($result, (string) $builder);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ * @expectedExceptionMessage The produced query is not a valid json string : "{{}"
+ * @covers \Elastica\Query\Builder::toArray
+ */
+ public function testToArrayWithInvalidData()
+ {
+ $builder = new Builder();
+ $builder->open('foo');
+ $builder->toArray();
+ }
+
+ /**
+ * @group unit
+ * @covers \Elastica\Query\Builder::toArray
+ */
+ public function testToArray()
+ {
+ $builder = new Builder();
+ $builder->query()->term()->field('category.id', array(1, 2, 3))->termClose()->queryClose();
+ $expected = array(
+ 'query' => array(
+ 'term' => array(
+ 'category.id' => array(1, 2, 3),
+ ),
+ ),
+ );
+ $this->assertEquals($expected, $builder->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/CommonTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/CommonTest.php
new file mode 100644
index 00000000..016213a8
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/CommonTest.php
@@ -0,0 +1,63 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Common;
+use Elastica\Test\Base as BaseTest;
+
+class CommonTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new Common('body', 'test query', .001);
+ $query->setLowFrequencyOperator(Common::OPERATOR_AND);
+
+ $expected = array(
+ 'common' => array(
+ 'body' => array(
+ 'query' => 'test query',
+ 'cutoff_frequency' => .001,
+ 'low_freq_operator' => 'and',
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $docs = array(
+ new Document(1, array('body' => 'foo baz')),
+ new Document(2, array('body' => 'foo bar baz')),
+ new Document(3, array('body' => 'foo bar baz bat')),
+ );
+ //add documents to create common terms
+ for ($i = 4; $i < 24; $i++) {
+ $docs[] = new Document($i, array('body' => 'foo bar'));
+ }
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $query = new Common('body', 'foo bar baz bat', .5);
+ $results = $type->search($query)->getResults();
+
+ //documents containing only common words should not be returned
+ $this->assertEquals(3, sizeof($results));
+
+ $query->setMinimumShouldMatch(2);
+ $results = $type->search($query);
+
+ //only the document containing both low frequency terms should match
+ $this->assertEquals(1, $results->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ConstantScoreTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ConstantScoreTest.php
new file mode 100644
index 00000000..a3a213b9
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ConstantScoreTest.php
@@ -0,0 +1,162 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Filter\Ids;
+use Elastica\Filter\Term;
+use Elastica\Index;
+use Elastica\Query\ConstantScore;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+
+class ConstantScoreTest extends BaseTest
+{
+ public function dataProviderSampleQueries()
+ {
+ return array(
+ array(
+ new Term(array('foo', 'bar')),
+ array(
+ 'constant_score' => array(
+ 'filter' => array(
+ 'term' => array(
+ 'foo',
+ 'bar',
+ ),
+ ),
+ ),
+ ),
+ ),
+ array(
+ array(
+ 'and' => array(
+ array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'foo',
+ 'default_field' => 'something',
+ ),
+ ),
+ ),
+ array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'bar',
+ 'default_field' => 'something',
+ ),
+ ),
+ ),
+ ),
+ ),
+ '{"constant_score":{"filter":{"and":[{"query":{"query_string":{"query":"foo","default_field":"something"}}},{"query":{"query_string":{"query":"bar","default_field":"something"}}}]}}}',
+ ),
+ );
+ }
+ /**
+ * @group unit
+ * @dataProvider dataProviderSampleQueries
+ */
+ public function testSimple($filter, $expected)
+ {
+ $query = new ConstantScore();
+ $query->setFilter($filter);
+ if (is_string($expected)) {
+ $expected = json_decode($expected, true);
+ }
+ $this->assertEquals($expected, $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new ConstantScore();
+
+ $boost = 1.2;
+ $filter = new Ids();
+ $filter->setIds(array(1));
+
+ $query->setFilter($filter);
+ $query->setBoost($boost);
+
+ $expectedArray = array(
+ 'constant_score' => array(
+ 'filter' => $filter->toArray(),
+ 'boost' => $boost,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $filter = new Ids();
+ $filter->setIds(array(1));
+
+ $query = new ConstantScore($filter);
+
+ $expectedArray = array(
+ 'constant_score' => array(
+ 'filter' => $filter->toArray(),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $index = $this->_createIndex();
+
+ $type = $index->getType('constant_score');
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'email' => 'hans@test.com', 'username' => 'hans')),
+ new Document(2, array('id' => 2, 'email' => 'emil@test.com', 'username' => 'emil')),
+ new Document(3, array('id' => 3, 'email' => 'ruth@test.com', 'username' => 'ruth')),
+ ));
+
+ // Refresh index
+ $index->refresh();
+
+ $boost = 1.3;
+ $query_match = new MatchAll();
+
+ $query = new ConstantScore();
+ $query->setQuery($query_match);
+ $query->setBoost($boost);
+
+ $expectedArray = array(
+ 'constant_score' => array(
+ 'query' => $query_match->toArray(),
+ 'boost' => $boost,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ $resultSet = $type->search($query);
+
+ $results = $resultSet->getResults();
+
+ $this->assertEquals($resultSet->count(), 3);
+ $this->assertEquals($results[1]->getScore(), 1);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstructEmpty()
+ {
+ $query = new ConstantScore();
+ $expectedArray = array('constant_score' => array());
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/DisMaxTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/DisMaxTest.php
new file mode 100644
index 00000000..2c128018
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/DisMaxTest.php
@@ -0,0 +1,84 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\DisMax;
+use Elastica\Query\Ids;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+
+class DisMaxTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new DisMax();
+
+ $idsQuery1 = new Ids();
+ $idsQuery1->setIds(1);
+
+ $idsQuery2 = new Ids();
+ $idsQuery2->setIds(2);
+
+ $idsQuery3 = new Ids();
+ $idsQuery3->setIds(3);
+
+ $boost = 1.2;
+ $tieBreaker = 2;
+
+ $query->setBoost($boost);
+ $query->setTieBreaker($tieBreaker);
+ $query->addQuery($idsQuery1);
+ $query->addQuery($idsQuery2);
+ $query->addQuery($idsQuery3->toArray());
+
+ $expectedArray = array(
+ 'dis_max' => array(
+ 'tie_breaker' => $tieBreaker,
+ 'boost' => $boost,
+ 'queries' => array(
+ $idsQuery1->toArray(),
+ $idsQuery2->toArray(),
+ $idsQuery3->toArray(),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ ));
+
+ $index->refresh();
+
+ $queryString1 = new QueryString('Bade*');
+ $queryString2 = new QueryString('Base*');
+
+ $boost = 1.2;
+ $tieBreaker = 2;
+
+ $query = new DisMax();
+ $query->setBoost($boost);
+ $query->setTieBreaker($tieBreaker);
+ $query->addQuery($queryString1);
+ $query->addQuery($queryString2);
+ $resultSet = $type->search($query);
+
+ $this->assertEquals(3, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/EscapeStringTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/EscapeStringTest.php
new file mode 100644
index 00000000..536a7bb3
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/EscapeStringTest.php
@@ -0,0 +1,36 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Util;
+
+class EscapeStringTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $index = $this->_createIndex();
+ $index->getSettings()->setNumberOfReplicas(0);
+
+ $type = new Type($index, 'helloworld');
+
+ $doc = new Document(1, array(
+ 'email' => 'test@test.com', 'username' => 'test 7/6 123', 'test' => array('2', '3', '5'), )
+ );
+ $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $queryString = new QueryString(Util::escapeTerm('test 7/6'));
+ $resultSet = $type->search($queryString);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FilteredTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FilteredTest.php
new file mode 100644
index 00000000..c4bea6f2
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FilteredTest.php
@@ -0,0 +1,124 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Filter\Term;
+use Elastica\Query\Filtered;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+
+class FilteredTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testFilteredSearch()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('helloworld');
+
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'hanswurst', 'test' => array('2', '3', '5'))),
+ new Document(2, array('id' => 2, 'email' => 'test@test.com', 'username' => 'peter', 'test' => array('2', '3', '5'))),
+ ));
+
+ $queryString = new QueryString('test*');
+
+ $filter1 = new Term();
+ $filter1->setTerm('username', 'peter');
+
+ $filter2 = new Term();
+ $filter2->setTerm('username', 'qwerqwer');
+
+ $query1 = new Filtered($queryString, $filter1);
+ $query2 = new Filtered($queryString, $filter2);
+ $index->refresh();
+
+ $resultSet = $type->search($queryString);
+ $this->assertEquals(2, $resultSet->count());
+
+ $resultSet = $type->search($query1);
+ $this->assertEquals(1, $resultSet->count());
+
+ $resultSet = $type->search($query2);
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFilteredGetter()
+ {
+ $queryString = new QueryString('test*');
+
+ $filter1 = new Term();
+ $filter1->setTerm('username', 'peter');
+
+ $filter2 = new Term();
+ $filter2->setTerm('username', 'qwerqwer');
+
+ $query1 = new Filtered($queryString, $filter1);
+ $query2 = new Filtered($queryString, $filter2);
+
+ $this->assertEquals($query1->getQuery(), $queryString);
+ $this->assertEquals($query2->getQuery(), $queryString);
+ $this->assertEquals($query1->getFilter(), $filter1);
+ $this->assertEquals($query2->getFilter(), $filter2);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testFilteredWithoutArgumentsShouldRaiseException()
+ {
+ $query = new Filtered();
+ $query->toArray();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilteredSearchNoQuery()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('helloworld');
+
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'hanswurst', 'test' => array('2', '3', '5'))),
+ new Document(2, array('id' => 2, 'email' => 'test@test.com', 'username' => 'peter', 'test' => array('2', '3', '5'))),
+ ));
+
+ $index->refresh();
+
+ $filter = new Term();
+ $filter->setTerm('username', 'peter');
+
+ $query = new Filtered(null, $filter);
+
+ $resultSet = $type->search($query);
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFilteredSearchNoFilter()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'hanswurst', 'test' => array('2', '3', '5')));
+ $type->addDocument($doc);
+ $doc = new Document(2, array('id' => 2, 'email' => 'test@test.com', 'username' => 'peter', 'test' => array('2', '3', '5')));
+ $type->addDocument($doc);
+
+ $queryString = new QueryString('hans*');
+
+ $query = new Filtered($queryString);
+ $index->refresh();
+
+ $resultSet = $type->search($query);
+ $this->assertEquals(1, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FunctionScoreTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FunctionScoreTest.php
new file mode 100644
index 00000000..25600034
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FunctionScoreTest.php
@@ -0,0 +1,324 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Filter\Term;
+use Elastica\Query\FunctionScore;
+use Elastica\Query\MatchAll;
+use Elastica\Script;
+use Elastica\Test\Base as BaseTest;
+
+class FunctionScoreTest extends BaseTest
+{
+ protected $locationOrigin = '32.804654, -117.242594';
+
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->setMapping(array(
+ 'name' => array('type' => 'string', 'index' => 'not_analyzed'),
+ 'location' => array('type' => 'geo_point'),
+ 'price' => array('type' => 'float'),
+ ));
+
+ $type->addDocuments(array(
+ new Document(1, array(
+ 'name' => "Mr. Frostie's",
+ 'location' => array('lat' => 32.799605, 'lon' => -117.243027),
+ 'price' => 4.5,
+ )),
+ new Document(2, array(
+ 'name' => "Miller's Field",
+ 'location' => array('lat' => 32.795964, 'lon' => -117.255028),
+ 'price' => 9.5,
+ )),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $priceOrigin = 0;
+ $locationScale = '2mi';
+ $priceScale = 9.25;
+ $query = new FunctionScore();
+ $childQuery = new MatchAll();
+ $query->setQuery($childQuery);
+ $query->addDecayFunction(FunctionScore::DECAY_GAUSS, 'location', $this->locationOrigin, $locationScale);
+ $query->addDecayFunction(FunctionScore::DECAY_GAUSS, 'price', $priceOrigin, $priceScale);
+ $expected = array(
+ 'function_score' => array(
+ 'query' => $childQuery->toArray(),
+ 'functions' => array(
+ array(
+ 'gauss' => array(
+ 'location' => array(
+ 'origin' => $this->locationOrigin,
+ 'scale' => $locationScale,
+ ),
+ ),
+ ),
+ array(
+ 'gauss' => array(
+ 'price' => array(
+ 'origin' => $priceOrigin,
+ 'scale' => $priceScale,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ $this->assertEquals($expected, $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testDecayWeight()
+ {
+ $priceOrigin = 0;
+ $locationScale = '2mi';
+ $priceScale = 9.25;
+ $query = new FunctionScore();
+ $childQuery = new MatchAll();
+ $query->setQuery($childQuery);
+ $query->addDecayFunction(
+ FunctionScore::DECAY_GAUSS,
+ 'location',
+ $this->locationOrigin,
+ $locationScale,
+ null,
+ null,
+ .5
+ );
+ $query->addDecayFunction(FunctionScore::DECAY_GAUSS, 'price', $priceOrigin, $priceScale, null, null, 2);
+ $expected = array(
+ 'function_score' => array(
+ 'query' => $childQuery->toArray(),
+ 'functions' => array(
+ array(
+ 'gauss' => array(
+ 'location' => array(
+ 'origin' => $this->locationOrigin,
+ 'scale' => $locationScale,
+ ),
+ ),
+ 'weight' => .5,
+ ),
+ array(
+ 'gauss' => array(
+ 'price' => array(
+ 'origin' => $priceOrigin,
+ 'scale' => $priceScale,
+ ),
+ ),
+ 'weight' => 2,
+ ),
+ ),
+ ),
+ );
+ $this->assertEquals($expected, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGauss()
+ {
+ $query = new FunctionScore();
+ $query->addDecayFunction(FunctionScore::DECAY_GAUSS, 'location', $this->locationOrigin, '4mi');
+ $query->addDecayFunction(FunctionScore::DECAY_GAUSS, 'price', 0, 10);
+ $response = $this->_getIndexForTest()->search($query);
+ $results = $response->getResults();
+
+ // the document with the closest location and lowest price should be scored highest
+ $result0 = $results[0]->getData();
+ $this->assertEquals("Mr. Frostie's", $result0['name']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWeight()
+ {
+ $filter = new Term(array('price' => 4.5));
+ $query = new FunctionScore();
+ $query->addBoostFactorFunction(5.0, $filter);
+ $expected = array(
+ 'function_score' => array(
+ 'functions' => array(
+ array(
+ 'weight' => 5.0,
+ 'filter' => array(
+ 'term' => array(
+ 'price' => 4.5,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $query->toArray());
+
+ $response = $this->_getIndexForTest()->search($query);
+ $results = $response->getResults();
+
+ // the document with price = 4.5 should be scored highest
+ $result0 = $results[0]->getData();
+ $this->assertEquals("Mr. Frostie's", $result0['name']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testRandomScore()
+ {
+ $filter = new Term(array('price' => 4.5));
+ $query = new FunctionScore();
+ $query->addRandomScoreFunction(2, $filter);
+ $expected = array(
+ 'function_score' => array(
+ 'functions' => array(
+ array(
+ 'random_score' => array(
+ 'seed' => 2,
+ ),
+ 'filter' => array(
+ 'term' => array(
+ 'price' => 4.5,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $query->toArray());
+
+ $response = $this->_getIndexForTest()->search($query);
+ $results = $response->getResults();
+
+ // the document with the random score should have a score > 1, means it is the first result
+ $result0 = $results[0]->getData();
+
+ $this->assertEquals("Miller's Field", $result0['name']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testRandomScoreWeight()
+ {
+ $filter = new Term(array('price' => 4.5));
+ $query = new FunctionScore();
+ $query->addRandomScoreFunction(2, $filter, 2);
+ $expected = array(
+ 'function_score' => array(
+ 'functions' => array(
+ array(
+ 'random_score' => array(
+ 'seed' => 2,
+ ),
+ 'filter' => array(
+ 'term' => array(
+ 'price' => 4.5,
+ ),
+ ),
+ 'weight' => 2,
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testRandomScoreWithoutSeed()
+ {
+ $query = new FunctionScore();
+ $query->setRandomScore();
+
+ $response = $this->_getIndexForTest()->search($query);
+
+ $this->assertEquals(2, $response->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testScriptScore()
+ {
+ $scriptString = "_score * doc['price'].value";
+ $script = new Script($scriptString);
+ $query = new FunctionScore();
+ $query->addScriptScoreFunction($script);
+ $expected = array(
+ 'function_score' => array(
+ 'functions' => array(
+ array(
+ 'script_score' => array(
+ 'script' => $scriptString,
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $query->toArray());
+
+ $response = $this->_getIndexForTest()->search($query);
+ $results = $response->getResults();
+
+ // the document the highest price should be scored highest
+ $result0 = $results[0]->getData();
+ $this->assertEquals("Miller's Field", $result0['name']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetMinScore()
+ {
+ $expected = array(
+ 'function_score' => array(
+ 'min_score' => 0.8,
+ 'functions' => array(
+ array(
+ 'gauss' => array(
+ 'price' => array(
+ 'origin' => 0,
+ 'scale' => 10,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $query = new FunctionScore();
+ $query->addDecayFunction(FunctionScore::DECAY_GAUSS, 'price', 0, 10);
+ $returnedValue = $query->setMinScore(0.8);
+
+ $this->assertEquals($expected, $query->toArray());
+ $this->assertInstanceOf('Elastica\Query\FunctionScore', $returnedValue);
+
+ $response = $this->_getIndexForTest()->search($query);
+ $results = $response->getResults();
+
+ $this->assertCount(1, $results);
+ $this->assertEquals(1, $results[0]->getId());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyLikeThisTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyLikeThisTest.php
new file mode 100644
index 00000000..fe11e788
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyLikeThisTest.php
@@ -0,0 +1,300 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query\FuzzyLikeThis;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Type\Mapping;
+
+class FuzzyLikeThisTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test');
+ $index->create(array(), true);
+ $index->getSettings()->setNumberOfReplicas(0);
+ //$index->getSettings()->setNumberOfShards(1);
+
+ $type = new Type($index, 'helloworldfuzzy');
+ $mapping = new Mapping($type, array(
+ 'email' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ 'content' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ ));
+
+ $mapping->setSource(array('enabled' => false));
+ $type->setMapping($mapping);
+
+ $doc = new Document(1000, array('email' => 'testemail@gmail.com', 'content' => 'This is a sample post. Hello World Fuzzy Like This!'));
+ $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $fltQuery = new FuzzyLikeThis();
+ $fltQuery->setLikeText('sample gmail');
+ $fltQuery->addFields(array('email', 'content'));
+ $fltQuery->setMinSimilarity(0.3);
+ $fltQuery->setMaxQueryTerms(3);
+ $resultSet = $type->search($fltQuery);
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetPrefixLength()
+ {
+ $query = new FuzzyLikeThis();
+
+ $length = 3;
+ $query->setPrefixLength($length);
+
+ $data = $query->toArray();
+
+ $this->assertEquals($length, $data['fuzzy_like_this']['prefix_length']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddFields()
+ {
+ $query = new FuzzyLikeThis();
+
+ $fields = array('test1', 'test2');
+ $query->addFields($fields);
+
+ $data = $query->toArray();
+
+ $this->assertEquals($fields, $data['fuzzy_like_this']['fields']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetLikeText()
+ {
+ $query = new FuzzyLikeThis();
+
+ $text = ' hello world';
+ $query->setLikeText($text);
+
+ $data = $query->toArray();
+
+ $this->assertEquals(trim($text), $data['fuzzy_like_this']['like_text']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetIgnoreTF()
+ {
+ $query = new FuzzyLikeThis();
+
+ $ignoreTF = false;
+ $query->setIgnoreTF($ignoreTF);
+ $data = $query->toArray();
+ $this->assertEquals($ignoreTF, $data['fuzzy_like_this']['ignore_tf']);
+
+ $ignoreTF = true;
+ $query->setIgnoreTF($ignoreTF);
+ $data = $query->toArray();
+ $this->assertEquals($ignoreTF, $data['fuzzy_like_this']['ignore_tf']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetIgnoreTFDefault()
+ {
+ $query = new FuzzyLikeThis();
+
+ $data = $query->toArray();
+
+ $defaultIgnoreTF = false;
+ $this->assertEquals($defaultIgnoreTF, $data['fuzzy_like_this']['ignore_tf']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMinSimilarity()
+ {
+ $query = new FuzzyLikeThis();
+
+ $similarity = 2;
+ $query->setMinSimilarity($similarity);
+
+ $data = $query->toArray();
+
+ $this->assertEquals($similarity, $data['fuzzy_like_this']['min_similarity']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetBoost()
+ {
+ $query = new FuzzyLikeThis();
+
+ $boost = 2.2;
+ $query->setBoost($boost);
+
+ $data = $query->toArray();
+
+ $this->assertEquals($boost, $data['fuzzy_like_this']['boost']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddAnalyzerViasetParam()
+ {
+ $analyzer = 'snowball';
+
+ $query = new FuzzyLikeThis();
+ $query->setParam('analyzer', $analyzer);
+
+ $data = $query->toArray();
+ $this->assertEquals($analyzer, $data['fuzzy_like_this']['analyzer']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetAnalyzer()
+ {
+ $analyzer = 'snowball';
+
+ $query = new FuzzyLikeThis();
+ $query->setAnalyzer($analyzer);
+
+ $data = $query->toArray();
+ $this->assertEquals($analyzer, $data['fuzzy_like_this']['analyzer']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAnalyzerNotPresentInArrayToMaintainDefaultOfField()
+ {
+ $query = new FuzzyLikeThis();
+
+ $data = $query->toArray();
+ $this->assertArrayNotHasKey('analyzer', $data);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testArgArrayFieldsOverwrittenBySetParams()
+ {
+ $query = new FuzzyLikeThis();
+ $query->setMaxQueryTerms(100);
+ $query->setParam('max_query_terms', 200);
+
+ $data = $query->toArray();
+ $this->assertEquals(200, $data['fuzzy_like_this']['max_query_terms']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchSetAnalyzer()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test');
+ $index->create(array('analysis' => array(
+ 'analyzer' => array(
+ 'searchAnalyzer' => array(
+ 'type' => 'custom',
+ 'tokenizer' => 'standard',
+ 'filter' => array('myStopWords'),
+ ),
+ ),
+ 'filter' => array(
+ 'myStopWords' => array(
+ 'type' => 'stop',
+ 'stopwords' => array('The'),
+ ),
+ ),
+ )), true);
+
+ $index->getSettings()->setNumberOfReplicas(0);
+ //$index->getSettings()->setNumberOfShards(1);
+
+ $type = new Type($index, 'helloworldfuzzy');
+ $mapping = new Mapping($type, array(
+ 'email' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ 'content' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ ));
+
+ $mapping->setSource(array('enabled' => false));
+ $type->setMapping($mapping);
+
+ $type->addDocuments(array(
+ new Document(1000, array('email' => 'testemail@gmail.com', 'content' => 'The Fuzzy Test!')),
+ new Document(1001, array('email' => 'testemail@gmail.com', 'content' => 'Elastica Fuzzy Test')),
+ ));
+
+ // Refresh index
+ $index->refresh();
+
+ $fltQuery = new FuzzyLikeThis();
+ $fltQuery->addFields(array('email', 'content'));
+ $fltQuery->setLikeText('The');
+
+ $fltQuery->setMinSimilarity(0.1);
+ $fltQuery->setMaxQueryTerms(3);
+
+ // Test before analyzer applied, should return 1 result
+ $resultSet = $type->search($fltQuery);
+ $this->assertEquals(1, $resultSet->count());
+
+ $fltQuery->setParam('analyzer', 'searchAnalyzer');
+
+ $resultSet = $type->search($fltQuery);
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testNoLikeTextProvidedShouldReturnNoResults()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test');
+ $index->create(array(), true);
+ $index->getSettings()->setNumberOfReplicas(0);
+
+ $type = new Type($index, 'helloworldfuzzy');
+ $mapping = new Mapping($type, array(
+ 'email' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ 'content' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ ));
+
+ $mapping->setSource(array('enabled' => false));
+ $type->setMapping($mapping);
+
+ $doc = new Document(1000, array('email' => 'testemail@gmail.com', 'content' => 'This is a sample post. Hello World Fuzzy Like This!'));
+ $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $fltQuery = new FuzzyLikeThis();
+ $fltQuery->setLikeText('');
+ $fltQuery->addFields(array('email', 'content'));
+ $fltQuery->setMinSimilarity(0.3);
+ $fltQuery->setMaxQueryTerms(3);
+ $resultSet = $type->search($fltQuery);
+
+ $this->assertEquals(0, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyTest.php
new file mode 100644
index 00000000..e9107232
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/FuzzyTest.php
@@ -0,0 +1,136 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Fuzzy;
+use Elastica\Test\Base as BaseTest;
+
+class FuzzyTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $fuzzy = new Fuzzy();
+ $fuzzy->addField('user', array('value' => 'Nicolas', 'boost' => 1.0));
+ $expectedArray = array(
+ 'fuzzy' => array(
+ 'user' => array(
+ 'value' => 'Nicolas',
+ 'boost' => 1.0,
+ ),
+ ),
+ );
+ $this->assertEquals($expectedArray, $fuzzy->toArray(), 'Deprecated method failed');
+
+ $fuzzy = new Fuzzy('user', 'Nicolas');
+ $expectedArray = array(
+ 'fuzzy' => array(
+ 'user' => array(
+ 'value' => 'Nicolas',
+ ),
+ ),
+ );
+ $this->assertEquals($expectedArray, $fuzzy->toArray());
+
+ $fuzzy = new Fuzzy();
+ $fuzzy->setField('user', 'Nicolas')->setFieldOption('boost', 1.0);
+ $expectedArray = array(
+ 'fuzzy' => array(
+ 'user' => array(
+ 'value' => 'Nicolas',
+ 'boost' => 1.0,
+ ),
+ ),
+ );
+ $this->assertEquals($expectedArray, $fuzzy->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+
+ $query = new Fuzzy();
+ $query->setField($field, 'Baden');
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testBadArguments()
+ {
+ $this->setExpectedException('Elastica\Exception\InvalidException');
+ $query = new Fuzzy();
+ $query->addField('name', array(array('value' => 'Baden')));
+
+ $this->setExpectedException('Elastica\Exception\InvalidException');
+ $query = new Fuzzy();
+ $query->setField('name', array());
+
+ $this->setExpectedException('Elastica\Exception\InvalidException');
+ $query = new Fuzzy();
+ $query->setField('name', 'value');
+ $query->setField('name1', 'value1');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFuzzyWithFacets()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+
+ $fuzzyQuery = new Fuzzy();
+ $fuzzyQuery->setField($field, 'Baden');
+
+ $facet = new \Elastica\Facet\Terms('test');
+ $facet->setField('name');
+
+ $query = new \Elastica\Query($fuzzyQuery);
+ $query->addFacet($facet);
+
+ $resultSet = $index->search($query);
+
+ // Assert query worked ok
+ $this->assertEquals(2, $resultSet->count());
+
+ // Check Facets
+ $this->assertTrue($resultSet->hasFacets());
+ $facets = $resultSet->getFacets();
+ $this->assertEquals(2, $facets['test']['total']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasChildTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasChildTest.php
new file mode 100644
index 00000000..a717b1ab
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasChildTest.php
@@ -0,0 +1,117 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Query\HasChild;
+use Elastica\Query\Match;
+use Elastica\Query\MatchAll;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class HasChildTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $q = new MatchAll();
+
+ $type = 'test';
+
+ $query = new HasChild($q, $type);
+
+ $expectedArray = array(
+ 'has_child' => array(
+ 'query' => $q->toArray(),
+ 'type' => $type,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScope()
+ {
+ $q = new MatchAll();
+
+ $type = 'test';
+
+ $scope = 'foo';
+
+ $query = new HasChild($q, $type);
+ $query->setScope($scope);
+
+ $expectedArray = array(
+ 'has_child' => array(
+ 'query' => $q->toArray(),
+ 'type' => $type,
+ '_scope' => $scope,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testTypeInsideHasChildSearch()
+ {
+ $index = $this->_getTestIndex();
+
+ $f = new Match();
+ $f->setField('alt.name', 'testname');
+ $query = new HasChild($f, 'child');
+
+ $searchQuery = new Query();
+ $searchQuery->setQuery($query);
+ $searchResults = $index->search($searchQuery);
+
+ $this->assertEquals(1, $searchResults->count());
+
+ $result = $searchResults->current()->getData();
+ $expected = array('id' => 'parent2', 'user' => 'parent2', 'email' => 'parent2@test.com');
+
+ $this->assertEquals($expected, $result);
+ }
+
+ protected function _getTestIndex()
+ {
+ $index = $this->_createIndex('has_child_test');
+
+ $parentType = $index->getType('parent');
+
+ $childType = $index->getType('child');
+ $childMapping = new Mapping($childType);
+ $childMapping->setParent('parent');
+ $childMapping->send();
+
+ $altType = $index->getType('alt');
+ $altDoc = new Document('alt1', array('name' => 'altname'));
+ $altType->addDocument($altDoc);
+
+ $parent1 = new Document('parent1', array('id' => 'parent1', 'user' => 'parent1', 'email' => 'parent1@test.com'));
+ $parentType->addDocument($parent1);
+ $parent2 = new Document('parent2', array('id' => 'parent2', 'user' => 'parent2', 'email' => 'parent2@test.com'));
+ $parentType->addDocument($parent2);
+
+ $child1 = new Document('child1', array('id' => 'child1', 'user' => 'child1', 'email' => 'child1@test.com'));
+ $child1->setParent('parent1');
+ $childType->addDocument($child1);
+ $child2 = new Document('child2', array('id' => 'child2', 'user' => 'child2', 'email' => 'child2@test.com'));
+ $child2->setParent('parent2');
+ $childType->addDocument($child2);
+ $child3 = new Document('child3', array('id' => 'child3', 'user' => 'child3', 'email' => 'child3@test.com', 'alt' => array(array('name' => 'testname'))));
+ $child3->setParent('parent2');
+ $childType->addDocument($child3);
+
+ $index->refresh();
+
+ return $index;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasParentTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasParentTest.php
new file mode 100644
index 00000000..31a89852
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HasParentTest.php
@@ -0,0 +1,108 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\HasParent;
+use Elastica\Query\Match;
+use Elastica\Query\MatchAll;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class HasParentTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $q = new MatchAll();
+
+ $type = 'test';
+
+ $query = new HasParent($q, $type);
+
+ $expectedArray = array(
+ 'has_parent' => array(
+ 'query' => $q->toArray(),
+ 'type' => $type,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScope()
+ {
+ $q = new MatchAll();
+
+ $type = 'test';
+
+ $scope = 'foo';
+
+ $query = new HasParent($q, $type);
+ $query->setScope($scope);
+
+ $expectedArray = array(
+ 'has_parent' => array(
+ 'query' => $q->toArray(),
+ 'type' => $type,
+ '_scope' => $scope,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testHasParent()
+ {
+ $index = $this->_createIndex();
+
+ $shopType = $index->getType('shop');
+ $productType = $index->getType('product');
+ $mapping = new Mapping();
+ $mapping->setParent('shop');
+ $productType->setMapping($mapping);
+
+ $shopType->addDocuments(
+ array(
+ new Document('zurich', array('brand' => 'google')),
+ new Document('london', array('brand' => 'apple')),
+ )
+ );
+
+ $doc1 = new Document(1, array('device' => 'chromebook'));
+ $doc1->setParent('zurich');
+
+ $doc2 = new Document(2, array('device' => 'macmini'));
+ $doc2->setParent('london');
+
+ $productType->addDocument($doc1);
+ $productType->addDocument($doc2);
+
+ $index->refresh();
+
+ // All documents
+ $parentQuery = new HasParent(new MatchAll(), $shopType->getName());
+ $search = new Search($index->getClient());
+ $results = $search->search($parentQuery);
+ $this->assertEquals(2, $results->count());
+
+ $match = new Match();
+ $match->setField('brand', 'google');
+
+ $parentQuery = new HasParent($match, $shopType->getName());
+ $search = new Search($index->getClient());
+ $results = $search->search($parentQuery);
+ $this->assertEquals(1, $results->count());
+ $result = $results->current();
+ $data = $result->getData();
+ $this->assertEquals($data['device'], 'chromebook');
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HighlightTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HighlightTest.php
new file mode 100644
index 00000000..c6850019
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/HighlightTest.php
@@ -0,0 +1,48 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+
+class HighlightTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testHightlightSearch()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('helloworld');
+
+ $phrase = 'My name is ruflin';
+
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'phrase' => $phrase, 'username' => 'hanswurst', 'test' => array('2', '3', '5'))),
+ new Document(2, array('id' => 2, 'phrase' => $phrase, 'username' => 'peter', 'test' => array('2', '3', '5'))),
+ ));
+
+ $queryString = new QueryString('rufl*');
+ $query = new Query($queryString);
+ $query->setHighlight(array(
+ 'pre_tags' => array('<em class="highlight">'),
+ 'post_tags' => array('</em>'),
+ 'fields' => array(
+ 'phrase' => array(
+ 'fragment_size' => 200,
+ 'number_of_fragments' => 1,
+ ),
+ ),
+ ));
+
+ $index->refresh();
+
+ $resultSet = $type->search($query);
+ foreach ($resultSet as $result) {
+ $highlight = $result->getHighlights();
+ $this->assertEquals(array('phrase' => array(0 => 'My name is <em class="highlight">ruflin</em>')), $highlight);
+ }
+ $this->assertEquals(2, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/IdsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/IdsTest.php
new file mode 100644
index 00000000..7b39020f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/IdsTest.php
@@ -0,0 +1,187 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Ids;
+use Elastica\Test\Base as BaseTest;
+
+class IdsTest extends BaseTest
+{
+ protected $_index;
+ protected $_type;
+
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $index = $this->_createIndex();
+
+ $type1 = $index->getType('helloworld1');
+ $type2 = $index->getType('helloworld2');
+
+ $doc = new Document(1, array('name' => 'hello world'));
+ $type1->addDocument($doc);
+
+ $doc = new Document(2, array('name' => 'nicolas ruflin'));
+ $type1->addDocument($doc);
+
+ $doc = new Document(3, array('name' => 'ruflin'));
+ $type1->addDocument($doc);
+
+ $doc = new Document(4, array('name' => 'hello world again'));
+ $type2->addDocument($doc);
+
+ $index->refresh();
+
+ $this->_type = $type1;
+ $this->_index = $index;
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetIdsSearchSingle()
+ {
+ $query = new Ids();
+ $query->setIds('1');
+
+ $resultSet = $this->_type->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetIdsSearchArray()
+ {
+ $query = new Ids();
+ $query->setIds(array('1', '2'));
+
+ $resultSet = $this->_type->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddIdsSearchSingle()
+ {
+ $query = new Ids();
+ $query->addId('3');
+
+ $resultSet = $this->_type->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testComboIdsSearchArray()
+ {
+ $query = new Ids();
+
+ $query->setIds(array('1', '2'));
+ $query->addId('3');
+
+ $resultSet = $this->_type->search($query);
+
+ $this->assertEquals(3, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchSingle()
+ {
+ $query = new Ids();
+
+ $query->setIds('1');
+ $query->setType('helloworld1');
+
+ $resultSet = $this->_index->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchArray()
+ {
+ $query = new Ids();
+
+ $query->setIds(array('1', '2'));
+ $query->setType('helloworld1');
+
+ $resultSet = $this->_index->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchSingleDocInOtherType()
+ {
+ $query = new Ids();
+
+ // Doc 4 is in the second type...
+ $query->setIds('4');
+ $query->setType('helloworld1');
+
+ $resultSet = $this->_index->search($query);
+
+ // ...therefore 0 results should be returned
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeSingleSearchArrayDocInOtherType()
+ {
+ $query = new Ids();
+
+ // Doc 4 is in the second type...
+ $query->setIds(array('1', '4'));
+ $query->setType('helloworld1');
+
+ $resultSet = $this->_index->search($query);
+
+ // ...therefore only 1 result should be returned
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeArraySearchArray()
+ {
+ $query = new Ids();
+
+ $query->setIds(array('1', '4'));
+ $query->setType(array('helloworld1', 'helloworld2'));
+
+ $resultSet = $this->_index->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetTypeArraySearchSingle()
+ {
+ $query = new Ids();
+
+ $query->setIds('4');
+ $query->setType(array('helloworld1', 'helloworld2'));
+
+ $resultSet = $this->_index->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ImageTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ImageTest.php
new file mode 100644
index 00000000..989e4e4a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/ImageTest.php
@@ -0,0 +1,159 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query\Image;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Type\Mapping;
+
+class ImageTest extends BaseTest
+{
+ /**
+ * @var string
+ */
+ protected $_testFileContent;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->_testFileContent = base64_encode(file_get_contents(BASE_PATH.'/data/test.jpg'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArrayFromReference()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test');
+ $type = new Type($index, 'helloworld');
+ $field = 'image';
+
+ $query = new Image();
+ $query->setFieldFeature($field, 'CEDD');
+ $query->setFieldHash($field, 'BIT_SAMPLING');
+ $query->setFieldBoost($field, 100);
+
+ $query->setImageByReference($field, $index->getName(), $type->getName(), 10);
+
+ $jsonString = '{"image":{"image":{"feature":"CEDD","hash":"BIT_SAMPLING","boost":100,"index":"test","type":"helloworld","id":10,"path":"image"}}}';
+ $this->assertEquals($jsonString, json_encode($query->toArray()));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArrayFromImage()
+ {
+ $field = 'image';
+
+ $query = new Image();
+ $query->setFieldFeature($field, 'CEDD');
+ $query->setFieldHash($field, 'BIT_SAMPLING');
+ $query->setFieldBoost($field, 100);
+
+ $query->setFieldImage($field, BASE_PATH.'/data/test.jpg');
+
+ $jsonString = '{"image":{"image":{"feature":"CEDD","hash":"BIT_SAMPLING","boost":100,"image":"\/9j\/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP\/sABFEdWNreQABAAQAAAA8AAD\/4QN6aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI\/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjUtYzAyMSA3OS4xNTQ5MTEsIDIwMTMvMTAvMjktMTE6NDc6MTYgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6OWQ4MjQ5N2MtNzViMS0wYzQ5LTg4ZjMtMDdiNmRhMjU0ZWRhIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjA4NjBGM0Y1QkJGQTExRTM4MjQ0QzMzNjU2MjUxOEJGIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjA4NjBGM0Y0QkJGQTExRTM4MjQ0QzMzNjU2MjUxOEJGIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5ZDgyNDk3Yy03NWIxLTBjNDktODhmMy0wN2I2ZGEyNTRlZGEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OWQ4MjQ5N2MtNzViMS0wYzQ5LTg4ZjMtMDdiNmRhMjU0ZWRhIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+\/+4ADkFkb2JlAGTAAAAAAf\/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoKDBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f\/8AAEQgAZABkAwERAAIRAQMRAf\/EAKwAAAEFAQEBAQAAAAAAAAAAAAgAAwQFBwYCAQkBAQEAAwEBAAAAAAAAAAAAAAABAgQFAwYQAAEDAgMCBQwOCQQDAAAAAAIBAwQABRESBiEHMUFhExRRcYEisnPDNIQVRRaRodEyQlJikiOzVGYnCLFyo9NklKQlGIIzQ2VTdhcRAAIBAgQEBAYDAQAAAAAAAAABAhEDITESBEFRMgVhcZFCgaHR4SITsVJiFf\/aAAwDAQACEQMRAD8AJyHDhlDYImG1JWwVVUBVVVRTkqge6DC+ztfMH3KgF0GF9na+YPuUAugwvs7XzB9ygF0GF9na+YPuUBR6n1NpDTTAuXUmgdcTFmK22JvuYfFbRMcOVdnLXje3MLa\/JmEpqOZmty32GbiparFGaa24OS1QzXlyNoiJ85a50+5y9q9Tyd7kiva3v6jQ8xwraY\/E5gh9tDrBdxueBP2s6ax74rK6YtXq0DFx2LJjIjzafrAooaJ1sa2LfcU+pUM1eXE0i3nY7jEblwUjyYzqYg62gEK+wnDyV0IzUlVOqPVNMkdBhfZ2vmD7lZFF0GF9na+YPuUBD6JF88c3zIc30fNkyphjnwxwwqkJkHxKP3oO5SoUfoBUAqA47eXr5rSlqEY6C7eJuIwmC2iKJ755xE+AGPZXZWpu9z+qOHU8jzuXNK8Qe813vd2UlV243WaWJmvbOGqcarsQQHsCKVw4Qnclh+UmamLZ3dn3UKQCd1lkprwx42CCnIrpIqqvWSuva7Uve\/Q9la5l0W6rT6hgCSQPiLnlL2iTCth9ss+PqX9aOcv27W725spEEimsDtJpRyvoicaInan2NvJWjf7dKKrB6l8\/uYuDRWaT1fdNN3BJcIlNhxU6XCVcG3hTh\/VcT4Jdhdlali+7bqsiRk0ETZrvBvFsj3KCfORZI5wVdipxKJJxEK7FSu9bmpxTWRtJ1VSbWZSF6b8m8JVA9B8Sj96DuUqAfoDNdab+dKaZvDtnGPIuk6MqDMSNkRtolTHIpuEKKaIqYoOOHHtoCz3bb07frsriMO3yIPm7ms\/SCbLPz2bDLkIuDJx0Bh2u9SHf9VXG5kalHEyYhp8WOwqiOCfKXE+zXzO4u67jkaM5VdTSt3ulAtdrB54E84zBFyUfGIr2wMovUFOHqlX0Gy2ytQ\/08\/oe8I0R3LTIinBW6ZEphGxLthx61Ggiw6Mw8zwIQrXk20zMxXexpMLZLG7xRysSTyShRMERxdouf68MC5a5HcLCi9a45+fP4nhcjTEsdx2oTbuEywun9DIBZcUV4nAVBdRP1kUS7FTt12jcfiWzLgbJXWNghem\/JvCVQPQfEo\/eg7lKgH6AC1m2u6h3hnajeVty63h9hySqZlFDkGpHgvCqCi4VQEvp3dvYNA2a+yLI7KcclxlN1ZTgubY7ZqCjlEMPfLjXncdIvyI8gfbLGR+4W1hzaDzzAn1lMca+b28azinzRoxWISEIUwxw4Vxr642mTxSqQfbCowTI+IqvUVNtYSM4nI70GG39JXNC4W2VcFeoQEhItae9VbMjG50syPdfKNnXtmUOFxxxov1TZPH9FcfaOl2J423+SCVr6A2yF6b8m8JVA9B8Sj96DuUqAfoAOtGF+MtrT\/v3vrXaoDAmRhlRH4x+9fbJsusYqK\/prGSqqBgjgj9ul82YqMm3vZCBeHPHcwVOyoV8zGsJeMX\/AAaGQRdjlNTobctgkJl4BdbVOMTTH2uCvrIyUkmsmbWZbtJjtrMhKbGsWyj2wRxrBmSM73v3lqHpd+Pm+muBDHaHjUcUJxewKVz+43KW6cZYfUwuukfM4PczbHJuuor+XFm3tOyHC6iqPNB7Z1ztjGt1eB5WlWQRdd42yF6b8m8JVA9B8Sj96DuUqA5jeTvJtWhLSzMnMPSn5hmzBjsiioTwgpojhqqIA7Npe1QA2borLf77vMtFwYiOOMx5x3C5TEAkjtoucyTnFTLiRnlEccaoDBqAH7fhpB60X71jihjbLqSJLUU2NS8MMS6gvImxfjJypXG31jTLWsma16NHUh7ud4Q2VUt1wNUtxkqsv7V5kiXFUJE282q7dnvV5Kz2W9UFon08Hy+xjCdDaIdyYkNi82Ym04mIOAqEJIvGhJsrtp1VVkexYDLbRMcajZUVWotV2qzQilXGQLDSJ2grtM1+K2HCS14Xr0barJ\/V+RXJLMH7VWp52qr10lwVajtpzcONjjzbeOOK4cJku0q+d3O4c5apYcvBGpOdXU3XdTo0tPWJX5LeS43DK48K++BtE+jbXl2qq8q11e3bdwhql1S+S4GzZhRVZ21dA9SF6b8m8JVA9B8Sj96DuUqA5feRu0tOvLbGh3CVIhlCcJ+K7GUNjhAoduJiWYUx4NnXoAbdz+p9R6f3m2yyx5riwJVwdt1wgqZLGcwU2+dFtVwE0IEJCTbxLilUBg1AVmpVsnmKYF7Fpy1uN83IbfVEA0NUERxXjIlRE5axkk1R5ElSmIKWoLQ9Y7m9HUSSOhKraEqkQCq4oKl8LBNmbjrlbrt8oOsMY\/NGq7b4Huz6juduPC2z3IxLtVts+1XrguI+1WjC7KHS3EwToXbu8PWxt5EupgnxgFsS9lBr1e8vP3My1y5lCy1e7\/cubYGTd7ia4YBmePsrtQE66ola6UpvCsn6mGLZtu7XdAtoNu66gyOXAVQmIIKhtslxEZcBmnFh2qcvDXT23b6PVcz4I2LdmmLNTrqnuKgIXpvybwlUD0HxKP3oO5SoB+gAo0Qf43WlPvC\/9c9VAa9QGC79NZjcLoOnIp5oVtJHJypwHKVO1DlRoVxX5S8lcff39UtCyWZq35VwMrLUN3Pmbc235yJ0xYhxDxJxTNcoNtn75MVWvXbbqcaLqRhCbQTunN2OloOmIlquFriy3hHnJTjrYuKr57XMDVMcEXYmHEldCduM+pI29KeZIa3XbvWjQwsETMm3aGZPYVVSvJbS1\/VE\/XHkYlvp3zav3fa8LTWlQtsK2JDjyBZKIiqrjqmhe8NtPgJxV7xilkZJULrcV+Ya86v1H6ranjRxnyGnHrdPiCTYuKymZxpxsiPAsmJCQrhs4KpTfKAVAQvTfk3hKoHoPiUfvQdylQD9ABHoYvxxtP8A7E\/9c9VAW28PV7WltNPzhUSnO\/QW5lfhPmi5VVPignbFyJWvub6twb48DCc9KqChcZZqpm44rjpkRuOltIzJcxEvKSrjXz0at1ZpGk\/l10Ot0vD2sZ7eMO2kUe0iSYoclUwdewX\/AMQrkH5Sr1K7Gzte5nvZhxCMroGyKgOe1ToPR2o4stLzZ4cx6QwrBynGGykICIuXK8qZxUVXEcF2LQAafl6JR3zaYRSXY7KDMvCuEV5NvXwoA7KAVAQvTfk3hKoHoPiUfvQdylQD9AA9oUvx0tKfeN\/656qAjN48yyXqZJ09emnIc+P9JalLATNvKirJil71xMVyOBwphtTai15XbMbkaSMZxTWJiZ7utS3a+x7PazbkdKcQFliuVGWse3dMC29oO3BMcV2Vzf8Anzi+aNd2WFhp2w27T9jhWW3BzcKA0LLI8aonCRdUiXElXq11IxSVEbKVFQsayKKgESISKK7UXYqUAAmu7A9uz1+o2K\/xJsq2yykQXoh85IikJqoty21Hm0MUVRIcxIqcOHBQBhblNb3bW+7i16juwMNz5ZPg8MUSFr6F82kVBMjVMUDFdvDQHc0BC9N+TeEqgeg+JR+9B3KVAP0ADOgy\/Ha0J95H\/rnqoDT1Fpiwajt62+9wm50VVQxFxFQgNOA2zFUNs04iBUWoCn0Xu4tGkpEx+HMmTSlZRBZ7ovkyCYrkBzKJqir8dSXZw0B1dAKgFQHl1VFo1HhQVVOvhQH567obLA1XvYsNnvIrJhzpjzs0CVfpUaBx9RNeHAyDAuSgP0Et9ut9tiNwrdFZhQ2UwajR2xaaBFXHtQBEFNvUSgJFAQvTfk3hKoHoPiUfvQdylQD9AABrKPedG7y7o2RlBu1tujs6A+qIiqJPq8w+CFsICEk9tKoO2\/yy3qIiY+aNibV6M5t5f9+oD5\/lpvV\/6j+Wc\/f0B5X82u9Xi80fyzn7+gPJfm43qim3zR\/LOfv6AZP83+9ZODzP\/LO\/v6Ag3P8ANvvZm2+TC5y2xkktk0siPHNHQQ0wUm1N0xQuoqitARPyqafn3XfDbJ0dslhWRqRJmPInaijjJstipcGYzc2Jx4L1KAO2gFQEL035N4SqBmJ546KzzfR+byDkzZ8cMEwxwoQe\/vf8N+0oU5bWfqdjH9c\/V7NgvRfO3NZsMdvN8\/twx4cKA5j8BuP1K\/pKA+fgL9yv6OgF+An3J\/o6A8r\/APAOP1I7PQ6A8F\/j1x+o\/Z6FQHgv8deP1F7PQqA7rRnq\/wCal9S\/MfmrOubzRzfMc5gmObo\/a5sOrtoC\/wD73\/DftKAX97\/hv2lARP7p50\/4Of5j5eTJn9nHGhD\/2Q=="}}}';
+ $this->assertEquals($jsonString, json_encode($query->toArray()));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFromReference()
+ {
+ $this->markTestSkipped('Tests skipped as plugin not working properly with ES 1.6.0. See https://github.com/ruflin/Elastica/pull/881');
+ $field = 'image';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ $field => array(
+ 'type' => 'image',
+ 'store' => false,
+ 'include_in_all' => false,
+ 'feature' => array(
+ 'CEDD' => array(
+ 'hash' => 'BIT_SAMPLING',
+ ),
+ ),
+ ),
+ )
+ );
+
+ $type->setMapping($mapping);
+
+ $type->addDocuments(array(
+ new Document(1, array($field => $this->_testFileContent)),
+ new Document(2, array($field => $this->_testFileContent)),
+ new Document(3, array($field => $this->_testFileContent)),
+ ));
+
+ $index->refresh();
+
+ $query = new Image();
+ $query->setFieldFeature($field, 'CEDD');
+ $query->setFieldHash($field, 'BIT_SAMPLING');
+ $query->setFieldBoost($field, 100);
+ $query->setImageByReference($field, $index->getName(), $type->getName(), 1);
+
+ $resultSet = $index->search($query);
+ $this->assertEquals(3, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFromImage()
+ {
+ $this->markTestSkipped('Tests skipped as plugin not working properly with ES 1.6.0. See https://github.com/ruflin/Elastica/pull/881');
+
+ $field = 'image';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ $field => array(
+ 'type' => 'image',
+ 'store' => false,
+ 'include_in_all' => false,
+ 'feature' => array(
+ 'CEDD' => array(
+ 'hash' => 'BIT_SAMPLING',
+ ),
+ ),
+ ),
+ )
+ );
+
+ $type->setMapping($mapping);
+
+ $type->addDocuments(array(
+ new Document(1, array($field => $this->_testFileContent)),
+ new Document(2, array($field => $this->_testFileContent)),
+ new Document(3, array($field => $this->_testFileContent)),
+ ));
+
+ $index->refresh();
+
+ $query = new Image();
+ $query->setFieldFeature($field, 'CEDD');
+ $query->setFieldHash($field, 'BIT_SAMPLING');
+ $query->setFieldBoost($field, 100);
+ $query->setFieldImage($field, BASE_PATH.'/data/test.jpg');
+
+ $resultSet = $index->search($query);
+ $this->assertEquals(3, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchAllTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchAllTest.php
new file mode 100644
index 00000000..7eb0fae0
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchAllTest.php
@@ -0,0 +1,49 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\MatchAll;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+
+class MatchAllTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new MatchAll();
+
+ $expectedArray = array('match_all' => new \stdClass());
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchAllIndicesTypes()
+ {
+ $index1 = $this->_createIndex();
+ $index2 = $this->_createIndex();
+
+ $client = $index1->getClient();
+
+ $search1 = new Search($client);
+ $resultSet1 = $search1->search(new MatchAll());
+
+ $doc1 = new Document(1, array('name' => 'ruflin'));
+ $doc2 = new Document(1, array('name' => 'ruflin'));
+ $index1->getType('test')->addDocument($doc1);
+ $index2->getType('test')->addDocument($doc2);
+
+ $index1->refresh();
+ $index2->refresh();
+
+ $search2 = new Search($client);
+ $resultSet2 = $search2->search(new MatchAll());
+
+ $this->assertEquals($resultSet1->getTotalHits() + 2, $resultSet2->getTotalHits());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchTest.php
new file mode 100644
index 00000000..98fdf26a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MatchTest.php
@@ -0,0 +1,339 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Match;
+use Elastica\Query\MatchPhrase;
+use Elastica\Query\MatchPhrasePrefix;
+use Elastica\Test\Base as BaseTest;
+
+class MatchTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $field = 'test';
+ $testQuery = 'Nicolas Ruflin';
+ $type = 'phrase';
+ $operator = 'and';
+ $analyzer = 'myanalyzer';
+ $boost = 2.0;
+ $minimumShouldMatch = 2;
+ $fuzziness = 0.3;
+ $fuzzyRewrite = 'constant_score_boolean';
+ $prefixLength = 3;
+ $maxExpansions = 12;
+
+ $query = new Match();
+ $query->setFieldQuery($field, $testQuery);
+ $query->setFieldType($field, $type);
+ $query->setFieldOperator($field, $operator);
+ $query->setFieldAnalyzer($field, $analyzer);
+ $query->setFieldBoost($field, $boost);
+ $query->setFieldMinimumShouldMatch($field, $minimumShouldMatch);
+ $query->setFieldFuzziness($field, $fuzziness);
+ $query->setFieldFuzzyRewrite($field, $fuzzyRewrite);
+ $query->setFieldPrefixLength($field, $prefixLength);
+ $query->setFieldMaxExpansions($field, $maxExpansions);
+
+ $expectedArray = array(
+ 'match' => array(
+ $field => array(
+ 'query' => $testQuery,
+ 'type' => $type,
+ 'operator' => $operator,
+ 'analyzer' => $analyzer,
+ 'boost' => $boost,
+ 'minimum_should_match' => $minimumShouldMatch,
+ 'fuzziness' => $fuzziness,
+ 'fuzzy_rewrite' => $fuzzyRewrite,
+ 'prefix_length' => $prefixLength,
+ 'max_expansions' => $maxExpansions,
+ ),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatch()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'New Hampshire')),
+ new Document(4, array('name' => 'Basel Land')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+ $operator = 'or';
+
+ $query = new Match();
+ $query->setFieldQuery($field, 'Basel New');
+ $query->setFieldOperator($field, $operator);
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(4, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchSetFieldBoost()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'New Hampshire')),
+ new Document(4, array('name' => 'Basel Land')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+ $operator = 'or';
+
+ $query = new Match();
+ $query->setFieldQuery($field, 'Basel New');
+ $query->setFieldOperator($field, $operator);
+ $query->setFieldBoost($field, 1.2);
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(4, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchSetFieldBoostWithString()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'New Hampshire')),
+ new Document(4, array('name' => 'Basel Land')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+ $operator = 'or';
+
+ $query = new Match();
+ $query->setFieldQuery($field, 'Basel New');
+ $query->setFieldOperator($field, $operator);
+ $query->setFieldBoost($field, '1.2');
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(4, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchZeroTerm()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ ));
+
+ $index->refresh();
+
+ $query = new Match();
+ $query->setFieldQuery('name', '');
+ $query->setFieldZeroTermsQuery('name', Match::ZERO_TERM_ALL);
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchPhrase()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'New Hampshire')),
+ new Document(4, array('name' => 'Basel Land')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+ $type = 'phrase';
+
+ $query = new Match();
+ $query->setFieldQuery($field, 'New York');
+ $query->setFieldType($field, $type);
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchPhraseAlias()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'New Hampshire')),
+ new Document(4, array('name' => 'Basel Land')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+
+ $query = new MatchPhrase();
+ $query->setFieldQuery($field, 'New York');
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchPhrasePrefix()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'New Hampshire')),
+ new Document(4, array('name' => 'Basel Land')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+ $type = 'phrase_prefix';
+
+ $query = new Match();
+ $query->setFieldQuery($field, 'New');
+ $query->setFieldType($field, $type);
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMatchPhrasePrefixAlias()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'New Hampshire')),
+ new Document(4, array('name' => 'Basel Land')),
+ ));
+
+ $index->refresh();
+
+ $field = 'name';
+
+ $query = new MatchPhrasePrefix();
+ $query->setFieldQuery($field, 'New');
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testMatchFuzzinessType()
+ {
+ $field = 'test';
+ $query = new Match();
+
+ $fuzziness = 'AUTO';
+ $query->setFieldFuzziness($field, $fuzziness);
+
+ $parameters = $query->getParam($field);
+ $this->assertEquals($fuzziness, $parameters['fuzziness']);
+
+ $fuzziness = 0.3;
+ $query->setFieldFuzziness($field, $fuzziness);
+
+ $parameters = $query->getParam($field);
+ $this->assertEquals($fuzziness, $parameters['fuzziness']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $match = new Match(null, 'values');
+ $this->assertEquals(array('match' => array()), $match->toArray());
+
+ $match = new Match('field', null);
+ $this->assertEquals(array('match' => array()), $match->toArray());
+
+ $match1 = new Match('field', 'values');
+ $match2 = new Match();
+ $match2->setField('field', 'values');
+ $this->assertEquals($match1->toArray(), $match2->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MoreLikeThisTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MoreLikeThisTest.php
new file mode 100644
index 00000000..5dfe9379
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MoreLikeThisTest.php
@@ -0,0 +1,240 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query;
+use Elastica\Query\MoreLikeThis;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Type\Mapping;
+
+class MoreLikeThisTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test');
+ $index->create(array(), true);
+ $index->getSettings()->setNumberOfReplicas(0);
+ //$index->getSettings()->setNumberOfShards(1);
+
+ $type = new Type($index, 'helloworldmlt');
+ $mapping = new Mapping($type, array(
+ 'email' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ 'content' => array('store' => 'yes', 'type' => 'string', 'index' => 'analyzed'),
+ ));
+
+ $mapping->setSource(array('enabled' => false));
+ $type->setMapping($mapping);
+
+ $doc = new Document(1000, array('email' => 'testemail@gmail.com', 'content' => 'This is a sample post. Hello World Fuzzy Like This!'));
+ $type->addDocument($doc);
+
+ $doc = new Document(1001, array('email' => 'nospam@gmail.com', 'content' => 'This is a fake nospam email address for gmail'));
+ $type->addDocument($doc);
+
+ // Refresh index
+ $index->refresh();
+
+ $mltQuery = new MoreLikeThis();
+ $mltQuery->setLikeText('fake gmail sample');
+ $mltQuery->setFields(array('email', 'content'));
+ $mltQuery->setMaxQueryTerms(1);
+ $mltQuery->setMinDocFrequency(1);
+ $mltQuery->setMinTermFrequency(1);
+
+ $query = new Query();
+ $query->setFields(array('email', 'content'));
+ $query->setQuery($mltQuery);
+
+ $resultSet = $type->search($query);
+ $resultSet->getResponse()->getData();
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetFields()
+ {
+ $query = new MoreLikeThis();
+
+ $fields = array('firstname', 'lastname');
+ $query->setFields($fields);
+
+ $data = $query->toArray();
+ $this->assertEquals($fields, $data['more_like_this']['fields']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetIds()
+ {
+ $query = new MoreLikeThis();
+ $ids = array(1, 2, 3);
+ $query->setIds($ids);
+
+ $data = $query->toArray();
+ $this->assertEquals($ids, $data['more_like_this']['ids']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetLikeText()
+ {
+ $query = new MoreLikeThis();
+ $query->setLikeText(' hello world');
+
+ $data = $query->toArray();
+ $this->assertEquals('hello world', $data['more_like_this']['like_text']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetBoost()
+ {
+ $query = new MoreLikeThis();
+
+ $boost = 1.3;
+ $query->setBoost($boost);
+
+ $this->assertEquals($boost, $query->getParam('boost'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMaxQueryTerms()
+ {
+ $query = new MoreLikeThis();
+
+ $max = 3;
+ $query->setMaxQueryTerms($max);
+
+ $this->assertEquals($max, $query->getParam('max_query_terms'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetPercentTermsToMatch()
+ {
+ $query = new MoreLikeThis();
+
+ $match = 0.8;
+ $query->setPercentTermsToMatch($match);
+
+ $this->assertEquals($match, $query->getParam('percent_terms_to_match'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMinimumShouldMatch()
+ {
+ $query = new MoreLikeThis();
+
+ $match = '80%';
+ $query->setMinimumShouldMatch($match);
+
+ $this->assertEquals($match, $query->getParam('minimum_should_match'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMinDocFrequency()
+ {
+ $query = new MoreLikeThis();
+
+ $freq = 2;
+ $query->setMinDocFrequency($freq);
+
+ $this->assertEquals($freq, $query->getParam('min_doc_freq'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMaxDocFrequency()
+ {
+ $query = new MoreLikeThis();
+
+ $freq = 2;
+ $query->setMaxDocFrequency($freq);
+
+ $this->assertEquals($freq, $query->getParam('max_doc_freq'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMinWordLength()
+ {
+ $query = new MoreLikeThis();
+
+ $length = 4;
+ $query->setMinWordLength($length);
+
+ $this->assertEquals($length, $query->getParam('min_word_length'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMaxWordLength()
+ {
+ $query = new MoreLikeThis();
+
+ $length = 5;
+ $query->setMaxWordLength($length);
+
+ $this->assertEquals($length, $query->getParam('max_word_length'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetBoostTerms()
+ {
+ $query = new MoreLikeThis();
+
+ $boost = false;
+ $query->setBoostTerms($boost);
+
+ $this->assertEquals($boost, $query->getParam('boost_terms'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetAnalyzer()
+ {
+ $query = new MoreLikeThis();
+
+ $analyzer = 'UpperCase';
+ $query->setAnalyzer($analyzer);
+
+ $this->assertEquals($analyzer, $query->getParam('analyzer'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetStopWords()
+ {
+ $query = new MoreLikeThis();
+
+ $stopWords = array('no', 'yes', 'test');
+ $query->setStopWords($stopWords);
+
+ $this->assertEquals($stopWords, $query->getParam('stop_words'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MultiMatchTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MultiMatchTest.php
new file mode 100644
index 00000000..e32f91af
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/MultiMatchTest.php
@@ -0,0 +1,214 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query;
+use Elastica\Query\MultiMatch;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Type\Mapping;
+
+class MultiMatchTest extends BaseTest
+{
+ private $index;
+ private $multiMatch;
+
+ private static $data = array(
+ array('id' => 1, 'name' => 'Rodolfo', 'last_name' => 'Moraes', 'full_name' => 'Rodolfo Moraes'),
+ array('id' => 2, 'name' => 'Tristan', 'last_name' => 'Maindron', 'full_name' => 'Tristan Maindron'),
+ array('id' => 3, 'name' => 'Monique', 'last_name' => 'Maindron', 'full_name' => 'Monique Maindron'),
+ array('id' => 4, 'name' => 'John', 'last_name' => 'not Doe', 'full_name' => 'John not Doe'),
+ );
+
+ /**
+ * @group functional
+ */
+ public function testMinimumShouldMatch()
+ {
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Tristan Maindron');
+ $multiMatch->setFields(array('full_name', 'name'));
+ $multiMatch->setMinimumShouldMatch('2<100%');
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAndOperator()
+ {
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Monique Maindron');
+ $multiMatch->setFields(array('full_name', 'name'));
+ $multiMatch->setOperator(MultiMatch::OPERATOR_AND);
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testType()
+ {
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Trist');
+ $multiMatch->setFields(array('full_name', 'name'));
+ $multiMatch->setType(MultiMatch::TYPE_PHRASE_PREFIX);
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFuzzy()
+ {
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Tritsan'); // Mispell on purpose
+ $multiMatch->setFields(array('full_name', 'name'));
+ $multiMatch->setFuzziness(2);
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Tritsan'); // Mispell on purpose
+ $multiMatch->setFields(array('full_name', 'name'));
+ $multiMatch->setFuzziness(0);
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFuzzyWithOptions1()
+ {
+ // Here Elasticsearch will not accept mispells
+ // on the first 6 letters.
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Tritsan'); // Mispell on purpose
+ $multiMatch->setFields(array('full_name', 'name'));
+ $multiMatch->setFuzziness(2);
+ $multiMatch->setPrefixLength(6);
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(0, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFuzzyWithOptions2()
+ {
+ // Here with a 'M' search we should hit 'Moraes' first
+ // and then stop because MaxExpansion = 1.
+ // If MaxExpansion was set to 2, we could hit "Maindron" too.
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('M');
+ $multiMatch->setFields(array('name'));
+ $multiMatch->setType(MultiMatch::TYPE_PHRASE_PREFIX);
+ $multiMatch->setPrefixLength(0);
+ $multiMatch->setMaxExpansions(1);
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testZeroTerm()
+ {
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('not'); // This is a stopword.
+ $multiMatch->setFields(array('full_name', 'last_name'));
+ $multiMatch->setZeroTermsQuery(MultiMatch::ZERO_TERM_NONE);
+ $multiMatch->setAnalyzer('stops');
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(0, $resultSet->count());
+
+ $multiMatch->setZeroTermsQuery(MultiMatch::ZERO_TERM_ALL);
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(4, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testBaseMultiMatch()
+ {
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Rodolfo');
+ $multiMatch->setFields(array('name', 'last_name'));
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $multiMatch = new MultiMatch();
+ $multiMatch->setQuery('Moraes');
+ $multiMatch->setFields(array('name', 'last_name'));
+ $resultSet = $this->_getResults($multiMatch);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * Executes the query with the current multimatch.
+ */
+ private function _getResults(MultiMatch $multiMatch)
+ {
+ return $this->_generateIndex()->search(new Query($multiMatch));
+ }
+
+ /**
+ * Builds an index for testing.
+ */
+ private function _generateIndex()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $index->create(array(
+ 'analysis' => array(
+ 'analyzer' => array(
+ 'noStops' => array(
+ 'type' => 'standard',
+ 'stopwords' => '_none_',
+ ),
+ 'stops' => array(
+ 'type' => 'standard',
+ 'stopwords' => array('not'),
+ ),
+ ),
+ ),
+ ), true);
+
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no', 'analyzer' => 'noStops'),
+ 'last_name' => array('type' => 'string', 'store' => 'no', 'analyzer' => 'noStops'),
+ 'full_name' => array('type' => 'string', 'store' => 'no', 'analyzer' => 'noStops'),
+ ));
+
+ $type->setMapping($mapping);
+
+ foreach (self::$data as $key => $docData) {
+ $type->addDocument(new Document($key, $docData));
+ }
+
+ // Refresh index
+ $index->refresh();
+
+ return $index;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/NestedTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/NestedTest.php
new file mode 100644
index 00000000..1b5fc368
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/NestedTest.php
@@ -0,0 +1,30 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Query\Nested;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+
+class NestedTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testSetQuery()
+ {
+ $nested = new Nested();
+ $path = 'test1';
+
+ $queryString = new QueryString('test');
+ $this->assertInstanceOf('Elastica\Query\Nested', $nested->setQuery($queryString));
+ $this->assertInstanceOf('Elastica\Query\Nested', $nested->setPath($path));
+ $expected = array(
+ 'nested' => array(
+ 'query' => $queryString->toArray(),
+ 'path' => $path,
+ ),
+ );
+
+ $this->assertEquals($expected, $nested->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PostFilterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PostFilterTest.php
new file mode 100644
index 00000000..178c803e
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PostFilterTest.php
@@ -0,0 +1,64 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Filter\Term;
+use Elastica\Query;
+use Elastica\Query\Match;
+use Elastica\Test\Base as BaseTest;
+
+class PostFilterTest extends BaseTest
+{
+ protected function _getTestIndex()
+ {
+ $index = $this->_createIndex();
+ $docs = array(
+ new Document(1, array('color' => 'green', 'make' => 'ford')),
+ new Document(2, array('color' => 'blue', 'make' => 'volvo')),
+ new Document(3, array('color' => 'red', 'make' => 'ford')),
+ new Document(4, array('color' => 'green', 'make' => 'renault')),
+ );
+ $index->getType('test')->addDocuments($docs);
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new Query();
+
+ $post_filter = new Term(array('color' => 'green'));
+ $query->setPostFilter($post_filter);
+
+ $data = $query->toArray();
+
+ $this->assertArrayHasKey('post_filter', $data);
+ $this->assertEquals(array('term' => array('color' => 'green')), $data['post_filter']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $query = new Query();
+
+ $match = new Match();
+ $match->setField('make', 'ford');
+
+ $query->setQuery($match);
+
+ $filter = new Term();
+ $filter->setTerm('color', 'green');
+
+ $query->setPostFilter($filter);
+
+ $results = $this->_getTestIndex()->search($query);
+
+ $this->assertEquals(1, $results->getTotalHits());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PrefixTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PrefixTest.php
new file mode 100644
index 00000000..e12ead05
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/PrefixTest.php
@@ -0,0 +1,27 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Query\Prefix;
+use Elastica\Test\Base as BaseTest;
+
+class PrefixTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new Prefix();
+ $key = 'name';
+ $value = 'ni';
+ $boost = 2;
+ $query->setPrefix($key, $value, $boost);
+
+ $data = $query->toArray();
+
+ $this->assertInternalType('array', $data['prefix']);
+ $this->assertInternalType('array', $data['prefix'][$key]);
+ $this->assertEquals($data['prefix'][$key]['value'], $value);
+ $this->assertEquals($data['prefix'][$key]['boost'], $boost);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/QueryStringTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/QueryStringTest.php
new file mode 100644
index 00000000..5b549a30
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/QueryStringTest.php
@@ -0,0 +1,189 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+
+class QueryStringTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testSearchMultipleFields()
+ {
+ $str = md5(rand());
+ $query = new QueryString($str);
+
+ $expected = array(
+ 'query' => $str,
+ );
+
+ $this->assertEquals(array('query_string' => $expected), $query->toArray());
+
+ $fields = array();
+ $max = rand() % 10 + 1;
+ for ($i = 0; $i < $max; $i++) {
+ $fields[] = md5(rand());
+ }
+
+ $query->setFields($fields);
+ $expected['fields'] = $fields;
+ $this->assertEquals(array('query_string' => $expected), $query->toArray());
+
+ foreach (array(false, true) as $val) {
+ $query->setUseDisMax($val);
+ $expected['use_dis_max'] = $val;
+
+ $this->assertEquals(array('query_string' => $expected), $query->toArray());
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $index = $this->_createIndex();
+ $index->getSettings()->setNumberOfReplicas(0);
+ $type = $index->getType('helloworld');
+
+ $doc = new Document(1, array('email' => 'test@test.com', 'username' => 'hanswurst', 'test' => array('2', '3', '5')));
+ $type->addDocument($doc);
+ $index->refresh();
+
+ $queryString = new QueryString('test*');
+ $resultSet = $type->search($queryString);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * Tests if search in multiple fields is possible.
+ *
+ * @group functional
+ */
+ public function testSearchFields()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $doc = new Document(1, array('title' => 'hello world', 'firstname' => 'nicolas', 'lastname' => 'ruflin', 'price' => '102', 'year' => '2012'));
+ $type->addDocument($doc);
+ $index->refresh();
+
+ $query = new QueryString();
+ $query = $query->setQuery('ruf*');
+ $query = $query->setDefaultField('title');
+ $query = $query->setFields(array('title', 'firstname', 'lastname', 'price', 'year'));
+
+ $resultSet = $type->search($query);
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetDefaultOperator()
+ {
+ $operator = 'AND';
+ $query = new QueryString('test');
+ $query->setDefaultOperator($operator);
+
+ $data = $query->toArray();
+
+ $this->assertEquals($data['query_string']['default_operator'], $operator);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetDefaultField()
+ {
+ $default = 'field1';
+ $query = new QueryString('test');
+ $query->setDefaultField($default);
+
+ $data = $query->toArray();
+
+ $this->assertEquals($data['query_string']['default_field'], $default);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetRewrite()
+ {
+ $rewrite = 'scoring_boolean';
+ $query = new QueryString('test');
+ $query->setRewrite($rewrite);
+
+ $data = $query->toArray();
+
+ $this->assertEquals($data['query_string']['rewrite'], $rewrite);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testSetQueryInvalid()
+ {
+ $query = new QueryString();
+ $query->setQuery(array());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetTimezone()
+ {
+ $timezone = 'Europe/Paris';
+ $text = 'date:[2012 TO 2014]';
+
+ $query = new QueryString($text);
+ $query->setTimezone($timezone);
+
+ $expected = array(
+ 'query_string' => array(
+ 'query' => $text,
+ 'time_zone' => $timezone,
+ ),
+ );
+
+ $this->assertEquals($expected, $query->toArray());
+ $this->assertInstanceOf('Elastica\Query\QueryString', $query->setTimezone($timezone));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetPhraseSlop()
+ {
+ $phraseSlop = 9;
+
+ $query = new QueryString('test');
+ $query->setPhraseSlop($phraseSlop);
+
+ $data = $query->toArray();
+ $this->assertEquals($phraseSlop, $data['query_string']['phrase_slop']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetBoost()
+ {
+ $index = $this->_createIndex();
+ $query = new QueryString('test');
+ $query->setBoost(9.3);
+
+ $doc = new Document('', array('name' => 'test'));
+ $index->getType('test')->addDocument($doc);
+ $index->refresh();
+
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RangeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RangeTest.php
new file mode 100644
index 00000000..108ef0c9
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RangeTest.php
@@ -0,0 +1,79 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Range;
+use Elastica\Test\Base as BaseTest;
+
+class RangeTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('age' => 16, 'height' => 140)),
+ new Document(2, array('age' => 21, 'height' => 155)),
+ new Document(3, array('age' => 33, 'height' => 160)),
+ new Document(4, array('age' => 68, 'height' => 160)),
+ ));
+
+ $index->optimize();
+ $index->refresh();
+
+ $query = new Range('age', array('from' => 10, 'to' => 20));
+ $result = $type->search($query)->count();
+ $this->assertEquals(1, $result);
+
+ $query = new Range();
+ $query->addField('height', array('gte' => 160));
+
+ $result = $type->search($query)->count();
+ $this->assertEquals(2, $result);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $range = new Range();
+
+ $field = array('from' => 20, 'to' => 40);
+ $range->addField('age', $field);
+
+ $expectedArray = array(
+ 'range' => array(
+ 'age' => $field,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $range->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $ranges = array('from' => 20, 'to' => 40);
+ $range = new Range(
+ 'age',
+ $ranges
+ );
+
+ $expectedArray = array(
+ 'range' => array(
+ 'age' => $ranges,
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $range->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RegexpTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RegexpTest.php
new file mode 100644
index 00000000..c67e6317
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RegexpTest.php
@@ -0,0 +1,31 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Query\Regexp;
+use Elastica\Test\Base as BaseTest;
+
+class RegexpTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $field = 'name';
+ $value = 'ruf';
+ $boost = 2;
+
+ $query = new Regexp($field, $value, $boost);
+
+ $expectedArray = array(
+ 'regexp' => array(
+ $field => array(
+ 'value' => $value,
+ 'boost' => $boost,
+ ),
+ ),
+ );
+
+ $this->assertequals($expectedArray, $query->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RescoreTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RescoreTest.php
new file mode 100644
index 00000000..87842b0f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/RescoreTest.php
@@ -0,0 +1,236 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Query;
+use Elastica\Query\Match;
+use Elastica\Query\Term;
+use Elastica\Rescore\Query as QueryRescore;
+use Elastica\Test\Base as BaseTest;
+
+class RescoreTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new Query();
+ $mainQuery = new Match();
+ $mainQuery = $mainQuery->setFieldQuery('test1', 'foo');
+ $secQuery = new Term();
+ $secQuery = $secQuery->setTerm('test2', 'bar', 2);
+ $queryRescore = new QueryRescore($secQuery);
+ $query->setQuery($mainQuery);
+ $query->setRescore($queryRescore);
+ $data = $query->toArray();
+
+ $expected = array(
+ 'query' => array(
+ 'match' => array(
+ 'test1' => array(
+ 'query' => 'foo',
+ ),
+ ),
+ ),
+ 'rescore' => array(
+ 'query' => array(
+ 'rescore_query' => array(
+ 'term' => array(
+ 'test2' => array(
+ 'value' => 'bar',
+ 'boost' => 2,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $data);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSize()
+ {
+ $query = new Query();
+ $mainQuery = new Match();
+ $mainQuery = $mainQuery->setFieldQuery('test1', 'foo');
+ $secQuery = new Term();
+ $secQuery = $secQuery->setTerm('test2', 'bar', 2);
+ $queryRescore = new QueryRescore($secQuery);
+ $queryRescore->setWindowSize(50);
+ $query->setQuery($mainQuery);
+ $query->setRescore($queryRescore);
+ $data = $query->toArray();
+
+ $expected = array(
+ 'query' => array(
+ 'match' => array(
+ 'test1' => array(
+ 'query' => 'foo',
+ ),
+ ),
+ ),
+ 'rescore' => array(
+ 'window_size' => 50,
+ 'query' => array(
+ 'rescore_query' => array(
+ 'term' => array(
+ 'test2' => array(
+ 'value' => 'bar',
+ 'boost' => 2,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $data);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetWeights()
+ {
+ $query = new Query();
+ $mainQuery = new Match();
+ $mainQuery = $mainQuery->setFieldQuery('test1', 'foo');
+ $secQuery = new Term();
+ $secQuery = $secQuery->setTerm('test2', 'bar', 2);
+ $queryRescore = new QueryRescore($secQuery);
+ $queryRescore->setWindowSize(50);
+ $queryRescore->setQueryWeight(.7);
+ $queryRescore->setRescoreQueryWeight(1.2);
+ $query->setQuery($mainQuery);
+ $query->setRescore($queryRescore);
+ $data = $query->toArray();
+
+ $expected = array(
+ 'query' => array(
+ 'match' => array(
+ 'test1' => array(
+ 'query' => 'foo',
+ ),
+ ),
+ ),
+ 'rescore' => array(
+ 'window_size' => 50,
+ 'query' => array(
+ 'rescore_query' => array(
+ 'term' => array(
+ 'test2' => array(
+ 'value' => 'bar',
+ 'boost' => 2,
+ ),
+ ),
+ ),
+ 'query_weight' => 0.7,
+ 'rescore_query_weight' => 1.2,
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $data);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMultipleQueries()
+ {
+ $query = new Query();
+ $mainQuery = new Match();
+ $mainQuery = $mainQuery->setFieldQuery('test1', 'foo');
+
+ $secQuery1 = new Term();
+ $secQuery1 = $secQuery1->setTerm('test2', 'bar', 1);
+ $rescoreQuery1 = new QueryRescore();
+ $rescoreQuery1->setRescoreQuery($secQuery1);
+
+ $secQuery2 = new Term();
+ $secQuery2 = $secQuery2->setTerm('test2', 'tom', 2);
+ $rescoreQuery2 = new QueryRescore();
+ $rescoreQuery2->setRescoreQuery($secQuery2);
+
+ $query->setQuery($mainQuery);
+ $query->setRescore(array($rescoreQuery1, $rescoreQuery2));
+ $data = $query->toArray();
+
+ $expected = array(
+ 'query' => array(
+ 'match' => array(
+ 'test1' => array(
+ 'query' => 'foo',
+ ),
+ ),
+ ),
+ 'rescore' => array(
+ array(
+ 'query' => array(
+ 'rescore_query' => array(
+ 'term' => array(
+ 'test2' => array(
+ 'value' => 'bar',
+ 'boost' => 1,
+ ),
+ ),
+ ),
+ ),
+ ),
+ array(
+ 'query' => array(
+ 'rescore_query' => array(
+ 'term' => array(
+ 'test2' => array(
+ 'value' => 'tom',
+ 'boost' => 2,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $data);
+
+ $index = $this->_createIndex();
+ $index->refresh();
+ $results = $index->search($query);
+ $response = $results->getResponse();
+
+ $this->assertEquals(true, $response->isOk());
+ $this->assertEquals(0, $results->getTotalHits());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $query = new Query();
+ $mainQuery = new Match();
+ $mainQuery = $mainQuery->setFieldQuery('test1', 'foo');
+ $secQuery = new Term();
+ $secQuery = $secQuery->setTerm('test2', 'bar', 2);
+ $queryRescore = new QueryRescore($secQuery);
+ $queryRescore->setWindowSize(50);
+ $queryRescore->setQueryWeight(.7);
+ $queryRescore->setRescoreQueryWeight(1.2);
+ $query->setQuery($mainQuery);
+ $query->setRescore($queryRescore);
+ $data = $query->toArray();
+
+ $index = $this->_createIndex();
+ $index->refresh();
+ $results = $index->search($query);
+ $response = $results->getResponse();
+
+ $this->assertEquals(true, $response->isOk());
+ $this->assertEquals(0, $results->getTotalHits());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleQueryStringTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleQueryStringTest.php
new file mode 100644
index 00000000..80316547
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleQueryStringTest.php
@@ -0,0 +1,103 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\SimpleQueryString;
+use Elastica\Test\Base;
+
+class SimpleQueryStringTest extends Base
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $string = 'this is a test';
+ $fields = array('field1', 'field2');
+ $query = new SimpleQueryString($string, $fields);
+ $query->setDefaultOperator(SimpleQueryString::OPERATOR_OR);
+ $query->setAnalyzer('whitespace');
+
+ $expected = array(
+ 'simple_query_string' => array(
+ 'query' => $string,
+ 'fields' => $fields,
+ 'analyzer' => 'whitespace',
+ 'default_operator' => SimpleQueryString::OPERATOR_OR,
+ ),
+ );
+
+ $this->assertEquals($expected, $query->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $index = $this->_createIndex();
+ $docs = array(
+ new Document(1, array('make' => 'Gibson', 'model' => 'Les Paul')),
+ new Document(2, array('make' => 'Gibson', 'model' => 'SG Standard')),
+ new Document(3, array('make' => 'Gibson', 'model' => 'SG Supreme')),
+ new Document(4, array('make' => 'Gibson', 'model' => 'SG Faded')),
+ new Document(5, array('make' => 'Fender', 'model' => 'Stratocaster')),
+ );
+ $index->getType('guitars')->addDocuments($docs);
+ $index->refresh();
+
+ $query = new SimpleQueryString('gibson +sg +-faded', array('make', 'model'));
+ $results = $index->search($query);
+
+ $this->assertEquals(2, $results->getTotalHits());
+
+ $query->setFields(array('model'));
+ $results = $index->search($query);
+
+ // We should not get any hits, since the "make" field was not included in the query.
+ $this->assertEquals(0, $results->getTotalHits());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMinimumShouldMatch()
+ {
+ $expected = array(
+ 'simple_query_string' => array(
+ 'query' => 'DONT PANIC',
+ 'minimum_should_match' => '75%',
+ ),
+ );
+
+ $query = new SimpleQueryString($expected['simple_query_string']['query']);
+ $query->setMinimumShouldMatch($expected['simple_query_string']['minimum_should_match']);
+
+ $this->assertEquals($expected, $query->toArray());
+ $this->assertInstanceOf('Elastica\Query\SimpleQueryString', $query->setMinimumShouldMatch('75%'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetMinimumShouldMatchWorks()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('foobars');
+ $type->addDocuments(array(
+ new Document(1, array('body' => 'foo')),
+ new Document(2, array('body' => 'bar')),
+ new Document(3, array('body' => 'foo bar')),
+ new Document(4, array('body' => 'foo baz bar')),
+ ));
+ $index->refresh();
+
+ $query = new SimpleQueryString('foo bar');
+ $query->setMinimumShouldMatch(2);
+ $results = $type->search($query);
+
+ $this->assertCount(2, $results);
+ $this->assertEquals(3, $results[0]->getId());
+ $this->assertEquals(4, $results[1]->getId());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleTest.php
new file mode 100644
index 00000000..b4f1dc8d
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/SimpleTest.php
@@ -0,0 +1,19 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Query\Simple;
+use Elastica\Test\Base as BaseTest;
+
+class SimpleTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $testQuery = array('hello' => array('world'), 'name' => 'ruflin');
+ $query = new Simple($testQuery);
+
+ $this->assertEquals($testQuery, $query->toArray());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermTest.php
new file mode 100644
index 00000000..da15f0f2
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermTest.php
@@ -0,0 +1,27 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Query\Term;
+use Elastica\Test\Base as BaseTest;
+
+class TermTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $query = new Term();
+ $key = 'name';
+ $value = 'nicolas';
+ $boost = 2;
+ $query->setTerm($key, $value, $boost);
+
+ $data = $query->toArray();
+
+ $this->assertInternalType('array', $data['term']);
+ $this->assertInternalType('array', $data['term'][$key]);
+ $this->assertEquals($data['term'][$key]['value'], $value);
+ $this->assertEquals($data['term'][$key]['boost'], $boost);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermsTest.php
new file mode 100644
index 00000000..f0c2b4b4
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/TermsTest.php
@@ -0,0 +1,65 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Terms;
+use Elastica\Test\Base as BaseTest;
+
+class TermsTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testFilteredSearch()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('helloworld');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'hello world')),
+ new Document(2, array('name' => 'nicolas ruflin')),
+ new Document(3, array('name' => 'ruflin')),
+ ));
+
+ $query = new Terms();
+ $query->setTerms('name', array('nicolas', 'hello'));
+
+ $index->refresh();
+
+ $resultSet = $type->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+
+ $query->addTerm('ruflin');
+ $resultSet = $type->search($query);
+
+ $this->assertEquals(3, $resultSet->count());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetMinimum()
+ {
+ $key = 'name';
+ $terms = array('nicolas', 'ruflin');
+ $minimum = 2;
+
+ $query = new Terms($key, $terms);
+ $query->setMinimumMatch($minimum);
+
+ $data = $query->toArray();
+ $this->assertEquals($minimum, $data['terms']['minimum_match']);
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testInvalidParams()
+ {
+ $query = new Terms();
+
+ $query->toArray();
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/WildcardTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/WildcardTest.php
new file mode 100644
index 00000000..7a0c379e
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Query/WildcardTest.php
@@ -0,0 +1,106 @@
+<?php
+namespace Elastica\Test\Query;
+
+use Elastica\Document;
+use Elastica\Query\Wildcard;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class WildcardTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testConstructEmpty()
+ {
+ $wildcard = new Wildcard();
+ $this->assertEmpty($wildcard->getParams());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $key = 'name';
+ $value = 'Ru*lin';
+ $boost = 2.0;
+
+ $wildcard = new Wildcard($key, $value, $boost);
+
+ $expectedArray = array(
+ 'wildcard' => array(
+ $key => array(
+ 'value' => $value,
+ 'boost' => $boost,
+ ),
+ ),
+ );
+
+ $this->assertEquals($expectedArray, $wildcard->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchWithAnalyzer()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $indexParams = array(
+ 'analysis' => array(
+ 'analyzer' => array(
+ 'lw' => array(
+ 'type' => 'custom',
+ 'tokenizer' => 'keyword',
+ 'filter' => array('lowercase'),
+ ),
+ ),
+ ),
+ );
+
+ $index->create($indexParams, true);
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no', 'analyzer' => 'lw'),
+ )
+ );
+ $type->setMapping($mapping);
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'Basel-Stadt')),
+ new Document(2, array('name' => 'New York')),
+ new Document(3, array('name' => 'Baden')),
+ new Document(4, array('name' => 'Baden Baden')),
+ new Document(5, array('name' => 'New Orleans')),
+ ));
+
+ $index->refresh();
+
+ $query = new Wildcard();
+ $query->setValue('name', 'ba*');
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(3, $resultSet->count());
+
+ $query = new Wildcard();
+ $query->setValue('name', 'baden*');
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(2, $resultSet->count());
+
+ $query = new Wildcard();
+ $query->setValue('name', 'baden b*');
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $query = new Wildcard();
+ $query->setValue('name', 'baden bas*');
+ $resultSet = $index->search($query);
+
+ $this->assertEquals(0, $resultSet->count());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AbstractDSLTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AbstractDSLTest.php
new file mode 100644
index 00000000..3e44f463
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AbstractDSLTest.php
@@ -0,0 +1,97 @@
+<?php
+namespace Elastica\Test\QueryBuilder\DSL;
+
+use Elastica\Exception\NotImplementedException;
+use Elastica\QueryBuilder\DSL;
+use Elastica\Test\Base as BaseTest;
+
+abstract class AbstractDSLTest extends BaseTest
+{
+ /**
+ * @param DSL $dsl
+ * @param string $methodName
+ * @param string $className
+ * @param array $arguments
+ */
+ protected function _assertImplemented(DSL $dsl, $methodName, $className, $arguments)
+ {
+ // Check method existence
+ $this->assertTrue(method_exists($dsl, $methodName));
+
+ // Check returned value
+ $return = call_user_func_array(array($dsl, $methodName), $arguments);
+ $this->assertTrue(class_exists($className), 'Class not exists but NotImplementedException is not thrown');
+ $this->assertInstanceOf($className, $return);
+
+ // Check method signature
+ $class = new \ReflectionClass($className);
+ $method = new \ReflectionMethod(get_class($dsl), $methodName);
+ if (!$class->hasMethod('__construct')) {
+ $this->assertEmpty($method->getParameters(), 'Constructor is not defined, but method has some parameters');
+ } else {
+ $this->_assertParametersEquals($class->getMethod('__construct')->getParameters(), $method->getParameters());
+ }
+ }
+
+ /**
+ * @param DSL $dsl
+ * @param string $name
+ */
+ protected function _assertNotImplemented(DSL $dsl, $methodName, $arguments)
+ {
+ try {
+ call_user_func(array($dsl, $methodName), $arguments);
+ $this->fail('NotImplementedException is not thrown');
+ } catch (NotImplementedException $ex) {
+ // expected
+ }
+ }
+
+ /**
+ * @param \ReflectionParameter[] $left
+ * @param \ReflectionParameter[] $right
+ */
+ protected function _assertParametersEquals($left, $right)
+ {
+ $this->assertEquals(count($left), count($right), 'Parameters count mismatch');
+
+ for ($i = 0; $i < count($left); $i++) {
+ $this->assertEquals($left[$i]->getName(), $right[$i]->getName(), 'Parameters names mismatch');
+ $this->assertEquals($left[$i]->isOptional(), $right[$i]->isOptional(), 'Parameters optionality mismatch');
+ $this->assertEquals($this->_getHintName($left[$i]), $this->_getHintName($right[$i]), 'Parameters typehints mismatch');
+ $this->assertEquals($this->_getDefaultValue($left[$i]), $this->_getDefaultValue($right[$i]), 'Default values mismatch');
+ }
+ }
+
+ /**
+ * @param \ReflectionParameter $param
+ *
+ * @return string|null
+ */
+ protected function _getDefaultValue(\ReflectionParameter $param)
+ {
+ if ($param->isOptional()) {
+ return $param->getDefaultValue();
+ }
+ }
+
+ /**
+ * @param \ReflectionParameter $param
+ *
+ * @return string|null
+ */
+ protected function _getHintName(\ReflectionParameter $param)
+ {
+ if (version_compare(phpversion(), '5.4', '>=') && $param->isCallable()) {
+ return 'callable';
+ }
+
+ if ($param->isArray()) {
+ return 'array';
+ }
+
+ if ($class = $param->getClass()) {
+ return $class->getName();
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AggregationTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AggregationTest.php
new file mode 100644
index 00000000..67c70862
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/AggregationTest.php
@@ -0,0 +1,58 @@
+<?php
+namespace Elastica\Test\QueryBuilder\DSL;
+
+use Elastica\Filter\Exists;
+use Elastica\QueryBuilder\DSL;
+
+class AggregationTest extends AbstractDSLTest
+{
+ /**
+ * @group unit
+ */
+ public function testType()
+ {
+ $aggregationDSL = new DSL\Aggregation();
+
+ $this->assertInstanceOf('Elastica\QueryBuilder\DSL', $aggregationDSL);
+ $this->assertEquals(DSL::TYPE_AGGREGATION, $aggregationDSL->getType());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testInterface()
+ {
+ $aggregationDSL = new DSL\Aggregation();
+
+ $this->_assertImplemented($aggregationDSL, 'avg', 'Elastica\Aggregation\Avg', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'cardinality', 'Elastica\Aggregation\Cardinality', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'date_histogram', 'Elastica\Aggregation\DateHistogram', array('name', 'field', 1));
+ $this->_assertImplemented($aggregationDSL, 'date_range', 'Elastica\Aggregation\DateRange', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'extended_stats', 'Elastica\Aggregation\ExtendedStats', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'filter', 'Elastica\Aggregation\Filter', array('name', new Exists('field')));
+ $this->_assertImplemented($aggregationDSL, 'filters', 'Elastica\Aggregation\Filters', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'geo_distance', 'Elastica\Aggregation\GeoDistance', array('name', 'field', 'origin'));
+ $this->_assertImplemented($aggregationDSL, 'geohash_grid', 'Elastica\Aggregation\GeohashGrid', array('name', 'field'));
+ $this->_assertImplemented($aggregationDSL, 'global_agg', 'Elastica\Aggregation\GlobalAggregation', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'histogram', 'Elastica\Aggregation\Histogram', array('name', 'field', 1));
+ $this->_assertImplemented($aggregationDSL, 'ipv4_range', 'Elastica\Aggregation\IpRange', array('name', 'field'));
+ $this->_assertImplemented($aggregationDSL, 'max', 'Elastica\Aggregation\Max', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'min', 'Elastica\Aggregation\Min', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'missing', 'Elastica\Aggregation\Missing', array('name', 'field'));
+ $this->_assertImplemented($aggregationDSL, 'nested', 'Elastica\Aggregation\Nested', array('name', 'path'));
+ $this->_assertImplemented($aggregationDSL, 'percentiles', 'Elastica\Aggregation\Percentiles', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'range', 'Elastica\Aggregation\Range', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'reverse_nested', 'Elastica\Aggregation\ReverseNested', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'scripted_metric', 'Elastica\Aggregation\ScriptedMetric', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'significant_terms', 'Elastica\Aggregation\SignificantTerms', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'stats', 'Elastica\Aggregation\Stats', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'sum', 'Elastica\Aggregation\Sum', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'terms', 'Elastica\Aggregation\Terms', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'top_hits', 'Elastica\Aggregation\TopHits', array('name'));
+ $this->_assertImplemented($aggregationDSL, 'value_count', 'Elastica\Aggregation\ValueCount', array('name', 'field'));
+
+ $this->_assertNotImplemented($aggregationDSL, 'children', array('name'));
+ $this->_assertNotImplemented($aggregationDSL, 'geo_bounds', array('name'));
+ $this->_assertNotImplemented($aggregationDSL, 'percentile_ranks', array('name'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/FilterTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/FilterTest.php
new file mode 100644
index 00000000..755bd18a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/FilterTest.php
@@ -0,0 +1,58 @@
+<?php
+namespace Elastica\Test\QueryBuilder\DSL;
+
+use Elastica\Filter\Exists;
+use Elastica\Query\Match;
+use Elastica\QueryBuilder\DSL;
+
+class FilterTest extends AbstractDSLTest
+{
+ /**
+ * @group unit
+ */
+ public function testType()
+ {
+ $filterDSL = new DSL\Filter();
+
+ $this->assertInstanceOf('Elastica\QueryBuilder\DSL', $filterDSL);
+ $this->assertEquals(DSL::TYPE_FILTER, $filterDSL->getType());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testInterface()
+ {
+ $filterDSL = new DSL\Filter();
+
+ $this->_assertImplemented($filterDSL, 'bool', 'Elastica\Filter\BoolFilter', array());
+ $this->_assertImplemented($filterDSL, 'bool_and', 'Elastica\Filter\BoolAnd', array(array(new Exists('field'))));
+ $this->_assertImplemented($filterDSL, 'bool_not', 'Elastica\Filter\BoolNot', array(new Exists('field')));
+ $this->_assertImplemented($filterDSL, 'bool_or', 'Elastica\Filter\BoolOr', array(array(new Exists('field'))));
+ $this->_assertImplemented($filterDSL, 'exists', 'Elastica\Filter\Exists', array('field'));
+ $this->_assertImplemented($filterDSL, 'geo_bounding_box', 'Elastica\Filter\GeoBoundingBox', array('field', array(1, 2)));
+ $this->_assertImplemented($filterDSL, 'geo_distance', 'Elastica\Filter\GeoDistance', array('key', 'location', 'distance'));
+ $this->_assertImplemented($filterDSL, 'geo_distance_range', 'Elastica\Filter\GeoDistanceRange', array('key', 'location'));
+ $this->_assertImplemented($filterDSL, 'geo_polygon', 'Elastica\Filter\GeoPolygon', array('key', array()));
+ $this->_assertImplemented($filterDSL, 'geo_shape_pre_indexed', 'Elastica\Filter\GeoShapePreIndexed', array('path', 'indexedId', 'indexedType', 'indexedIndex', 'indexedPath'));
+ $this->_assertImplemented($filterDSL, 'geo_shape_provided', 'Elastica\Filter\GeoShapeProvided', array('path', array()));
+ $this->_assertImplemented($filterDSL, 'geohash_cell', 'Elastica\Filter\GeohashCell', array('field', 'location'));
+ $this->_assertImplemented($filterDSL, 'has_child', 'Elastica\Filter\HasChild', array(new Match(), 'type'));
+ $this->_assertImplemented($filterDSL, 'has_parent', 'Elastica\Filter\HasParent', array(new Match(), 'type'));
+ $this->_assertImplemented($filterDSL, 'ids', 'Elastica\Filter\Ids', array('type', array()));
+ $this->_assertImplemented($filterDSL, 'indices', 'Elastica\Filter\Indices', array(new Exists('field'), array()));
+ $this->_assertImplemented($filterDSL, 'limit', 'Elastica\Filter\Limit', array(1));
+ $this->_assertImplemented($filterDSL, 'match_all', 'Elastica\Filter\MatchAll', array());
+ $this->_assertImplemented($filterDSL, 'missing', 'Elastica\Filter\Missing', array('field'));
+ $this->_assertImplemented($filterDSL, 'nested', 'Elastica\Filter\Nested', array());
+ $this->_assertImplemented($filterDSL, 'numeric_range', 'Elastica\Filter\NumericRange', array());
+ $this->_assertImplemented($filterDSL, 'prefix', 'Elastica\Filter\Prefix', array('field', 'prefix'));
+ $this->_assertImplemented($filterDSL, 'query', 'Elastica\Filter\Query', array(new Match()));
+ $this->_assertImplemented($filterDSL, 'range', 'Elastica\Filter\Range', array('field', array()));
+ $this->_assertImplemented($filterDSL, 'regexp', 'Elastica\Filter\Regexp', array('field', 'regex'));
+ $this->_assertImplemented($filterDSL, 'script', 'Elastica\Filter\Script', array('script'));
+ $this->_assertImplemented($filterDSL, 'term', 'Elastica\Filter\Term', array());
+ $this->_assertImplemented($filterDSL, 'terms', 'Elastica\Filter\Terms', array('field', array()));
+ $this->_assertImplemented($filterDSL, 'type', 'Elastica\Filter\Type', array('type'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/QueryTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/QueryTest.php
new file mode 100644
index 00000000..d4669119
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/QueryTest.php
@@ -0,0 +1,85 @@
+<?php
+namespace Elastica\Test\QueryBuilder\DSL;
+
+use Elastica\Filter\Exists;
+use Elastica\Query\Match;
+use Elastica\QueryBuilder\DSL;
+
+class QueryTest extends AbstractDSLTest
+{
+ /**
+ * @group unit
+ */
+ public function testType()
+ {
+ $queryDSL = new DSL\Query();
+
+ $this->assertInstanceOf('Elastica\QueryBuilder\DSL', $queryDSL);
+ $this->assertEquals(DSL::TYPE_QUERY, $queryDSL->getType());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testMatch()
+ {
+ $queryDSL = new DSL\Query();
+
+ $match = $queryDSL->match('field', 'match');
+ $this->assertEquals('match', $match->getParam('field'));
+ $this->assertInstanceOf('Elastica\Query\Match', $match);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testInterface()
+ {
+ $queryDSL = new DSL\Query();
+
+ $this->_assertImplemented($queryDSL, 'bool', 'Elastica\Query\BoolQuery', array());
+ $this->_assertImplemented($queryDSL, 'boosting', 'Elastica\Query\Boosting', array());
+ $this->_assertImplemented($queryDSL, 'common_terms', 'Elastica\Query\Common', array('field', 'query', 0.001));
+ $this->_assertImplemented($queryDSL, 'constant_score', 'Elastica\Query\ConstantScore', array(new Match()));
+ $this->_assertImplemented($queryDSL, 'dis_max', 'Elastica\Query\DisMax', array());
+ $this->_assertImplemented($queryDSL, 'filtered', 'Elastica\Query\Filtered', array(new Match(), new Exists('field')));
+ $this->_assertImplemented($queryDSL, 'function_score', 'Elastica\Query\FunctionScore', array());
+ $this->_assertImplemented($queryDSL, 'fuzzy', 'Elastica\Query\Fuzzy', array('field', 'type'));
+ $this->_assertImplemented($queryDSL, 'fuzzy_like_this', 'Elastica\Query\FuzzyLikeThis', array());
+ $this->_assertImplemented($queryDSL, 'has_child', 'Elastica\Query\HasChild', array(new Match()));
+ $this->_assertImplemented($queryDSL, 'has_parent', 'Elastica\Query\HasParent', array(new Match(), 'type'));
+ $this->_assertImplemented($queryDSL, 'ids', 'Elastica\Query\Ids', array('type', array()));
+ $this->_assertImplemented($queryDSL, 'match', 'Elastica\Query\Match', array('field', 'values'));
+ $this->_assertImplemented($queryDSL, 'match_all', 'Elastica\Query\MatchAll', array());
+ $this->_assertImplemented($queryDSL, 'more_like_this', 'Elastica\Query\MoreLikeThis', array());
+ $this->_assertImplemented($queryDSL, 'multi_match', 'Elastica\Query\MultiMatch', array());
+ $this->_assertImplemented($queryDSL, 'nested', 'Elastica\Query\Nested', array());
+ $this->_assertImplemented($queryDSL, 'prefix', 'Elastica\Query\Prefix', array());
+ $this->_assertImplemented($queryDSL, 'query_string', 'Elastica\Query\QueryString', array());
+ $this->_assertImplemented($queryDSL, 'range', 'Elastica\Query\Range', array('field', array()));
+ $this->_assertImplemented($queryDSL, 'regexp', 'Elastica\Query\Regexp', array('field', 'value', 1.0));
+ $this->_assertImplemented($queryDSL, 'simple_query_string', 'Elastica\Query\SimpleQueryString', array('query'));
+ $this->_assertImplemented($queryDSL, 'term', 'Elastica\Query\Term', array());
+ $this->_assertImplemented($queryDSL, 'terms', 'Elastica\Query\Terms', array('field', array()));
+ $this->_assertImplemented($queryDSL, 'top_children', 'Elastica\Query\TopChildren', array(new Match(), 'type'));
+ $this->_assertImplemented($queryDSL, 'wildcard', 'Elastica\Query\Wildcard', array());
+
+ $this->_assertNotImplemented($queryDSL, 'custom_boost_factor', array());
+ $this->_assertNotImplemented($queryDSL, 'custom_filters_score', array());
+ $this->_assertNotImplemented($queryDSL, 'custom_score', array());
+ $this->_assertNotImplemented($queryDSL, 'field', array());
+ $this->_assertNotImplemented($queryDSL, 'fuzzy_like_this_field', array());
+ $this->_assertNotImplemented($queryDSL, 'geo_shape', array());
+ $this->_assertNotImplemented($queryDSL, 'indices', array());
+ $this->_assertNotImplemented($queryDSL, 'minimum_should_match', array());
+ $this->_assertNotImplemented($queryDSL, 'more_like_this_field', array());
+ $this->_assertNotImplemented($queryDSL, 'span_first', array());
+ $this->_assertNotImplemented($queryDSL, 'span_multi_term', array());
+ $this->_assertNotImplemented($queryDSL, 'span_near', array());
+ $this->_assertNotImplemented($queryDSL, 'span_not', array());
+ $this->_assertNotImplemented($queryDSL, 'span_or', array());
+ $this->_assertNotImplemented($queryDSL, 'span_term', array());
+ $this->_assertNotImplemented($queryDSL, 'template', array());
+ $this->_assertNotImplemented($queryDSL, 'text', array());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/SuggestTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/SuggestTest.php
new file mode 100644
index 00000000..b70e0ba7
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/DSL/SuggestTest.php
@@ -0,0 +1,32 @@
+<?php
+namespace Elastica\Test\QueryBuilder\DSL;
+
+use Elastica\QueryBuilder\DSL;
+
+class SuggestTest extends AbstractDSLTest
+{
+ /**
+ * @group unit
+ */
+ public function testType()
+ {
+ $suggestDSL = new DSL\Suggest();
+
+ $this->assertInstanceOf('Elastica\QueryBuilder\DSL', $suggestDSL);
+ $this->assertEquals(DSL::TYPE_SUGGEST, $suggestDSL->getType());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testInterface()
+ {
+ $suggestDSL = new DSL\Suggest();
+
+ $this->_assertImplemented($suggestDSL, 'completion', 'Elastica\Suggest\Completion', array('name', 'field'));
+ $this->_assertImplemented($suggestDSL, 'phrase', 'Elastica\Suggest\Phrase', array('name', 'field'));
+ $this->_assertImplemented($suggestDSL, 'term', 'Elastica\Suggest\Term', array('name', 'field'));
+
+ $this->_assertNotImplemented($suggestDSL, 'context', array());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/VersionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/VersionTest.php
new file mode 100644
index 00000000..d92848a7
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilder/VersionTest.php
@@ -0,0 +1,67 @@
+<?php
+namespace Elastica\Test\QueryBuilder;
+
+use Elastica\QueryBuilder\DSL;
+use Elastica\QueryBuilder\Version;
+use Elastica\Test\Base as BaseTest;
+
+class VersionTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testVersions()
+ {
+ $dsl = array(
+ new DSL\Query(),
+ new DSL\Filter(),
+ new DSL\Aggregation(),
+ new DSL\Suggest(),
+ );
+
+ $versions = array(
+ new Version\Version090(),
+ new Version\Version100(),
+ new Version\Version110(),
+ new Version\Version120(),
+ new Version\Version130(),
+ new Version\Version140(),
+ new Version\Version150(),
+ );
+
+ foreach ($versions as $version) {
+ $this->assertVersions($version, $dsl);
+ }
+ }
+
+ private function assertVersions(Version $version, array $dsl)
+ {
+ foreach ($version->getQueries() as $query) {
+ $this->assertTrue(
+ method_exists($dsl[0], $query),
+ 'query "'.$query.'" in '.get_class($version).' must be defined in '.get_class($dsl[0])
+ );
+ }
+
+ foreach ($version->getFilters() as $filter) {
+ $this->assertTrue(
+ method_exists($dsl[1], $filter),
+ 'filter "'.$filter.'" in '.get_class($version).' must be defined in '.get_class($dsl[1])
+ );
+ }
+
+ foreach ($version->getAggregations() as $aggregation) {
+ $this->assertTrue(
+ method_exists($dsl[2], $aggregation),
+ 'aggregation "'.$aggregation.'" in '.get_class($version).' must be defined in '.get_class($dsl[2])
+ );
+ }
+
+ foreach ($version->getSuggesters() as $suggester) {
+ $this->assertTrue(
+ method_exists($dsl[3], $suggester),
+ 'suggester "'.$suggester.'" in '.get_class($version).' must be defined in '.get_class($dsl[3])
+ );
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilderTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilderTest.php
new file mode 100644
index 00000000..6cbfd37b
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryBuilderTest.php
@@ -0,0 +1,88 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Exception\QueryBuilderException;
+use Elastica\Query;
+use Elastica\QueryBuilder;
+use Elastica\Suggest;
+
+class QueryBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @group unit
+ */
+ public function testCustomDSL()
+ {
+ $qb = new QueryBuilder();
+
+ // test custom DSL
+ $qb->addDSL(new CustomDSL());
+
+ $this->assertTrue($qb->custom()->custom_method(), 'custom DSL execution failed');
+
+ // test custom DSL exception message
+ $exceptionMessage = '';
+ try {
+ $qb->invalid();
+ } catch (QueryBuilderException $exception) {
+ $exceptionMessage = $exception->getMessage();
+ }
+
+ $this->assertEquals('DSL "invalid" not supported', $exceptionMessage);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFacade()
+ {
+ $qb = new QueryBuilder();
+
+ // test one example QueryBuilder flow for each default DSL type
+ $this->assertInstanceOf('Elastica\Query\AbstractQuery', $qb->query()->match());
+ $this->assertInstanceOf('Elastica\Filter\AbstractFilter', $qb->filter()->bool());
+ $this->assertInstanceOf('Elastica\Aggregation\AbstractAggregation', $qb->aggregation()->avg('name'));
+ $this->assertInstanceOf('Elastica\Suggest\AbstractSuggest', $qb->suggest()->term('name', 'field'));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testFacadeException()
+ {
+ $qb = new QueryBuilder(new QueryBuilder\Version\Version100());
+
+ // undefined
+ $exceptionMessage = '';
+ try {
+ $qb->query()->invalid();
+ } catch (QueryBuilderException $exception) {
+ $exceptionMessage = $exception->getMessage();
+ }
+
+ $this->assertEquals('undefined query "invalid"', $exceptionMessage);
+
+ // unsupported
+ $exceptionMessage = '';
+ try {
+ $qb->aggregation()->top_hits('top_hits');
+ } catch (QueryBuilderException $exception) {
+ $exceptionMessage = $exception->getMessage();
+ }
+
+ $this->assertEquals('aggregation "top_hits" in Version100 not supported', $exceptionMessage);
+ }
+}
+
+class CustomDSL implements QueryBuilder\DSL
+{
+ public function getType()
+ {
+ return 'custom';
+ }
+
+ public function custom_method()
+ {
+ return true;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryTest.php
new file mode 100644
index 00000000..a39ab23a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/QueryTest.php
@@ -0,0 +1,458 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Exception\InvalidException;
+use Elastica\Facet\Terms;
+use Elastica\Query;
+use Elastica\Query\Builder;
+use Elastica\Query\Term;
+use Elastica\Query\Text;
+use Elastica\Script;
+use Elastica\ScriptFields;
+use Elastica\Suggest;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+
+class QueryTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testStringConversion()
+ {
+ $queryString = '{
+ "query" : {
+ "filtered" : {
+ "filter" : {
+ "range" : {
+ "due" : {
+ "gte" : "2011-07-18 00:00:00",
+ "lt" : "2011-07-25 00:00:00"
+ }
+ }
+ },
+ "query" : {
+ "text_phrase" : {
+ "title" : "Call back request"
+ }
+ }
+ }
+ },
+ "sort" : {
+ "due" : {
+ "reverse" : true
+ }
+ },
+ "fields" : [
+ "created", "assigned_to"
+ ]
+ }';
+
+ $query = new Builder($queryString);
+ $queryArray = $query->toArray();
+
+ $this->assertInternalType('array', $queryArray);
+
+ $this->assertEquals('2011-07-18 00:00:00', $queryArray['query']['filtered']['filter']['range']['due']['gte']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testRawQuery()
+ {
+ $textQuery = new Term(array('title' => 'test'));
+
+ $query1 = Query::create($textQuery);
+
+ $query2 = new Query();
+ $query2->setRawQuery(array('query' => array('term' => array('title' => 'test'))));
+
+ $this->assertEquals($query1->toArray(), $query2->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSuggestShouldNotRemoveOtherParameters()
+ {
+ $query1 = new Query();
+ $query2 = new Query();
+
+ $suggest = new Suggest();
+ $suggest->setGlobalText('test');
+
+ $query1->setSize(40);
+ $query1->setSuggest($suggest);
+
+ $query2->setSuggest($suggest);
+ $query2->setSize(40);
+
+ $this->assertEquals($query1->toArray(), $query2->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSuggestMustReturnQueryInstance()
+ {
+ $query = new Query();
+ $suggest = new Suggest();
+ $this->assertInstanceOf('Elastica\Query', $query->setSuggest($suggest));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testArrayQuery()
+ {
+ $query = array(
+ 'query' => array(
+ 'text' => array(
+ 'title' => 'test',
+ ),
+ ),
+ );
+
+ $query1 = Query::create($query);
+
+ $query2 = new Query();
+ $query2->setRawQuery(array('query' => array('text' => array('title' => 'test'))));
+
+ $this->assertEquals($query1->toArray(), $query2->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetSort()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'hello world')),
+ new Document(2, array('firstname' => 'guschti', 'lastname' => 'ruflin')),
+ new Document(3, array('firstname' => 'nicolas', 'lastname' => 'ruflin')),
+ ));
+
+ $queryTerm = new Term();
+ $queryTerm->setTerm('lastname', 'ruflin');
+
+ $index->refresh();
+
+ $query = Query::create($queryTerm);
+
+ // ASC order
+ $query->setSort(array(array('firstname' => array('order' => 'asc'))));
+ $resultSet = $type->search($query);
+ $this->assertEquals(2, $resultSet->count());
+
+ $first = $resultSet->current()->getData();
+ $second = $resultSet->next()->getData();
+
+ $this->assertEquals('guschti', $first['firstname']);
+ $this->assertEquals('nicolas', $second['firstname']);
+
+ // DESC order
+ $query->setSort(array('firstname' => array('order' => 'desc')));
+ $resultSet = $type->search($query);
+ $this->assertEquals(2, $resultSet->count());
+
+ $first = $resultSet->current()->getData();
+ $second = $resultSet->next()->getData();
+
+ $this->assertEquals('nicolas', $first['firstname']);
+ $this->assertEquals('guschti', $second['firstname']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddSort()
+ {
+ $query = new Query();
+ $sortParam = array('firstname' => array('order' => 'asc'));
+ $query->addSort($sortParam);
+
+ $this->assertEquals($query->getParam('sort'), array($sortParam));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetRawQuery()
+ {
+ $query = new Query();
+
+ $params = array('query' => 'test');
+ $query->setRawQuery($params);
+
+ $this->assertEquals($params, $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetFields()
+ {
+ $query = new Query();
+
+ $params = array('query' => 'test');
+
+ $query->setFields(array('firstname', 'lastname'));
+
+ $data = $query->toArray();
+
+ $this->assertContains('firstname', $data['fields']);
+ $this->assertContains('lastname', $data['fields']);
+ $this->assertCount(2, $data['fields']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testGetQuery()
+ {
+ $query = new Query();
+
+ try {
+ $query->getQuery();
+ $this->fail('should throw exception because query does not exist');
+ } catch (InvalidException $e) {
+ $this->assertTrue(true);
+ }
+
+ $termQuery = new Term();
+ $termQuery->setTerm('text', 'value');
+ $query->setQuery($termQuery);
+
+ $this->assertEquals($termQuery->toArray(), $query->getQuery());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetFacets()
+ {
+ $query = new Query();
+
+ $facet = new Terms('text');
+ $query->setFacets(array($facet));
+
+ $data = $query->toArray();
+
+ $this->assertArrayHasKey('facets', $data);
+ $this->assertEquals(array('text' => array('terms' => array())), $data['facets']);
+
+ $query->setFacets(array());
+
+ $this->assertArrayNotHasKey('facets', $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetQueryToArrayCast()
+ {
+ $query = new Query();
+ $termQuery = new Term();
+ $termQuery->setTerm('text', 'value');
+ $query->setQuery($termQuery);
+
+ $termQuery->setTerm('text', 'another value');
+
+ $anotherQuery = new Query();
+ $anotherQuery->setQuery($termQuery);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetQueryToArrayChangeQuery()
+ {
+ $query = new Query();
+ $termQuery = new Term();
+ $termQuery->setTerm('text', 'value');
+ $query->setQuery($termQuery);
+
+ $queryArray = $query->toArray();
+
+ $termQuery = $query->getQuery();
+ $termQuery['term']['text']['value'] = 'another value';
+
+ $this->assertEquals($queryArray, $query->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScriptFieldsToArrayCast()
+ {
+ $query = new Query();
+ $scriptFields = new ScriptFields();
+ $scriptFields->addScript('script', new Script('script'));
+
+ $query->setScriptFields($scriptFields);
+
+ $scriptFields->addScript('another script', new Script('another script'));
+
+ $anotherQuery = new Query();
+ $anotherQuery->setScriptFields($scriptFields);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddScriptFieldsToArrayCast()
+ {
+ $query = new Query();
+ $scriptField = new Script('script');
+
+ $query->addScriptField('script', $scriptField);
+
+ $scriptField->setScript('another script');
+
+ $anotherQuery = new Query();
+ $anotherQuery->addScriptField('script', $scriptField);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddFacetToArrayCast()
+ {
+ $query = new Query();
+ $facet = new Terms('text');
+
+ $query->addFacet($facet);
+
+ $facet->setName('another text');
+
+ $anotherQuery = new Query();
+ $anotherQuery->addFacet($facet);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddAggregationToArrayCast()
+ {
+ $query = new Query();
+ $aggregation = new \Elastica\Aggregation\Terms('text');
+
+ $query->addAggregation($aggregation);
+
+ $aggregation->setName('another text');
+
+ $anotherQuery = new Query();
+ $anotherQuery->addAggregation($aggregation);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSuggestToArrayCast()
+ {
+ $query = new Query();
+ $suggest = new Suggest();
+ $suggest->setGlobalText('text');
+
+ $query->setSuggest($suggest);
+
+ $suggest->setGlobalText('another text');
+
+ $anotherQuery = new Query();
+ $anotherQuery->setSuggest($suggest);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetRescoreToArrayCast()
+ {
+ $query = new Query();
+ $rescore = new \Elastica\Rescore\Query();
+ $rescore->setQueryWeight(1);
+
+ $query->setRescore($rescore);
+
+ $rescore->setQueryWeight(2);
+
+ $anotherQuery = new Query();
+ $anotherQuery->setRescore($rescore);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetPostFilterToArrayCast()
+ {
+ $query = new Query();
+ $postFilter = new \Elastica\Filter\Terms();
+ $postFilter->setTerms('key', array('term'));
+ $query->setPostFilter($postFilter);
+
+ $postFilter->setTerms('another key', array('another term'));
+
+ $anotherQuery = new Query();
+ $anotherQuery->setPostFilter($postFilter);
+
+ $this->assertNotEquals($query->toArray(), $anotherQuery->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testNoSource()
+ {
+ $index = $this->_createIndex();
+
+ $type = new Type($index, 'user');
+
+ // Adds 1 document to the index
+ $doc1 = new Document(1,
+ array('username' => 'ruflin', 'test' => array('2', '3', '5'))
+ );
+ $type->addDocument($doc1);
+
+ // To update index
+ $index->refresh();
+
+ $query = Query::create('ruflin');
+ $resultSet = $type->search($query);
+
+ // Disable source
+ $query->setSource(false);
+
+ $resultSetNoSource = $type->search($query);
+
+ $this->assertEquals(1, $resultSet->count());
+ $this->assertEquals(1, $resultSetNoSource->count());
+
+ // Tests if no source is in response except id
+ $result = $resultSetNoSource->current();
+ $this->assertEquals(1, $result->getId());
+ $this->assertEmpty($result->getData());
+
+ // Tests if source is in response except id
+ $result = $resultSet->current();
+ $this->assertEquals(1, $result->getId());
+ $this->assertNotEmpty($result->getData());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/RequestTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/RequestTest.php
new file mode 100644
index 00000000..987f2391
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/RequestTest.php
@@ -0,0 +1,95 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Connection;
+use Elastica\Request;
+use Elastica\Test\Base as BaseTest;
+
+class RequestTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testConstructor()
+ {
+ $path = 'test';
+ $method = Request::POST;
+ $query = array('no' => 'params');
+ $data = array('key' => 'value');
+
+ $request = new Request($path, $method, $data, $query);
+
+ $this->assertEquals($path, $request->getPath());
+ $this->assertEquals($method, $request->getMethod());
+ $this->assertEquals($query, $request->getQuery());
+ $this->assertEquals($data, $request->getData());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testInvalidConnection()
+ {
+ $request = new Request('', Request::GET);
+ $request->send();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSend()
+ {
+ $connection = new Connection();
+ $connection->setHost($this->_getHost());
+ $connection->setPort('9200');
+
+ $request = new Request('_status', Request::GET, array(), array(), $connection);
+
+ $response = $request->send();
+
+ $this->assertInstanceOf('Elastica\Response', $response);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToString()
+ {
+ $path = 'test';
+ $method = Request::POST;
+ $query = array('no' => 'params');
+ $data = array('key' => 'value');
+
+ $connection = new Connection();
+ $connection->setHost($this->_getHost());
+ $connection->setPort('9200');
+
+ $request = new Request($path, $method, $data, $query, $connection);
+
+ $data = $request->toArray();
+
+ $this->assertInternalType('array', $data);
+ $this->assertArrayHasKey('method', $data);
+ $this->assertArrayHasKey('path', $data);
+ $this->assertArrayHasKey('query', $data);
+ $this->assertArrayHasKey('data', $data);
+ $this->assertArrayHasKey('connection', $data);
+ $this->assertEquals($request->getMethod(), $data['method']);
+ $this->assertEquals($request->getPath(), $data['path']);
+ $this->assertEquals($request->getQuery(), $data['query']);
+ $this->assertEquals($request->getData(), $data['data']);
+ $this->assertInternalType('array', $data['connection']);
+ $this->assertArrayHasKey('host', $data['connection']);
+ $this->assertArrayHasKey('port', $data['connection']);
+ $this->assertEquals($request->getConnection()->getHost(), $data['connection']['host']);
+ $this->assertEquals($request->getConnection()->getPort(), $data['connection']['port']);
+
+ $string = $request->toString();
+
+ $this->assertInternalType('string', $string);
+
+ $string = (string) $request;
+ $this->assertInternalType('string', $string);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ResponseTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ResponseTest.php
new file mode 100644
index 00000000..e7b83ade
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ResponseTest.php
@@ -0,0 +1,205 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Facet\DateHistogram;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Request;
+use Elastica\Response;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class ResponseTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testClassHierarchy()
+ {
+ $facet = new DateHistogram('dateHist1');
+ $this->assertInstanceOf('Elastica\Facet\Histogram', $facet);
+ $this->assertInstanceOf('Elastica\Facet\AbstractFacet', $facet);
+ unset($facet);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testResponse()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('helloworld');
+
+ $mapping = new Mapping($type, array(
+ 'name' => array('type' => 'string', 'store' => 'no'),
+ 'dtmPosted' => array('type' => 'date', 'store' => 'no', 'format' => 'yyyy-MM-dd HH:mm:ss'),
+ ));
+ $type->setMapping($mapping);
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'nicolas ruflin', 'dtmPosted' => '2011-06-23 21:53:00')),
+ new Document(2, array('name' => 'raul martinez jr', 'dtmPosted' => '2011-06-23 09:53:00')),
+ new Document(3, array('name' => 'rachelle clemente', 'dtmPosted' => '2011-07-08 08:53:00')),
+ new Document(4, array('name' => 'elastica search', 'dtmPosted' => '2011-07-08 01:53:00')),
+ ));
+
+ $query = new Query();
+ $query->setQuery(new MatchAll());
+ $index->refresh();
+
+ $resultSet = $type->search($query);
+
+ $engineTime = $resultSet->getResponse()->getEngineTime();
+ $shardsStats = $resultSet->getResponse()->getShardsStatistics();
+
+ $this->assertInternalType('int', $engineTime);
+ $this->assertTrue(is_array($shardsStats));
+ $this->assertArrayHasKey('total', $shardsStats);
+ $this->assertArrayHasKey('successful', $shardsStats);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testIsOk()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $doc = new Document(1, array('name' => 'ruflin'));
+ $response = $type->addDocument($doc);
+
+ $this->assertTrue($response->isOk());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testIsOkMultiple()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $docs = array(
+ new Document(1, array('name' => 'ruflin')),
+ new Document(2, array('name' => 'ruflin')),
+ );
+ $response = $type->addDocuments($docs);
+
+ $this->assertTrue($response->isOk());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsOkBulkWithErrorsField()
+ {
+ $response = new Response(json_encode(array(
+ 'took' => 213,
+ 'errors' => false,
+ 'items' => array(
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707891', '_version' => 4, 'status' => 200)),
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707893', '_version' => 4, 'status' => 200)),
+ ),
+ )));
+
+ $this->assertTrue($response->isOk());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsNotOkBulkWithErrorsField()
+ {
+ $response = new Response(json_encode(array(
+ 'took' => 213,
+ 'errors' => true,
+ 'items' => array(
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707891', '_version' => 4, 'status' => 200)),
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707893', '_version' => 4, 'status' => 200)),
+ ),
+ )));
+
+ $this->assertFalse($response->isOk());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsOkBulkItemsWithOkField()
+ {
+ $response = new Response(json_encode(array(
+ 'took' => 213,
+ 'items' => array(
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707891', '_version' => 4, 'ok' => true)),
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707893', '_version' => 4, 'ok' => true)),
+ ),
+ )));
+
+ $this->assertTrue($response->isOk());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsNotOkBulkItemsWithOkField()
+ {
+ $response = new Response(json_encode(array(
+ 'took' => 213,
+ 'items' => array(
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707891', '_version' => 4, 'ok' => true)),
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707893', '_version' => 4, 'ok' => false)),
+ ),
+ )));
+
+ $this->assertFalse($response->isOk());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsOkBulkItemsWithStatusField()
+ {
+ $response = new Response(json_encode(array(
+ 'took' => 213,
+ 'items' => array(
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707891', '_version' => 4, 'status' => 200)),
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707893', '_version' => 4, 'status' => 200)),
+ ),
+ )));
+
+ $this->assertTrue($response->isOk());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testIsNotOkBulkItemsWithStatusField()
+ {
+ $response = new Response(json_encode(array(
+ 'took' => 213,
+ 'items' => array(
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707891', '_version' => 4, 'status' => 200)),
+ array('index' => array('_index' => 'rohlik', '_type' => 'grocery', '_id' => '707893', '_version' => 4, 'status' => 301)),
+ ),
+ )));
+
+ $this->assertFalse($response->isOk());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetDataEmpty()
+ {
+ $index = $this->_createIndex();
+
+ $response = $index->request(
+ 'non-existant-type/_mapping',
+ Request::GET
+ )->getData();
+
+ $this->assertEquals(0, count($response));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ResultSetTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ResultSetTest.php
new file mode 100644
index 00000000..be76d4a2
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ResultSetTest.php
@@ -0,0 +1,95 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Result;
+use Elastica\Test\Base as BaseTest;
+
+class ResultSetTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGetters()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'elastica search')),
+ new Document(2, array('name' => 'elastica library')),
+ new Document(3, array('name' => 'elastica test')),
+ ));
+ $index->refresh();
+
+ $resultSet = $type->search('elastica search');
+
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSet);
+ $this->assertEquals(3, $resultSet->getTotalHits());
+ $this->assertGreaterThan(0, $resultSet->getMaxScore());
+ $this->assertInternalType('array', $resultSet->getResults());
+ $this->assertEquals(3, count($resultSet));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testArrayAccess()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'elastica search')),
+ new Document(2, array('name' => 'elastica library')),
+ new Document(3, array('name' => 'elastica test')),
+ ));
+ $index->refresh();
+
+ $resultSet = $type->search('elastica search');
+
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSet);
+ $this->assertInstanceOf('Elastica\Result', $resultSet[0]);
+ $this->assertInstanceOf('Elastica\Result', $resultSet[1]);
+ $this->assertInstanceOf('Elastica\Result', $resultSet[2]);
+
+ $this->assertFalse(isset($resultSet[3]));
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testInvalidOffsetCreation()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $doc = new Document(1, array('name' => 'elastica search'));
+ $type->addDocument($doc);
+ $index->refresh();
+
+ $resultSet = $type->search('elastica search');
+
+ $result = new Result(array('_id' => 'fakeresult'));
+ $resultSet[1] = $result;
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testInvalidOffsetGet()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $doc = new Document(1, array('name' => 'elastica search'));
+ $type->addDocument($doc);
+ $index->refresh();
+
+ $resultSet = $type->search('elastica search');
+
+ return $resultSet[3];
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ResultTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ResultTest.php
new file mode 100644
index 00000000..a905fcc5
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ResultTest.php
@@ -0,0 +1,131 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Result;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type\Mapping;
+
+class ResultTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGetters()
+ {
+ // Creates a new index 'xodoa' and a type 'user' inside this index
+ $typeName = 'user';
+
+ $index = $this->_createIndex();
+ $type = $index->getType($typeName);
+
+ // Adds 1 document to the index
+ $docId = 3;
+ $doc1 = new Document($docId, array('username' => 'hans'));
+ $type->addDocument($doc1);
+
+ // Refreshes index
+ $index->refresh();
+
+ $resultSet = $type->search('hans');
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $result = $resultSet->current();
+
+ $this->assertInstanceOf('Elastica\Result', $result);
+ $this->assertEquals($index->getName(), $result->getIndex());
+ $this->assertEquals($typeName, $result->getType());
+ $this->assertEquals($docId, $result->getId());
+ $this->assertGreaterThan(0, $result->getScore());
+ $this->assertInternalType('array', $result->getData());
+ $this->assertTrue(isset($result->username));
+ $this->assertEquals('hans', $result->username);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetIdNoSource()
+ {
+ // Creates a new index 'xodoa' and a type 'user' inside this index
+ $indexName = 'xodoa';
+ $typeName = 'user';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $type = $index->getType($typeName);
+
+ $mapping = new Mapping($type);
+ $mapping->disableSource();
+ $mapping->send();
+
+ // Adds 1 document to the index
+ $docId = 3;
+ $doc1 = new Document($docId, array('username' => 'hans'));
+ $type->addDocument($doc1);
+
+ // Refreshes index
+ $index->refresh();
+
+ $resultSet = $type->search('hans');
+
+ $this->assertEquals(1, $resultSet->count());
+
+ $result = $resultSet->current();
+
+ $this->assertEquals(array(), $result->getSource());
+ $this->assertInstanceOf('Elastica\Result', $result);
+ $this->assertEquals($indexName, $result->getIndex());
+ $this->assertEquals($typeName, $result->getType());
+ $this->assertEquals($docId, $result->getId());
+ $this->assertGreaterThan(0, $result->getScore());
+ $this->assertInternalType('array', $result->getData());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetTotalTimeReturnsExpectedResults()
+ {
+ $typeName = 'user';
+ $index = $this->_createIndex();
+ $type = $index->getType($typeName);
+
+ // Adds 1 document to the index
+ $docId = 3;
+ $doc1 = new Document($docId, array('username' => 'hans'));
+ $type->addDocument($doc1);
+
+ // Refreshes index
+ $index->refresh();
+
+ $resultSet = $type->search('hans');
+
+ $this->assertNotNull($resultSet->getTotalTime(), 'Get Total Time should never be a null value');
+ $this->assertEquals(
+ 'integer',
+ getType($resultSet->getTotalTime()),
+ 'Total Time should be an integer'
+ );
+ }
+
+ /**
+ * @group unit
+ */
+ public function testHasFields()
+ {
+ $data = array('value set');
+
+ $result = new Result(array());
+ $this->assertFalse($result->hasFields());
+
+ $result = new Result(array('_source' => $data));
+ $this->assertFalse($result->hasFields());
+
+ $result = new Result(array('fields' => $data));
+ $this->assertTrue($result->hasFields());
+ $this->assertEquals($data, $result->getFields());
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ScanAndScrollTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScanAndScrollTest.php
new file mode 100644
index 00000000..9f06f9e6
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScanAndScrollTest.php
@@ -0,0 +1,78 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\ResultSet;
+use Elastica\ScanAndScroll;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+
+class ScanAndScrollTest extends BaseTest
+{
+ /**
+ * Full foreach test.
+ *
+ * @gropu functional
+ */
+ public function testForeach()
+ {
+ $scanAndScroll = new ScanAndScroll($this->_prepareSearch(), '1m', 2);
+ $docCount = 0;
+
+ /** @var ResultSet $resultSet */
+ foreach ($scanAndScroll as $scrollId => $resultSet) {
+ $docCount += $resultSet->count();
+ }
+
+ /*
+ * number of loops and documents per iteration may fluctuate
+ * => only test end results
+ */
+ $this->assertEquals(12, $docCount);
+ }
+
+ /**
+ * query size revert options.
+ *
+ * @group functional
+ */
+ public function testQuerySizeRevert()
+ {
+ $search = $this->_prepareSearch();
+ $search->getQuery()->setSize(9);
+
+ $scanAndScroll = new ScanAndScroll($search);
+
+ $scanAndScroll->rewind();
+ $this->assertEquals(9, $search->getQuery()->getParam('size'));
+
+ $scanAndScroll->next();
+ $this->assertEquals(9, $search->getQuery()->getParam('size'));
+ }
+
+ /**
+ * index: 12 docs, 2 shards.
+ *
+ * @return Search
+ */
+ private function _prepareSearch()
+ {
+ $index = $this->_createIndex('', true, 2);
+ $index->refresh();
+
+ $docs = array();
+ for ($x = 1; $x <= 12; $x++) {
+ $docs[] = new Document($x, array('id' => $x, 'key' => 'value'));
+ }
+
+ $type = $index->getType('scanAndScrollTest');
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $search = new Search($this->_getClient());
+ $search->addIndex($index)->addType($type);
+
+ return $search;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptFieldsTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptFieldsTest.php
new file mode 100644
index 00000000..5448209d
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptFieldsTest.php
@@ -0,0 +1,93 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Script;
+use Elastica\ScriptFields;
+use Elastica\Test\Base as BaseTest;
+
+class ScriptFieldsTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testNewScriptFields()
+ {
+ $script = new Script('1 + 2');
+
+ // addScript
+ $scriptFields = new ScriptFields();
+ $scriptFields->addScript('test', $script);
+ $this->assertEquals($scriptFields->getParam('test'), $script->toArray());
+
+ // setScripts
+ $scriptFields = new ScriptFields();
+ $scriptFields->setScripts(array(
+ 'test' => $script,
+ ));
+ $this->assertEquals($scriptFields->getParam('test'), $script->toArray());
+
+ // Constructor
+ $scriptFields = new ScriptFields(array(
+ 'test' => $script,
+ ));
+ $this->assertEquals($scriptFields->getParam('test'), $script->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScriptFields()
+ {
+ $query = new Query();
+ $script = new Script('1 + 2');
+
+ $scriptFields = new ScriptFields(array(
+ 'test' => $script,
+ ));
+ $query->setScriptFields($scriptFields);
+ $this->assertEquals($query->getParam('script_fields'), $scriptFields->toArray());
+
+ $query->setScriptFields(array(
+ 'test' => $script,
+ ));
+ $this->assertEquals($query->getParam('script_fields'), $scriptFields->toArray());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testNameException()
+ {
+ $script = new Script('1 + 2');
+ $scriptFields = new ScriptFields(array($script));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQuery()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $doc = new Document(1, array('firstname' => 'guschti', 'lastname' => 'ruflin'));
+ $type->addDocument($doc);
+ $index->refresh();
+
+ $query = new Query();
+ $script = new Script('1 + 2');
+ $scriptFields = new ScriptFields(array(
+ 'test' => $script,
+ ));
+ $query->setScriptFields($scriptFields);
+
+ $resultSet = $type->search($query);
+ $first = $resultSet->current()->getData();
+
+ // 1 + 2
+ $this->assertEquals(3, $first['test'][0]);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptTest.php
new file mode 100644
index 00000000..b42d8646
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScriptTest.php
@@ -0,0 +1,169 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Script;
+use Elastica\Test\Base as BaseTest;
+
+class ScriptTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testConstructor()
+ {
+ $value = "_score * doc['my_numeric_field'].value";
+ $script = new Script($value);
+
+ $expected = array(
+ 'script' => $value,
+ );
+ $this->assertEquals($value, $script->getScript());
+ $this->assertEquals($expected, $script->toArray());
+
+ $params = array(
+ 'param1' => 'one',
+ 'param2' => 10,
+ );
+
+ $script = new Script($value, $params);
+
+ $expected = array(
+ 'script' => $value,
+ 'params' => $params,
+ );
+
+ $this->assertEquals($value, $script->getScript());
+ $this->assertEquals($params, $script->getParams());
+ $this->assertEquals($expected, $script->toArray());
+
+ $lang = 'mvel';
+
+ $script = new Script($value, $params, $lang);
+
+ $expected = array(
+ 'script' => $value,
+ 'params' => $params,
+ 'lang' => $lang,
+ );
+
+ $this->assertEquals($value, $script->getScript());
+ $this->assertEquals($params, $script->getParams());
+ $this->assertEquals($lang, $script->getLang());
+ $this->assertEquals($expected, $script->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreateString()
+ {
+ $string = '_score * 2.0';
+ $script = Script::create($string);
+
+ $this->assertInstanceOf('Elastica\Script', $script);
+
+ $this->assertEquals($string, $script->getScript());
+
+ $expected = array(
+ 'script' => $string,
+ );
+ $this->assertEquals($expected, $script->toArray());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreateScript()
+ {
+ $data = new Script('_score * 2.0');
+
+ $script = Script::create($data);
+
+ $this->assertInstanceOf('Elastica\Script', $script);
+ $this->assertSame($data, $script);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCreateArray()
+ {
+ $string = '_score * 2.0';
+ $lang = 'mvel';
+ $params = array(
+ 'param1' => 'one',
+ 'param2' => 1,
+ );
+ $array = array(
+ 'script' => $string,
+ 'lang' => $lang,
+ 'params' => $params,
+ );
+
+ $script = Script::create($array);
+
+ $this->assertInstanceOf('Elastica\Script', $script);
+
+ $this->assertEquals($string, $script->getScript());
+ $this->assertEquals($params, $script->getParams());
+ $this->assertEquals($lang, $script->getLang());
+
+ $this->assertEquals($array, $script->toArray());
+ }
+
+ /**
+ * @group unit
+ * @dataProvider dataProviderCreateInvalid
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testCreateInvalid($data)
+ {
+ Script::create($data);
+ }
+
+ /**
+ * @return array
+ */
+ public function dataProviderCreateInvalid()
+ {
+ return array(
+ array(
+ new \stdClass(),
+ ),
+ array(
+ array('params' => array('param1' => 'one')),
+ ),
+ array(
+ array('script' => '_score * 2.0', 'params' => 'param'),
+ ),
+ );
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetLang()
+ {
+ $script = new Script('foo', array(), Script::LANG_GROOVY);
+ $this->assertEquals(Script::LANG_GROOVY, $script->getLang());
+
+ $script->setLang(Script::LANG_PYTHON);
+ $this->assertEquals(Script::LANG_PYTHON, $script->getLang());
+
+ $this->assertInstanceOf('Elastica\Script', $script->setLang(Script::LANG_PYTHON));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetScript()
+ {
+ $script = new Script('foo');
+ $this->assertEquals('foo', $script->getScript());
+
+ $script->setScript('bar');
+ $this->assertEquals('bar', $script->getScript());
+
+ $this->assertInstanceOf('Elastica\Script', $script->setScript('foo'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ScrollTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScrollTest.php
new file mode 100644
index 00000000..df5b0317
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ScrollTest.php
@@ -0,0 +1,105 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\ResultSet;
+use Elastica\Scroll;
+use Elastica\Search;
+
+class ScrollTest extends Base
+{
+ /**
+ * Full foreach test.
+ *
+ * @group functional
+ */
+ public function testForeach()
+ {
+ $scroll = new Scroll($this->_prepareSearch());
+ $count = 1;
+
+ /** @var ResultSet $resultSet */
+ foreach ($scroll as $scrollId => $resultSet) {
+ $this->assertNotEmpty($scrollId);
+
+ $results = $resultSet->getResults();
+ switch (true) {
+ case $count === 1:
+ // hits: 1 - 5
+ $this->assertEquals(5, $resultSet->count());
+ $this->assertEquals('1', $results[0]->getId());
+ $this->assertEquals('5', $results[4]->getId());
+ break;
+ case $count === 2:
+ // hits: 6 - 10
+ $this->assertEquals(5, $resultSet->count());
+ $this->assertEquals('6', $results[0]->getId());
+ $this->assertEquals('10', $results[4]->getId());
+ break;
+ case $count === 3:
+ // hit: 11
+ $this->assertEquals(1, $resultSet->count());
+ $this->assertEquals('11', $results[0]->getId());
+ break;
+ case $count === 4:
+ $this->assertEquals(0, $resultSet->count());
+ break;
+ default:
+ $this->fail('too many iterations');
+ }
+
+ $count++;
+ }
+ }
+
+ /**
+ * Scroll must not overwrite options.
+ *
+ * @group functional
+ */
+ public function testSearchRevert()
+ {
+ $search = $this->_prepareSearch();
+
+ $search->setOption(Search::OPTION_SCROLL, 'must');
+ $search->setOption(Search::OPTION_SCROLL_ID, 'not');
+ $search->setOption(Search::OPTION_SEARCH_TYPE, 'change');
+ $old = $search->getOptions();
+
+ $scroll = new Scroll($search);
+
+ $scroll->rewind();
+ $this->assertEquals($old, $search->getOptions());
+
+ $scroll->next();
+ $this->assertEquals($old, $search->getOptions());
+ }
+
+ /**
+ * index: 11 docs
+ * query size: 5.
+ *
+ * @return Search
+ */
+ private function _prepareSearch()
+ {
+ $index = $this->_createIndex();
+ $index->refresh();
+
+ $docs = array();
+ for ($x = 1; $x <= 11; $x++) {
+ $docs[] = new Document($x, array('id' => $x, 'key' => 'value'));
+ }
+
+ $type = $index->getType('scrollTest');
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $search = new Search($this->_getClient());
+ $search->addIndex($index)->addType($type);
+ $search->getQuery()->setSize(5);
+
+ return $search;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/SearchTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/SearchTest.php
new file mode 100644
index 00000000..905f8462
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/SearchTest.php
@@ -0,0 +1,647 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Aggregation;
+use Elastica\Document;
+use Elastica\Exception\ResponseException;
+use Elastica\Index;
+use Elastica\Query;
+use Elastica\Query\FunctionScore;
+use Elastica\Query\MatchAll;
+use Elastica\Query\QueryString;
+use Elastica\Script;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+
+class SearchTest extends BaseTest
+{
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $this->assertInstanceOf('Elastica\Search', $search);
+ $this->assertSame($client, $search->getClient());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddIndex()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $index1 = $this->_createIndex();
+ $index2 = $this->_createIndex();
+
+ $search->addIndex($index1);
+ $indices = $search->getIndices();
+
+ $this->assertEquals(1, count($indices));
+
+ $search->addIndex($index2);
+ $indices = $search->getIndices();
+
+ $this->assertEquals(2, count($indices));
+
+ $this->assertTrue(in_array($index1->getName(), $indices));
+ $this->assertTrue(in_array($index2->getName(), $indices));
+
+ // Add string
+ $search->addIndex('test3');
+ $indices = $search->getIndices();
+
+ $this->assertEquals(3, count($indices));
+ $this->assertTrue(in_array('test3', $indices));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddIndices()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $indices = array();
+ $indices[] = $client->getIndex('elastica_test1');
+ $indices[] = $client->getIndex('elastica_test2');
+
+ $search->addIndices($indices);
+
+ $this->assertEquals(2, count($search->getIndices()));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddType()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $index = $this->_createIndex();
+
+ $type1 = $index->getType('type1');
+ $type2 = $index->getType('type2');
+
+ $this->assertEquals(array(), $search->getTypes());
+
+ $search->addType($type1);
+ $types = $search->getTypes();
+
+ $this->assertEquals(1, count($types));
+
+ $search->addType($type2);
+ $types = $search->getTypes();
+
+ $this->assertEquals(2, count($types));
+
+ $this->assertTrue(in_array($type1->getName(), $types));
+ $this->assertTrue(in_array($type2->getName(), $types));
+
+ // Add string
+ $search->addType('test3');
+ $types = $search->getTypes();
+
+ $this->assertEquals(3, count($types));
+ $this->assertTrue(in_array('test3', $types));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddTypes()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $index = $client->getIndex('foo');
+
+ $types = array();
+ $types[] = $index->getType('type1');
+ $types[] = $index->getType('type2');
+
+ $search->addTypes($types);
+
+ $this->assertEquals(2, count($search->getTypes()));
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testAddTypeInvalid()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $search->addType(new \stdClass());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testAddIndexInvalid()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $search->addIndex(new \stdClass());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testAddNumericIndex()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $search->addIndex(1);
+
+ $this->assertContains('1', $search->getIndices(), 'Make sure it has been added and converted to string');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetPath()
+ {
+ $client = $this->_getClient();
+ $search1 = new Search($client);
+ $search2 = new Search($client);
+
+ $index1 = $this->_createIndex();
+ $index2 = $this->_createIndex();
+
+ $type1 = $index1->getType('type1');
+ $type2 = $index1->getType('type2');
+
+ // No index
+ $this->assertEquals('/_search', $search1->getPath());
+
+ // Only index
+ $search1->addIndex($index1);
+ $this->assertEquals($index1->getName().'/_search', $search1->getPath());
+
+ // MUltiple index, no types
+ $search1->addIndex($index2);
+ $this->assertEquals($index1->getName().','.$index2->getName().'/_search', $search1->getPath());
+
+ // Single type, no index
+ $search2->addType($type1);
+ $this->assertEquals('_all/'.$type1->getName().'/_search', $search2->getPath());
+
+ // Multiple types
+ $search2->addType($type2);
+ $this->assertEquals('_all/'.$type1->getName().','.$type2->getName().'/_search', $search2->getPath());
+
+ // Combine index and types
+ $search2->addIndex($index1);
+ $this->assertEquals($index1->getName().'/'.$type1->getName().','.$type2->getName().'/_search', $search2->getPath());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchRequest()
+ {
+ $client = $this->_getClient();
+ $search1 = new Search($client);
+
+ $index1 = $this->_createIndex();
+ $index2 = $this->_createIndex();
+
+ $type1 = $index1->getType('hello1');
+
+ $result = $search1->search(array());
+ $this->assertFalse($result->getResponse()->hasError());
+
+ $search1->addIndex($index1);
+
+ $result = $search1->search(array());
+ $this->assertFalse($result->getResponse()->hasError());
+
+ $search1->addIndex($index2);
+
+ $result = $search1->search(array());
+ $this->assertFalse($result->getResponse()->hasError());
+
+ $search1->addType($type1);
+
+ $result = $search1->search(array());
+ $this->assertFalse($result->getResponse()->hasError());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchScrollRequest()
+ {
+ $client = $this->_getClient();
+
+ $index = $this->_createIndex();
+ $type = $index->getType('scrolltest');
+
+ $docs = array();
+ for ($x = 1; $x <= 10; $x++) {
+ $docs[] = new Document($x, array('id' => $x, 'testscroll' => 'jbafford'));
+ }
+
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $search = new Search($client);
+ $search->addIndex($index)->addType($type);
+ $result = $search->search(array(), array(
+ Search::OPTION_SEARCH_TYPE => Search::OPTION_SEARCH_TYPE_SCAN,
+ Search::OPTION_SCROLL => '5m',
+ Search::OPTION_SIZE => 5,
+ ));
+ $this->assertFalse($result->getResponse()->hasError());
+
+ $scrollId = $result->getResponse()->getScrollId();
+ $this->assertNotEmpty($scrollId);
+
+ //There are 10 items, and we're scrolling with a size of 5
+ //So we should get two results of 5 items, and then no items
+ //We should also have sent the raw scroll_id as the HTTP request body
+ $search = new Search($client);
+ $result = $search->search(array(), array(
+ Search::OPTION_SCROLL => '5m',
+ Search::OPTION_SCROLL_ID => $scrollId,
+ ));
+ $this->assertFalse($result->getResponse()->hasError());
+ $this->assertEquals(5, count($result->getResults()));
+ $this->assertArrayNotHasKey(Search::OPTION_SCROLL_ID, $search->getClient()->getLastRequest()->getQuery());
+ $this->assertEquals($scrollId, $search->getClient()->getLastRequest()->getData());
+
+ $result = $search->search(array(), array(
+ Search::OPTION_SCROLL => '5m',
+ Search::OPTION_SCROLL_ID => $scrollId,
+ ));
+ $this->assertFalse($result->getResponse()->hasError());
+ $this->assertEquals(5, count($result->getResults()));
+ $this->assertArrayNotHasKey(Search::OPTION_SCROLL_ID, $search->getClient()->getLastRequest()->getQuery());
+ $this->assertEquals($scrollId, $search->getClient()->getLastRequest()->getData());
+
+ $result = $search->search(array(), array(
+ Search::OPTION_SCROLL => '5m',
+ Search::OPTION_SCROLL_ID => $scrollId,
+ ));
+ $this->assertFalse($result->getResponse()->hasError());
+ $this->assertEquals(0, count($result->getResults()));
+ $this->assertArrayNotHasKey(Search::OPTION_SCROLL_ID, $search->getClient()->getLastRequest()->getQuery());
+ $this->assertEquals($scrollId, $search->getClient()->getLastRequest()->getData());
+ }
+
+ /**
+ * Default Limit tests for \Elastica\Search.
+ *
+ * @group functional
+ */
+ public function testLimitDefaultSearch()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $type = $index->getType('zeroType');
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(2, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(3, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(4, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(5, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(6, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(7, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(8, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(9, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(10, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(11, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ ));
+ $index->refresh();
+
+ $search->addIndex($index)->addType($type);
+
+ // default limit results (default limit is 10)
+ $resultSet = $search->search('farrelley');
+ $this->assertEquals(10, $resultSet->count());
+
+ // limit = 1
+ $resultSet = $search->search('farrelley', 1);
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testArrayConfigSearch()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $docs = array();
+ for ($i = 0; $i < 11; $i++) {
+ $docs[] = new Document($i, array('id' => 1, 'email' => 'test@test.com', 'username' => 'test'));
+ }
+
+ $type = $index->getType('zeroType');
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $search->addIndex($index)->addType($type);
+ //Backward compatibility, integer => limit
+ // default limit results (default limit is 10)
+ $resultSet = $search->search('test');
+ $this->assertEquals(10, $resultSet->count());
+
+ // limit = 1
+ $resultSet = $search->search('test', 1);
+ $this->assertEquals(1, $resultSet->count());
+
+ //Array with limit
+ $resultSet = $search->search('test', array('limit' => 2));
+ $this->assertEquals(2, $resultSet->count());
+
+ //Array with size
+ $resultSet = $search->search('test', array('size' => 2));
+ $this->assertEquals(2, $resultSet->count());
+
+ //Array with from
+ $resultSet = $search->search('test', array('from' => 10));
+ $this->assertEquals(10, $resultSet->current()->getId());
+
+ //Array with routing
+ $resultSet = $search->search('test', array('routing' => 'r1,r2'));
+ $this->assertEquals(10, $resultSet->count());
+
+ //Array with limit and routing
+ $resultSet = $search->search('test', array('limit' => 5, 'routing' => 'r1,r2'));
+ $this->assertEquals(5, $resultSet->count());
+
+ //Search types
+ $resultSet = $search->search('test', array('limit' => 5, 'search_type' => 'count'));
+ $this->assertTrue(($resultSet->count() === 0) && $resultSet->getTotalHits() === 11);
+
+ //Timeout - this one is a bit more tricky to test
+ $mockResponse = new \Elastica\Response(json_encode(array('timed_out' => true)));
+ $client = $this->getMockBuilder('Elastica\\Client')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $client->method('request')
+ ->will($this->returnValue($mockResponse));
+ $search = new Search($client);
+ $script = new Script('Thread.sleep(100); return _score;');
+ $query = new FunctionScore();
+ $query->addScriptScoreFunction($script);
+ $resultSet = $search->search($query, array('timeout' => 50));
+ $this->assertTrue($resultSet->hasTimedOut());
+
+ // Throws InvalidException
+ $resultSet = $search->search('test', array('invalid_option' => 'invalid_option_value'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchWithVersionOption()
+ {
+ $index = $this->_createIndex();
+ $doc = new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'ruflin'));
+ $index->getType('test')->addDocument($doc);
+ $index->refresh();
+
+ $search = new Search($index->getClient());
+ $search->addIndex($index);
+
+ // Version param should not be inside by default
+ $results = $search->search(new MatchAll());
+ $hit = $results->current();
+ $this->assertEquals(array(), $hit->getParam('_version'));
+
+ // Added version param to result
+ $results = $search->search(new MatchAll(), array('version' => true));
+ $hit = $results->current();
+ $this->assertEquals(1, $hit->getParam('_version'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCountRequest()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $type = $index->getType('zeroType');
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(2, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(3, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(4, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(5, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(6, array('id' => 1, 'email' => 'test@test.com', 'username' => 'marley')),
+ new Document(7, array('id' => 1, 'email' => 'test@test.com', 'username' => 'marley')),
+ new Document(8, array('id' => 1, 'email' => 'test@test.com', 'username' => 'marley')),
+ new Document(9, array('id' => 1, 'email' => 'test@test.com', 'username' => 'marley')),
+ new Document(10, array('id' => 1, 'email' => 'test@test.com', 'username' => 'marley')),
+ new Document(11, array('id' => 1, 'email' => 'test@test.com', 'username' => 'marley')),
+ ));
+ $index->refresh();
+
+ $search->addIndex($index)->addType($type);
+
+ $count = $search->count('farrelley');
+ $this->assertEquals(5, $count);
+
+ $count = $search->count('marley');
+ $this->assertEquals(6, $count);
+
+ $count = $search->count();
+ $this->assertEquals(6, $count, 'Uses previous query set');
+
+ $count = $search->count(new MatchAll());
+ $this->assertEquals(11, $count);
+
+ $count = $search->count('bunny');
+ $this->assertEquals(0, $count);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testEmptySearch()
+ {
+ $client = $this->_getClient();
+ $search = new Search($client);
+
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+ $type = $index->getType('zeroType');
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(2, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(3, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(4, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(5, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(6, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(7, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley')),
+ new Document(8, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny')),
+ new Document(9, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny')),
+ new Document(10, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny')),
+ new Document(11, array('id' => 1, 'email' => 'test@test.com', 'username' => 'bunny')),
+ ));
+ $index->refresh();
+
+ $search->addIndex($index)->addType($type);
+ $resultSet = $search->search();
+ $this->assertInstanceOf('Elastica\ResultSet', $resultSet);
+ $this->assertCount(10, $resultSet);
+ $this->assertEquals(11, $resultSet->getTotalHits());
+
+ $query = new QueryString('bunny');
+ $search->setQuery($query);
+
+ $resultSet = $search->search();
+
+ $this->assertCount(4, $resultSet);
+ $this->assertEquals(4, $resultSet->getTotalHits());
+ $source = $resultSet->current()->getSource();
+ $this->assertEquals('bunny', $source['username']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCount()
+ {
+ $index = $this->_createIndex();
+ $search = new Search($index->getClient());
+ $type = $index->getType('test');
+
+ $doc = new Document(1, array('id' => 1, 'username' => 'ruflin'));
+
+ $type->addDocument($doc);
+ $index->refresh();
+
+ $search->addIndex($index);
+ $search->addType($type);
+
+ $result1 = $search->count(new \Elastica\Query\MatchAll());
+ $this->assertEquals(1, $result1);
+
+ $result2 = $search->count(new \Elastica\Query\MatchAll(), true);
+ $this->assertInstanceOf('\Elastica\ResultSet', $result2);
+ $this->assertEquals(1, $result2->getTotalHits());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testScanAndScroll()
+ {
+ $search = new Search($this->_getClient());
+ $this->assertInstanceOf('Elastica\ScanAndScroll', $search->scanAndScroll());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testIgnoreUnavailableOption()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_7086b4c2ee585bbb6740ece5ed7ece01');
+ $query = new MatchAll();
+
+ $search = new Search($client);
+ $search->addIndex($index);
+
+ $exception = null;
+ try {
+ $search->search($query);
+ } catch (ResponseException $e) {
+ $exception = $e;
+ }
+ $this->assertEquals('IndexMissingException', $exception->getElasticsearchException()->getExceptionName());
+
+ $results = $search->search($query, array(Search::OPTION_SEARCH_IGNORE_UNAVAILABLE => true));
+ $this->assertInstanceOf('\Elastica\ResultSet', $results);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testQueryCacheOption()
+ {
+ $client = $this->_getClient();
+
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+ $type = $index->getType('zeroType');
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'username' => 'farrelley')),
+ new Document(2, array('id' => 2, 'username' => 'bunny')),
+ ));
+ $index->refresh();
+
+ $aggregation = new Aggregation\Terms('username');
+ $aggregation->setField('username');
+
+ $query = new Query();
+ $query->addAggregation($aggregation);
+
+ $search = new Search($client);
+ $search->addIndex($index);
+ $search->setQuery($query);
+ $search->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_COUNT);
+ $search->setOption(Search::OPTION_QUERY_CACHE, true);
+
+ // before search query cache should be empty
+ $statsData = $index->getStats()->getData();
+ $queryCache = $statsData['_all']['primaries']['query_cache'];
+
+ $this->assertEquals(0, $queryCache['memory_size_in_bytes']);
+ $this->assertEquals(0, $queryCache['evictions']);
+ $this->assertEquals(0, $queryCache['hit_count']);
+ $this->assertEquals(0, $queryCache['miss_count']);
+
+ // first search should result in cache miss and save data to cache
+ $search->search();
+ $index->getStats()->refresh();
+ $statsData = $index->getStats()->getData();
+ $queryCache = $statsData['_all']['primaries']['query_cache'];
+
+ $this->assertNotEquals(0, $queryCache['memory_size_in_bytes']);
+ $this->assertEquals(0, $queryCache['evictions']);
+ $this->assertEquals(0, $queryCache['hit_count']);
+ $this->assertEquals(1, $queryCache['miss_count']);
+
+ // next search should result in cache hit
+ $search->search();
+ $index->getStats()->refresh();
+ $statsData = $index->getStats()->getData();
+ $queryCache = $statsData['_all']['primaries']['query_cache'];
+
+ $this->assertNotEquals(0, $queryCache['memory_size_in_bytes']);
+ $this->assertEquals(0, $queryCache['evictions']);
+ $this->assertEquals(1, $queryCache['hit_count']);
+ $this->assertEquals(1, $queryCache['miss_count']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/ShutdownTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/ShutdownTest.php
new file mode 100644
index 00000000..93d6e32b
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/ShutdownTest.php
@@ -0,0 +1,74 @@
+<?php
+
+use Elastica\Test\Base as BaseTest;
+
+/**
+ * These tests shuts down node/cluster, so can't be executed with rest testsuite
+ * Please use `sudo service elasticsearch restart` after every run of these tests.
+ */
+class ShutdownTest extends BaseTest
+{
+ /**
+ * @group shutdown
+ */
+ public function testNodeShutdown()
+ {
+ // Get cluster nodes
+ $client = $this->_getClient();
+ $cluster = $client->getCluster();
+ $nodes = $cluster->getNodes();
+
+ $nodesCount = count($nodes);
+
+ if ($nodesCount < 2) {
+ $this->markTestIncomplete('At least two nodes have to be running, because 1 node is shutdown');
+ }
+
+ $portFound = false;
+ // sayonara, wolverine, we'd never love you
+ foreach ($nodes as $node) {
+ if ((int) $node->getInfo()->getPort() === 9201) {
+ $portFound = true;
+ $node->shutdown('1s');
+ break;
+ }
+ }
+
+ if (!$portFound) {
+ $this->markTestSkipped('This test was skipped as in the new docker environment all elasticsearch instances run on the same port');
+ }
+
+ // Wait until node is shutdown
+ sleep(5);
+
+ // Get nodes again
+ $client = $this->_getClient();
+ $cluster = $client->getCluster();
+ $nodes = $cluster->getNodes();
+
+ // Only one left
+ $this->assertCount($nodesCount - 1, $nodes);
+ }
+
+ /**
+ * @group shutdown
+ * @depends testNodeShutdown
+ * @expectedException \Elastica\Exception\Connection\HttpException
+ */
+ public function testClusterShutdown()
+ {
+ // Get cluster nodes
+ $client = $this->_getClient();
+ $cluster = $client->getCluster();
+ $nodes = $cluster->getNodes();
+
+ // Shutdown cluster
+ $cluster->shutdown('1s');
+
+ // Wait...
+ sleep(5);
+
+ // Now exception must be thrown
+ $client->getStatus();
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/SnapshotTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/SnapshotTest.php
new file mode 100644
index 00000000..fa190e8c
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/SnapshotTest.php
@@ -0,0 +1,109 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Snapshot;
+
+class SnapshotTest extends Base
+{
+ /**
+ * @var Snapshot
+ */
+ protected $_snapshot;
+
+ /**
+ * @var Index
+ */
+ protected $_index;
+
+ /**
+ * @var Document[]
+ */
+ protected $_docs;
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->_snapshot = new Snapshot($this->_getClient());
+
+ $this->_index = $this->_createIndex();
+ $this->_docs = array(
+ new Document('1', array('city' => 'San Diego')),
+ new Document('2', array('city' => 'San Luis Obispo')),
+ new Document('3', array('city' => 'San Francisco')),
+ );
+ $this->_index->getType('test')->addDocuments($this->_docs);
+ $this->_index->refresh();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testRegisterRepository()
+ {
+ $name = 'test_register';
+ $location = '/tmp/test_register';
+
+ $response = $this->_snapshot->registerRepository($name, 'fs', array('location' => $location));
+ $this->assertTrue($response->isOk());
+
+ $response = $this->_snapshot->getRepository($name);
+ $this->assertEquals($location, $response['settings']['location']);
+
+ // attempt to retrieve a repository which does not exist
+ $this->setExpectedException('Elastica\Exception\NotFoundException');
+ $this->_snapshot->getRepository('foobar');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSnapshotAndRestore()
+ {
+ $repositoryName = 'test_repository';
+ $location = "/tmp/{$repositoryName}";
+
+ // register the repository
+ $response = $this->_snapshot->registerRepository($repositoryName, 'fs', array('location' => $location));
+ $this->assertTrue($response->isOk());
+
+ // create a snapshot of our test index
+ $snapshotName = 'test_snapshot_1';
+ $response = $this->_snapshot->createSnapshot($repositoryName, $snapshotName, array('indices' => $this->_index->getName()), true);
+
+ // ensure that the snapshot was created properly
+ $this->assertTrue($response->isOk());
+ $this->assertArrayHasKey('snapshot', $response->getData());
+ $data = $response->getData();
+ $this->assertContains($this->_index->getName(), $data['snapshot']['indices']);
+ $this->assertEquals(1, sizeof($data['snapshot']['indices'])); // only the specified index should be present
+ $this->assertEquals($snapshotName, $data['snapshot']['snapshot']);
+
+ // retrieve data regarding the snapshot
+ $response = $this->_snapshot->getSnapshot($repositoryName, $snapshotName);
+ $this->assertContains($this->_index->getName(), $response['indices']);
+
+ // delete our test index
+ $this->_index->delete();
+
+ // restore the index from our snapshot
+ $response = $this->_snapshot->restoreSnapshot($repositoryName, $snapshotName, array(), true);
+ $this->assertTrue($response->isOk());
+
+ $this->_index->refresh();
+ $this->_index->optimize();
+
+ // ensure that the index has been restored
+ $count = $this->_index->getType('test')->count();
+ $this->assertEquals(sizeof($this->_docs), $count);
+
+ // delete the snapshot
+ $response = $this->_snapshot->deleteSnapshot($repositoryName, $snapshotName);
+ $this->assertTrue($response->isOk());
+
+ // ensure that the snapshot has been deleted
+ $this->setExpectedException('Elastica\Exception\NotFoundException');
+ $this->_snapshot->getSnapshot($repositoryName, $snapshotName);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/StatusTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/StatusTest.php
new file mode 100644
index 00000000..fe6bb091
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/StatusTest.php
@@ -0,0 +1,133 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Exception\ResponseException;
+use Elastica\Status;
+use Elastica\Test\Base as BaseTest;
+
+class StatusTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testGetResponse()
+ {
+ $index = $this->_createIndex();
+ $status = new Status($index->getClient());
+ $this->assertInstanceOf('Elastica\Response', $status->getResponse());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetIndexStatuses()
+ {
+ $index = $this->_createIndex();
+
+ $status = new Status($index->getClient());
+ $statuses = $status->getIndexStatuses();
+
+ $this->assertInternalType('array', $statuses);
+
+ foreach ($statuses as $indexStatus) {
+ $this->assertInstanceOf('Elastica\Index\Status', $indexStatus);
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetIndexNames()
+ {
+ $indexName = 'test';
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+ $index->create(array(), true);
+ $index = $this->_createIndex();
+ $index->refresh();
+ $index->optimize();
+
+ $status = new Status($index->getClient());
+ $names = $status->getIndexNames();
+
+ $this->assertInternalType('array', $names);
+ $this->assertContains($index->getName(), $names);
+
+ foreach ($names as $name) {
+ $this->assertInternalType('string', $name);
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testIndexExists()
+ {
+ $indexName = 'elastica_test';
+ $aliasName = 'elastica_test-alias';
+
+ $client = $this->_getClient();
+ $index = $client->getIndex($indexName);
+
+ try {
+ // Make sure index is deleted first
+ $index->delete();
+ } catch (ResponseException $e) {
+ }
+
+ $status = new Status($client);
+ $this->assertFalse($status->indexExists($indexName));
+ $index->create();
+
+ $status->refresh();
+ $this->assertTrue($status->indexExists($indexName));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAliasExists()
+ {
+ $aliasName = 'elastica_test-alias';
+
+ $index1 = $this->_createIndex();
+ $indexName = $index1->getName();
+
+ $status = new Status($index1->getClient());
+
+ foreach ($status->getIndicesWithAlias($aliasName) as $tmpIndex) {
+ $tmpIndex->removeAlias($aliasName);
+ }
+
+ $this->assertFalse($status->aliasExists($aliasName));
+
+ $index1->addAlias($aliasName);
+ $status->refresh();
+ $this->assertTrue($status->aliasExists($aliasName));
+
+ $indicesWithAlias = $status->getIndicesWithAlias($aliasName);
+ $this->assertEquals(array($indexName), array_map(
+ function ($index) {
+ return $index->getName();
+ }, $indicesWithAlias));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testServerStatus()
+ {
+ $client = $this->_getClient();
+ $status = $client->getStatus();
+ $serverStatus = $status->getServerStatus();
+
+ $this->assertTrue(!empty($serverStatus));
+ $this->assertTrue('array' == gettype($serverStatus));
+ $this->assertArrayHasKey('status', $serverStatus);
+ $this->assertTrue($serverStatus['status'] == 200);
+ $this->assertArrayHasKey('version', $serverStatus);
+
+ $versionInfo = $serverStatus['version'];
+ $this->assertArrayHasKey('number', $versionInfo);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/CompletionTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/CompletionTest.php
new file mode 100644
index 00000000..6120743c
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/CompletionTest.php
@@ -0,0 +1,140 @@
+<?php
+namespace Elastica\Test\Suggest;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query;
+use Elastica\Suggest\Completion;
+use Elastica\Test\Base as BaseTest;
+
+class CompletionTest extends BaseTest
+{
+ /**
+ * @return Index
+ */
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('song');
+
+ $type->setMapping(array(
+ 'fieldName' => array(
+ 'type' => 'completion',
+ 'payloads' => true,
+ ),
+ ));
+
+ $type->addDocuments(array(
+ new Document(1, array(
+ 'fieldName' => array(
+ 'input' => array('Nevermind', 'Nirvana'),
+ 'output' => 'Nevermind - Nirvana',
+ 'payload' => array(
+ 'year' => 1991,
+ ),
+ ),
+ )),
+ new Document(2, array(
+ 'fieldName' => array(
+ 'input' => array('Bleach', 'Nirvana'),
+ 'output' => 'Bleach - Nirvana',
+ 'payload' => array(
+ 'year' => 1989,
+ ),
+ ),
+ )),
+ new Document(3, array(
+ 'fieldName' => array(
+ 'input' => array('Incesticide', 'Nirvana'),
+ 'output' => 'Incesticide - Nirvana',
+ 'payload' => array(
+ 'year' => 1992,
+ ),
+ ),
+ )),
+ ));
+
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $suggest = new Completion('suggestName', 'fieldName');
+ $suggest->setText('foo');
+ $suggest->setSize(10);
+ $expected = array(
+ 'text' => 'foo',
+ 'completion' => array(
+ 'size' => 10,
+ 'field' => 'fieldName',
+ ),
+ );
+ $this->assertEquals($expected, $suggest->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSuggestWorks()
+ {
+ $suggest = new Completion('suggestName', 'fieldName');
+ $suggest->setText('Never');
+
+ $index = $this->_getIndexForTest();
+ $resultSet = $index->search(Query::create($suggest));
+
+ $this->assertTrue($resultSet->hasSuggests());
+
+ $suggests = $resultSet->getSuggests();
+ $options = $suggests['suggestName'][0]['options'];
+
+ $this->assertCount(1, $options);
+ $this->assertEquals('Nevermind - Nirvana', $options[0]['text']);
+ $this->assertEquals(1991, $options[0]['payload']['year']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testFuzzySuggestWorks()
+ {
+ $suggest = new Completion('suggestName', 'fieldName');
+ $suggest->setFuzzy(array('fuzziness' => 2));
+ $suggest->setText('Neavermint');
+
+ $index = $this->_getIndexForTest();
+ $resultSet = $index->search(Query::create($suggest));
+
+ $this->assertTrue($resultSet->hasSuggests());
+
+ $suggests = $resultSet->getSuggests();
+ $options = $suggests['suggestName'][0]['options'];
+
+ $this->assertCount(1, $options);
+ $this->assertEquals('Nevermind - Nirvana', $options[0]['text']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetFuzzy()
+ {
+ $suggest = new Completion('suggestName', 'fieldName');
+
+ $fuzzy = array(
+ 'unicode_aware' => true,
+ 'fuzziness' => 3,
+ );
+
+ $suggest->setFuzzy($fuzzy);
+
+ $this->assertEquals($fuzzy, $suggest->getParam('fuzzy'));
+
+ $this->assertInstanceOf('Elastica\\Suggest\\Completion', $suggest->setFuzzy($fuzzy));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/PhraseTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/PhraseTest.php
new file mode 100644
index 00000000..9ce345d4
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/PhraseTest.php
@@ -0,0 +1,82 @@
+<?php
+namespace Elastica\Test\Suggest;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Suggest;
+use Elastica\Suggest\CandidateGenerator\DirectGenerator;
+use Elastica\Suggest\Phrase;
+use Elastica\Test\Base as BaseTest;
+
+class PhraseTest extends BaseTest
+{
+ /**
+ * @return Index
+ */
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('testSuggestType');
+ $type->addDocuments(array(
+ new Document(1, array('text' => 'Github is pretty cool')),
+ new Document(2, array('text' => 'Elasticsearch is bonsai cool')),
+ new Document(3, array('text' => 'This is a test phrase')),
+ new Document(4, array('text' => 'Another sentence for testing')),
+ new Document(5, array('text' => 'Some more words here')),
+ ));
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $suggest = new Suggest();
+ $phraseSuggest = new Phrase('suggest1', 'text');
+ $phraseSuggest->setText('elasticsearch is bansai coor');
+ $phraseSuggest->setAnalyzer('simple');
+ $suggest->addSuggestion($phraseSuggest);
+ $suggest->setGlobalText('global!');
+
+ $expected = array(
+ 'suggest' => array(
+ 'text' => 'global!',
+ 'suggest1' => array(
+ 'text' => 'elasticsearch is bansai coor',
+ 'phrase' => array(
+ 'field' => 'text',
+ 'analyzer' => 'simple',
+ ),
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $suggest->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testPhraseSuggest()
+ {
+ $suggest = new Suggest();
+ $phraseSuggest = new Phrase('suggest1', 'text');
+ $phraseSuggest->setText('elasticsearch is bansai coor');
+ $phraseSuggest->setAnalyzer('simple')->setHighlight('<suggest>', '</suggest>')->setStupidBackoffSmoothing(0.4);
+ $phraseSuggest->addCandidateGenerator(new DirectGenerator('text'));
+ $suggest->addSuggestion($phraseSuggest);
+
+ $index = $this->_getIndexForTest();
+ $result = $index->search($suggest);
+ $suggests = $result->getSuggests();
+
+ // 3 suggestions should be returned: One in which both misspellings are corrected, and two in which only one misspelling is corrected.
+ $this->assertEquals(3, sizeof($suggests['suggest1'][0]['options']));
+
+ $this->assertEquals('elasticsearch is <suggest>bonsai cool</suggest>', $suggests['suggest1'][0]['options'][0]['highlighted']);
+ $this->assertEquals('elasticsearch is bonsai cool', $suggests['suggest1'][0]['options'][0]['text']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/TermTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/TermTest.php
new file mode 100644
index 00000000..f1250e6f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Suggest/TermTest.php
@@ -0,0 +1,105 @@
+<?php
+namespace Elastica\Test\Suggest;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Suggest;
+use Elastica\Suggest\Term;
+use Elastica\Test\Base as BaseTest;
+
+class TermTest extends BaseTest
+{
+ /**
+ * @return Index
+ */
+ protected function _getIndexForTest()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('testSuggestType');
+ $type->addDocuments(array(
+ new Document(1, array('id' => 1, 'text' => 'GitHub')),
+ new Document(2, array('id' => 1, 'text' => 'Elastic')),
+ new Document(3, array('id' => 1, 'text' => 'Search')),
+ new Document(4, array('id' => 1, 'text' => 'Food')),
+ new Document(5, array('id' => 1, 'text' => 'Flood')),
+ new Document(6, array('id' => 1, 'text' => 'Folks')),
+ ));
+ $index->refresh();
+
+ return $index;
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToArray()
+ {
+ $suggest = new Suggest();
+ $suggest1 = new Term('suggest1', '_all');
+ $suggest->addSuggestion($suggest1->setText('Foor'));
+ $suggest2 = new Term('suggest2', '_all');
+ $suggest->addSuggestion($suggest2->setText('Girhub'));
+
+ $expected = array(
+ 'suggest' => array(
+ 'suggest1' => array(
+ 'term' => array(
+ 'field' => '_all',
+ ),
+ 'text' => 'Foor',
+ ),
+ 'suggest2' => array(
+ 'term' => array(
+ 'field' => '_all',
+ ),
+ 'text' => 'Girhub',
+ ),
+ ),
+ );
+
+ $this->assertEquals($expected, $suggest->toArray());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSuggestResults()
+ {
+ $suggest = new Suggest();
+ $suggest1 = new Term('suggest1', '_all');
+ $suggest->addSuggestion($suggest1->setText('Foor seach'));
+ $suggest2 = new Term('suggest2', '_all');
+ $suggest->addSuggestion($suggest2->setText('Girhub'));
+
+ $index = $this->_getIndexForTest();
+ $result = $index->search($suggest);
+
+ $this->assertEquals(2, $result->countSuggests());
+
+ $suggests = $result->getSuggests();
+
+ // Ensure that two suggestion results are returned for suggest1
+ $this->assertEquals(2, sizeof($suggests['suggest1']));
+
+ $this->assertEquals('github', $suggests['suggest2'][0]['options'][0]['text']);
+ $this->assertEquals('food', $suggests['suggest1'][0]['options'][0]['text']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSuggestNoResults()
+ {
+ $termSuggest = new Term('suggest1', '_all');
+ $termSuggest->setText('Foobar')->setSize(4);
+
+ $index = $this->_getIndexForTest();
+ $result = $index->search($termSuggest);
+
+ $this->assertEquals(1, $result->countSuggests());
+
+ // Assert that no suggestions were returned
+ $suggests = $result->getSuggests();
+ $this->assertEquals(0, sizeof($suggests['suggest1'][0]['options']));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Tool/CrossIndexTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Tool/CrossIndexTest.php
new file mode 100644
index 00000000..f8fbf280
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Tool/CrossIndexTest.php
@@ -0,0 +1,135 @@
+<?php
+namespace Elastica\Test\Tool;
+
+use Elastica\Document;
+use Elastica\Test\Base;
+use Elastica\Tool\CrossIndex;
+use Elastica\Type;
+
+class CrossIndexTest extends Base
+{
+ /**
+ * Test default reindex.
+ */
+ public function testReindex()
+ {
+ $oldIndex = $this->_createIndex(null, true, 2);
+ $this->_addDocs($oldIndex->getType('crossIndexTest'), 10);
+
+ $newIndex = $this->_createIndex(null, true, 2);
+
+ $this->assertInstanceOf(
+ 'Elastica\Index',
+ CrossIndex::reindex($oldIndex, $newIndex)
+ );
+
+ $this->assertEquals(10, $newIndex->count());
+ }
+
+ /**
+ * Test reindex type option.
+ */
+ public function testReindexTypeOption()
+ {
+ $oldIndex = $this->_createIndex('', true, 2);
+ $type1 = $oldIndex->getType('crossIndexTest_1');
+ $type2 = $oldIndex->getType('crossIndexTest_2');
+
+ $docs1 = $this->_addDocs($type1, 10);
+ $docs2 = $this->_addDocs($type2, 10);
+
+ $newIndex = $this->_createIndex(null, true, 2);
+
+ // \Elastica\Type
+ CrossIndex::reindex($oldIndex, $newIndex, array(
+ CrossIndex::OPTION_TYPE => $type1,
+ ));
+ $this->assertEquals(10, $newIndex->count());
+ $newIndex->deleteDocuments($docs1);
+
+ // string
+ CrossIndex::reindex($oldIndex, $newIndex, array(
+ CrossIndex::OPTION_TYPE => 'crossIndexTest_2',
+ ));
+ $this->assertEquals(10, $newIndex->count());
+ $newIndex->deleteDocuments($docs2);
+
+ // array
+ CrossIndex::reindex($oldIndex, $newIndex, array(
+ CrossIndex::OPTION_TYPE => array(
+ 'crossIndexTest_1',
+ $type2,
+ ),
+ ));
+ $this->assertEquals(20, $newIndex->count());
+ }
+
+ /**
+ * Test default copy.
+ */
+ public function testCopy()
+ {
+ $oldIndex = $this->_createIndex(null, true, 2);
+ $newIndex = $this->_createIndex(null, true, 2);
+
+ $oldType = $oldIndex->getType('copy_test');
+ $oldMapping = array(
+ 'name' => array(
+ 'type' => 'string',
+ 'store' => true,
+ ),
+ );
+ $oldType->setMapping($oldMapping);
+ $docs = $this->_addDocs($oldType, 10);
+
+ // mapping
+ $this->assertInstanceOf(
+ 'Elastica\Index',
+ CrossIndex::copy($oldIndex, $newIndex)
+ );
+
+ $newMapping = $newIndex->getType('copy_test')->getMapping();
+ if (!isset($newMapping['copy_test']['properties']['name'])) {
+ $this->fail('could not request new mapping');
+ }
+
+ $this->assertEquals(
+ $oldMapping['name'],
+ $newMapping['copy_test']['properties']['name']
+ );
+
+ // document copy
+ $this->assertEquals(10, $newIndex->count());
+ $newIndex->deleteDocuments($docs);
+
+ // ignore mapping
+ $ignoredType = $oldIndex->getType('copy_test_1');
+ $this->_addDocs($ignoredType, 10);
+
+ CrossIndex::copy($oldIndex, $newIndex, array(
+ CrossIndex::OPTION_TYPE => $oldType,
+ ));
+
+ $this->assertFalse($newIndex->getType($ignoredType->getName())->exists());
+ $this->assertEquals(10, $newIndex->count());
+ }
+
+ /**
+ * @param Type $type
+ * @param int $docs
+ *
+ * @return array
+ */
+ private function _addDocs(Type $type, $docs)
+ {
+ $insert = array();
+ for ($i = 1; $i <= $docs; $i++) {
+ $insert[] = new Document($i, array('_id' => $i, 'key' => 'value'));
+ }
+
+ $type->addDocuments($insert);
+ $type->getIndex()->refresh();
+
+ return $insert;
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/AbstractTransportTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/AbstractTransportTest.php
new file mode 100644
index 00000000..20573cc7
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/AbstractTransportTest.php
@@ -0,0 +1,80 @@
+<?php
+namespace Elastica\Test\Transport;
+
+use Elastica\Connection;
+use Elastica\Transport\AbstractTransport;
+use Elastica\Transport\Http;
+
+class AbstractTransportTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * Return transport configuration and the expected HTTP method.
+ *
+ * @return array[]
+ */
+ public function getValidDefinitions()
+ {
+ $connection = new Connection();
+
+ return array(
+ array('Http'),
+ array(array('type' => 'Http')),
+ array(array('type' => new Http())),
+ array(new Http()),
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider getValidDefinitions
+ */
+ public function testCanCreateTransportInstances($transport)
+ {
+ $connection = new Connection();
+ $params = array();
+ $transport = AbstractTransport::create($transport, $connection, $params);
+ $this->assertInstanceOf('Elastica\Transport\AbstractTransport', $transport);
+ $this->assertSame($connection, $transport->getConnection());
+ }
+
+ public function getInvalidDefinitions()
+ {
+ return array(
+ array(array('transport' => 'Http')),
+ array('InvalidTransport'),
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider getInvalidDefinitions
+ * @expectedException Elastica\Exception\InvalidException
+ * @expectedExceptionMessage Invalid transport
+ */
+ public function testThrowsExecptionOnInvalidTransportDefinition($transport)
+ {
+ AbstractTransport::create($transport, new Connection());
+ }
+
+ /**
+ * @group unit
+ */
+ public function testCanInjectParamsWhenUsingArray()
+ {
+ $connection = new Connection();
+ $params = array(
+ 'param1' => 'some value',
+ 'param3' => 'value3',
+ );
+
+ $transport = AbstractTransport::create(array(
+ 'type' => 'Http',
+ 'param1' => 'value1',
+ 'param2' => 'value2',
+ ), $connection, $params);
+
+ $this->assertSame('value1', $transport->getParam('param1'));
+ $this->assertSame('value2', $transport->getParam('param2'));
+ $this->assertSame('value3', $transport->getParam('param3'));
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/GuzzleTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/GuzzleTest.php
new file mode 100644
index 00000000..04e7ee2d
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/GuzzleTest.php
@@ -0,0 +1,180 @@
+<?php
+namespace Elastica\Test\Transport;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\ResultSet;
+use Elastica\Test\Base as BaseTest;
+
+class GuzzleTest extends BaseTest
+{
+ public static function setUpBeforeClass()
+ {
+ if (!class_exists('GuzzleHttp\\Client')) {
+ self::markTestSkipped('guzzlehttp/guzzle package should be installed to run guzzle transport tests');
+ }
+ }
+
+ /**
+ * Return transport configuration and the expected HTTP method.
+ *
+ * @return array[]
+ */
+ public function getConfig()
+ {
+ return array(
+ array(
+ array('persistent' => false, 'transport' => 'Guzzle'),
+ 'GET',
+ ),
+ array(
+ array('persistent' => false, 'transport' => array('type' => 'Guzzle', 'postWithRequestBody' => false)),
+ 'GET',
+ ),
+ array(
+ array('persistent' => false, 'transport' => array('type' => 'Guzzle', 'postWithRequestBody' => true)),
+ 'POST',
+ ),
+ );
+ }
+
+ /**
+ * @group functional
+ * @dataProvider getConfig
+ */
+ public function testDynamicHttpMethodBasedOnConfigParameter(array $config, $httpMethod)
+ {
+ $client = $this->_getClient($config);
+
+ $index = $client->getIndex('dynamic_http_method_test');
+ $index->create(array(), true);
+ $type = $index->getType('test');
+ $type->addDocument(new Document(1, array('test' => 'test')));
+ $index->refresh();
+ $resultSet = $index->search('test');
+ $info = $resultSet->getResponse()->getTransferInfo();
+ $this->assertStringStartsWith($httpMethod, $info['request_header']);
+ }
+
+ /**
+ * @group functional
+ * @dataProvider getConfig
+ */
+ public function testDynamicHttpMethodOnlyAffectsRequestsWithBody(array $config, $httpMethod)
+ {
+ $client = $this->_getClient($config);
+
+ $status = $client->getStatus();
+ $info = $status->getResponse()->getTransferInfo();
+ $this->assertStringStartsWith('GET', $info['request_header']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithEnvironmentalProxy()
+ {
+ putenv('http_proxy='.$this->_getProxyUrl().'/');
+
+ $client = $this->_getClient(array('transport' => 'Guzzle', 'persistent' => false));
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+
+ $client->getConnection()->setProxy(null); // will not change anything
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+
+ putenv('http_proxy=');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithEnabledEnvironmentalProxy()
+ {
+ putenv('http_proxy='.$this->_getProxyUrl403().'/');
+
+ $client = $this->_getClient(array('transport' => 'Guzzle', 'persistent' => false));
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(403, $transferInfo['http_code']);
+
+ $client = $this->_getClient(array('transport' => 'Guzzle', 'persistent' => false));
+ $client->getConnection()->setProxy('');
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+
+ putenv('http_proxy=');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithProxy()
+ {
+ $client = $this->_getClient(array('transport' => 'Guzzle', 'persistent' => false));
+ $client->getConnection()->setProxy($this->_getProxyUrl());
+
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithoutProxy()
+ {
+ $client = $this->_getClient(array('transport' => 'Guzzle', 'persistent' => false));
+ $client->getConnection()->setProxy('');
+
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testBodyReuse()
+ {
+ $client = $this->_getClient(array('transport' => 'Guzzle', 'persistent' => false));
+
+ $index = $client->getIndex('elastica_body_reuse_test');
+ $index->create(array(), true);
+ $this->_waitForAllocation($index);
+
+ $type = $index->getType('test');
+ $type->addDocument(new Document(1, array('test' => 'test')));
+
+ $index->refresh();
+
+ $resultSet = $index->search(array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'pew pew pew',
+ ),
+ ),
+ ));
+
+ $this->assertEquals(0, $resultSet->getTotalHits());
+
+ $response = $index->request('/_search', 'POST');
+ $resultSet = new ResultSet($response, Query::create(array()));
+
+ $this->assertEquals(1, $resultSet->getTotalHits());
+ }
+
+ /**
+ * @group unit
+ * @expectedException Elastica\Exception\Connection\GuzzleException
+ */
+ public function testInvalidConnection()
+ {
+ $client = $this->_getClient(array('transport' => 'Guzzle', 'port' => 4500, 'persistent' => false));
+ $response = $client->request('_status', 'GET');
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+ putenv('http_proxy=');
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/HttpTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/HttpTest.php
new file mode 100644
index 00000000..53ee105f
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/HttpTest.php
@@ -0,0 +1,246 @@
+<?php
+namespace Elastica\Test\Transport;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\ResultSet;
+use Elastica\Test\Base as BaseTest;
+
+class HttpTest extends BaseTest
+{
+ /**
+ * Return transport configuration and the expected HTTP method.
+ *
+ * @return array[]
+ */
+ public function getConfig()
+ {
+ return array(
+ array(
+ array('transport' => 'Http', 'curl' => array(CURLINFO_HEADER_OUT => true)),
+ 'GET',
+ ),
+ array(
+ array('transport' => array('type' => 'Http', 'postWithRequestBody' => false, 'curl' => array(CURLINFO_HEADER_OUT => true))),
+ 'GET',
+ ),
+ array(
+ array('transport' => array('type' => 'Http', 'postWithRequestBody' => true, 'curl' => array(CURLINFO_HEADER_OUT => true))),
+ 'POST',
+ ),
+ );
+ }
+
+ /**
+ * @group functional
+ * @dataProvider getConfig
+ */
+ public function testDynamicHttpMethodBasedOnConfigParameter(array $config, $httpMethod)
+ {
+ $client = $this->_getClient($config);
+
+ $index = $client->getIndex('dynamic_http_method_test');
+ $index->create(array(), true);
+ $this->_waitForAllocation($index);
+
+ $type = $index->getType('test');
+ $type->addDocument(new Document(1, array('test' => 'test')));
+
+ $index->refresh();
+
+ $resultSet = $index->search('test');
+
+ $info = $resultSet->getResponse()->getTransferInfo();
+ $this->assertStringStartsWith($httpMethod, $info['request_header']);
+ }
+
+ /**
+ * @group functional
+ * @dataProvider getConfig
+ */
+ public function testDynamicHttpMethodOnlyAffectsRequestsWithBody(array $config, $httpMethod)
+ {
+ $client = $this->_getClient($config);
+
+ $status = $client->getStatus();
+ $info = $status->getResponse()->getTransferInfo();
+ $this->assertStringStartsWith('GET', $info['request_header']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCurlNobodyOptionIsResetAfterHeadRequest()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('curl_test');
+ $index->create(array(), true);
+ $this->_waitForAllocation($index);
+
+ $type = $index->getType('item');
+ // Force HEAD request to set CURLOPT_NOBODY = true
+ $index->exists();
+
+ $id = 1;
+ $data = array('id' => $id, 'name' => 'Item 1');
+ $doc = new \Elastica\Document($id, $data);
+
+ $type->addDocument($doc);
+
+ $index->refresh();
+
+ $doc = $type->getDocument($id);
+
+ // Document should be retrieved correctly
+ $this->assertSame($data, $doc->getData());
+ $this->assertEquals($id, $doc->getId());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUnicodeData()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('curl_test');
+ $index->create(array(), true);
+ $this->_waitForAllocation($index);
+
+ $type = $index->getType('item');
+
+ // Force HEAD request to set CURLOPT_NOBODY = true
+ $index->exists();
+
+ $id = 22;
+ $data = array('id' => $id, 'name' => '
+ Сегодня, я вижу, особенно грустен твой взгляд, /
+ И руки особенно тонки, колени обняв. /
+ Послушай: далеко, далеко, на озере Чад /
+ Изысканный бродит жираф.');
+
+ $doc = new \Elastica\Document($id, $data);
+
+ $type->addDocument($doc);
+
+ $index->refresh();
+
+ $doc = $type->getDocument($id);
+
+ // Document should be retrieved correctly
+ $this->assertSame($data, $doc->getData());
+ $this->assertEquals($id, $doc->getId());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithEnvironmentalProxy()
+ {
+ putenv('http_proxy='.$this->_getProxyUrl().'/');
+
+ $client = $this->_getClient();
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+
+ $client->getConnection()->setProxy(null); // will not change anything
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+
+ putenv('http_proxy=');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithEnabledEnvironmentalProxy()
+ {
+ putenv('http_proxy='.$this->_getProxyUrl403().'/');
+ $client = $this->_getClient();
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(403, $transferInfo['http_code']);
+ $client = $this->_getClient();
+ $client->getConnection()->setProxy('');
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+ putenv('http_proxy=');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithProxy()
+ {
+ $client = $this->_getClient();
+ $client->getConnection()->setProxy($this->_getProxyUrl());
+
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testWithoutProxy()
+ {
+ $client = $this->_getClient();
+ $client->getConnection()->setProxy('');
+
+ $transferInfo = $client->request('/_nodes')->getTransferInfo();
+ $this->assertEquals(200, $transferInfo['http_code']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testBodyReuse()
+ {
+ $client = $this->_getClient();
+
+ $index = $client->getIndex('elastica_body_reuse_test');
+ $index->create(array(), true);
+ $this->_waitForAllocation($index);
+
+ $type = $index->getType('test');
+ $type->addDocument(new Document(1, array('test' => 'test')));
+
+ $index->refresh();
+
+ $resultSet = $index->search(array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'pew pew pew',
+ ),
+ ),
+ ));
+
+ $this->assertEquals(0, $resultSet->getTotalHits());
+
+ $response = $index->request('/_search', 'POST');
+ $resultSet = new ResultSet($response, Query::create(array()));
+
+ $this->assertEquals(1, $resultSet->getTotalHits());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testPostWith0Body()
+ {
+ $client = $this->_getClient();
+
+ $index = $client->getIndex('elastica_0_body');
+ $index->create(array(), true);
+ $this->_waitForAllocation($index);
+ $index->refresh();
+
+ $tokens = $index->analyze('0');
+
+ $this->assertNotEmpty($tokens);
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+ putenv('http_proxy=');
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/MemcacheTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/MemcacheTest.php
new file mode 100644
index 00000000..30897073
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/MemcacheTest.php
@@ -0,0 +1,176 @@
+<?php
+namespace Elastica\Test\Transport;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Query\QueryString;
+use Elastica\Request;
+use Elastica\Test\Base as BaseTest;
+
+class MemcacheTest extends BaseTest
+{
+ public static function setUpBeforeClass()
+ {
+ if (!extension_loaded('Memcache')) {
+ self::markTestSkipped('pecl/memcache must be installed to run this test case');
+ }
+ }
+
+ protected function _getMemcacheClient()
+ {
+ return $this->_getClient(array(
+ 'host' => $this->_getHost(),
+ 'port' => 11211,
+ 'transport' => 'Memcache',
+ ));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testConstruct()
+ {
+ $client = $this->_getMemcacheClient();
+ $this->assertEquals($this->_getHost(), $client->getConnection()->getHost());
+ $this->assertEquals(11211, $client->getConnection()->getPort());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCreateDocument()
+ {
+ $index = $this->_createIndex();
+ $this->_waitForAllocation($index);
+ $type = $index->getType('foo');
+
+ // Create document
+ $document = new Document(1, array('username' => 'John Doe'));
+ $type->addDocument($document);
+ $index->refresh();
+
+ // Check it was saved
+ $document = $type->getDocument(1);
+ $this->assertEquals('John Doe', $document->get('username'));
+ }
+
+ /**
+ * @group functional
+ * @expectedException Elastica\Exception\NotFoundException
+ */
+ public function testDeleteDocument()
+ {
+ $index = $this->_createIndex();
+ $this->_waitForAllocation($index);
+ $type = $index->getType('foo');
+
+ // Create document
+ $document = new Document(1, array('username' => 'John Doe'));
+ $type->addDocument($document);
+ $index->refresh();
+
+ // Delete document
+ $type->deleteById(1);
+
+ // Check if document is not exists
+ $document = $type->getDocument(1);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocument()
+ {
+ $index = $this->_createIndex();
+ $this->_waitForAllocation($index);
+ $type = $index->getType('foo');
+
+ // Create document
+ $document = new Document(1, array('username' => 'John Doe'));
+ $type->addDocument($document);
+ $index->refresh();
+
+ // Check it was saved
+ $savedDocument = $type->getDocument(1);
+ $this->assertEquals('John Doe', $savedDocument->get('username'));
+
+ // Update document
+ $newDocument = new Document(1, array('username' => 'Doe John'));
+ $type->updateDocument($newDocument);
+ $index->refresh();
+
+ // Check it was updated
+ $newSavedDocument = $type->getDocument(1);
+ $this->assertEquals('Doe John', $newSavedDocument->get('username'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSearchDocument()
+ {
+ $index = $this->_createIndex();
+ $this->_waitForAllocation($index);
+ $type = $index->getType('fruits');
+
+ // Create documents
+ $docs = array(
+ new Document(1, array('name' => 'banana')),
+ new Document(2, array('name' => 'apple')),
+ new Document(3, array('name' => 'orange')),
+ );
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ // Search documents
+ $queryString = new QueryString('orange');
+ $query = new Query($queryString);
+ $resultSet = $type->search($query);
+
+ // Check if correct document was found
+ $this->assertEquals(1, $resultSet->getTotalHits());
+ $this->assertEquals(3, $resultSet[0]->getId());
+ $data = $resultSet[0]->getData();
+ $this->assertEquals('orange', $data['name']);
+ }
+
+ /**
+ * @group functional
+ * @expectedException Elastica\Exception\InvalidException
+ * @expectedExceptionMessage is not supported in memcache transport
+ */
+ public function testHeadRequest()
+ {
+ $client = $this->_getMemcacheClient();
+ $client->request('foo', Request::HEAD);
+ }
+
+ /**
+ * @group functional
+ * @expectedException Elastica\Exception\InvalidException
+ * @expectedExceptionMessage is not supported in memcache transport
+ */
+ public function testInvalidRequest()
+ {
+ $client = $this->_getMemcacheClient();
+ $client->request('foo', 'its_fail');
+ }
+
+ /**
+ * @group functional
+ * @expectedException Elastica\Exception\Connection\MemcacheException
+ * @expectedExceptionMessage is too long
+ */
+ public function testRequestWithLongPath()
+ {
+ $client = $this->_getMemcacheClient();
+ $index = $client->getIndex('memcache-test');
+ $index->create();
+
+ $this->_waitForAllocation($index);
+
+ $queryString = new QueryString(str_repeat('z', 300));
+ $query = new Query($queryString);
+ $index->search($query);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/NullTransportTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/NullTransportTest.php
new file mode 100644
index 00000000..cea3e3ba
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/NullTransportTest.php
@@ -0,0 +1,96 @@
+<?php
+namespace Elastica\Test\Transport;
+
+use Elastica\Connection;
+use Elastica\Query;
+use Elastica\Request;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Transport\NullTransport;
+
+/**
+ * Elastica Null Transport Test.
+ *
+ * @author James Boehmer <james.boehmer@jamesboehmer.com>
+ */
+class NullTransportTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testEmptyResult()
+ {
+ // Creates a client with any destination, and verify it returns a response object when executed
+ $client = $this->_getClient();
+ $connection = new Connection(array('transport' => 'NullTransport'));
+ $client->setConnections(array($connection));
+
+ $index = $client->getIndex('elasticaNullTransportTest1');
+
+ $resultSet = $index->search(new Query());
+ $this->assertNotNull($resultSet);
+
+ $response = $resultSet->getResponse();
+ $this->assertNotNull($response);
+
+ // Validate most of the expected fields in the response data. Consumers of the response
+ // object have a reasonable expectation of finding "hits", "took", etc
+ $responseData = $response->getData();
+ $this->assertContains('took', $responseData);
+ $this->assertEquals(0, $responseData['took']);
+ $this->assertContains('_shards', $responseData);
+ $this->assertContains('hits', $responseData);
+ $this->assertContains('total', $responseData['hits']);
+ $this->assertEquals(0, $responseData['hits']['total']);
+ $this->assertContains('params', $responseData);
+
+ $took = $response->getEngineTime();
+ $this->assertEquals(0, $took);
+
+ $errorString = $response->getError();
+ $this->assertEmpty($errorString);
+
+ $shards = $response->getShardsStatistics();
+ $this->assertContains('total', $shards);
+ $this->assertEquals(0, $shards['total']);
+ $this->assertContains('successful', $shards);
+ $this->assertEquals(0, $shards['successful']);
+ $this->assertContains('failed', $shards);
+ $this->assertEquals(0, $shards['failed']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testExec()
+ {
+ $request = new Request('/test');
+ $params = array('name' => 'ruflin');
+ $transport = new NullTransport();
+ $response = $transport->exec($request, $params);
+
+ $this->assertInstanceOf('\Elastica\Response', $response);
+
+ $data = $response->getData();
+ $this->assertEquals($params, $data['params']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testOldObject()
+ {
+ if (version_compare(phpversion(), 7, '>=')) {
+ self::markTestSkipped('These objects are not supported in PHP 7');
+ }
+
+ $request = new Request('/test');
+ $params = array('name' => 'ruflin');
+ $transport = new \Elastica\Transport\Null();
+ $response = $transport->exec($request, $params);
+
+ $this->assertInstanceOf('\Elastica\Response', $response);
+
+ $data = $response->getData();
+ $this->assertEquals($params, $data['params']);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/ThriftTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/ThriftTest.php
new file mode 100644
index 00000000..b73ef4f7
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/ThriftTest.php
@@ -0,0 +1,135 @@
+<?php
+namespace Elastica\Test\Transport;
+
+use Elastica\Connection;
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Test\Base as BaseTest;
+
+class ThriftTest extends BaseTest
+{
+ public static function setUpBeforeClass()
+ {
+ if (!class_exists('Elasticsearch\\RestClient')) {
+ self::markTestSkipped('munkie/elasticsearch-thrift-php package should be installed to run thrift transport tests');
+ }
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConstruct()
+ {
+ $host = $this->_getHost();
+ $port = 9500;
+ $client = $this->_getClient(array('host' => $host, 'port' => $port, 'transport' => 'Thrift'));
+
+ $this->assertEquals($host, $client->getConnection()->getHost());
+ $this->assertEquals($port, $client->getConnection()->getPort());
+ }
+
+ /**
+ * @group functional
+ * @dataProvider configProvider
+ */
+ public function testSearchRequest($config)
+ {
+ $this->_checkPlugin();
+
+ // Creates a new index 'xodoa' and a type 'user' inside this index
+ $client = $this->_getClient($config);
+
+ $index = $client->getIndex('elastica_test1');
+ $index->create(array(), true);
+
+ $type = $index->getType('user');
+
+ // Adds 1 document to the index
+ $doc1 = new Document(1,
+ array('username' => 'hans', 'test' => array('2', '3', '5'))
+ );
+ $doc1->setVersion(0);
+ $type->addDocument($doc1);
+
+ // Adds a list of documents with _bulk upload to the index
+ $docs = array();
+ $docs[] = new Document(2,
+ array('username' => 'john', 'test' => array('1', '3', '6'))
+ );
+ $docs[] = new Document(3,
+ array('username' => 'rolf', 'test' => array('2', '3', '7'))
+ );
+ $type->addDocuments($docs);
+
+ // Refresh index
+ $index->refresh();
+ $resultSet = $type->search('rolf');
+
+ $this->assertEquals(1, $resultSet->getTotalHits());
+ }
+
+ /**
+ * @group unit
+ * @expectedException \Elastica\Exception\ConnectionException
+ */
+ public function testInvalidHostRequest()
+ {
+ $this->_checkPlugin();
+
+ $client = $this->_getClient(array('host' => 'unknown', 'port' => 9555, 'transport' => 'Thrift'));
+ $client->getStatus();
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\ResponseException
+ */
+ public function testInvalidElasticRequest()
+ {
+ $this->_checkPlugin();
+
+ $connection = new Connection();
+ $connection->setHost($this->_getHost());
+ $connection->setPort(9500);
+ $connection->setTransport('Thrift');
+
+ $client = $this->_getClient();
+ $client->addConnection($connection);
+
+ $index = new Index($client, 'missing_index');
+ $index->getStatus();
+ }
+
+ public function configProvider()
+ {
+ return array(
+ array(
+ array(
+ 'host' => $this->_getHost(),
+ 'port' => 9500,
+ 'transport' => 'Thrift',
+ ),
+ ),
+ array(
+ array(
+ 'host' => $this->_getHost(),
+ 'port' => 9500,
+ 'transport' => 'Thrift',
+ 'config' => array(
+ 'framedTransport' => false,
+ 'sendTimeout' => 10000,
+ 'recvTimeout' => 20000,
+ ),
+ ),
+ ),
+ );
+ }
+
+ protected function _checkPlugin()
+ {
+ $nodes = $this->_getClient()->getCluster()->getNodes();
+ if (!$nodes[0]->getInfo()->hasPlugin('transport-thrift')) {
+ $this->markTestSkipped('transport-thrift plugin not installed.');
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/TransportBenchmarkTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/TransportBenchmarkTest.php
new file mode 100644
index 00000000..11a16a34
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Transport/TransportBenchmarkTest.php
@@ -0,0 +1,261 @@
+<?php
+namespace Elastica\Test\Transport;
+
+use Elastica\Document;
+use Elastica\Index;
+use Elastica\Query;
+use Elastica\Test\Base as BaseTest;
+
+class TransportBenchmarkTest extends BaseTest
+{
+ protected $_max = 1000;
+
+ protected $_maxData = 20;
+
+ protected static $_results = array();
+
+ public static function tearDownAfterClass()
+ {
+ self::printResults();
+ }
+
+ /**
+ * @param array $config
+ *
+ * @return \Elastica\Type
+ */
+ protected function getType(array $config)
+ {
+ $client = $this->_getClient($config);
+ $index = $client->getIndex('benchmark'.uniqid());
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ return $index->getType('benchmark');
+ }
+
+ /**
+ * @dataProvider providerTransport
+ * @group benchmark
+ */
+ public function testAddDocument(array $config, $transport)
+ {
+ $this->_checkThrift($transport);
+
+ $type = $this->getType($config);
+ $index = $type->getIndex();
+ $index->create(array(), true);
+
+ $times = array();
+ for ($i = 0; $i < $this->_max; $i++) {
+ $data = $this->getData($i);
+ $doc = new Document($i, $data);
+ $result = $type->addDocument($doc);
+ $times[] = $result->getQueryTime();
+ $this->assertTrue($result->isOk());
+ }
+
+ $index->refresh();
+
+ self::logResults('insert', $transport, $times);
+ }
+
+ /**
+ * @depends testAddDocument
+ * @dataProvider providerTransport
+ * @group benchmark
+ */
+ public function testRandomRead(array $config, $transport)
+ {
+ $this->_checkThrift($transport);
+
+ $type = $this->getType($config);
+
+ $type->search('test');
+
+ $times = array();
+ for ($i = 0; $i < $this->_max; $i++) {
+ $test = rand(1, $this->_max);
+ $query = new Query();
+ $query->setQuery(new \Elastica\Query\MatchAll());
+ $query->setPostFilter(new \Elastica\Filter\Term(array('test' => $test)));
+ $result = $type->search($query);
+ $times[] = $result->getResponse()->getQueryTime();
+ }
+
+ self::logResults('random read', $transport, $times);
+ }
+
+ /**
+ * @depends testAddDocument
+ * @dataProvider providerTransport
+ * @group benchmark
+ */
+ public function testBulk(array $config, $transport)
+ {
+ $type = $this->getType($config);
+
+ $times = array();
+ for ($i = 0; $i < $this->_max; $i++) {
+ $docs = array();
+ for ($j = 0; $j < 10; $j++) {
+ $data = $this->getData($i.$j);
+ $docs[] = new Document($i, $data);
+ }
+
+ $result = $type->addDocuments($docs);
+ $times[] = $result->getQueryTime();
+ }
+
+ self::logResults('bulk', $transport, $times);
+ }
+
+ /**
+ * @dataProvider providerTransport
+ * @group benchmark
+ */
+ public function testGetMapping(array $config, $transport)
+ {
+ $client = $this->_getClient($config);
+ $index = $client->getIndex('benchmark');
+ $index->create(array(), true);
+ $type = $index->getType('mappingTest');
+
+ // Define mapping
+ $mapping = new \Elastica\Type\Mapping();
+ $mapping->setParam('_boost', array('name' => '_boost', 'null_value' => 1.0));
+ $mapping->setProperties(array(
+ 'id' => array('type' => 'integer', 'include_in_all' => false),
+ 'user' => array(
+ 'type' => 'object',
+ 'properties' => array(
+ 'name' => array('type' => 'string', 'include_in_all' => true),
+ 'fullName' => array('type' => 'string', 'include_in_all' => true),
+ ),
+ ),
+ 'msg' => array('type' => 'string', 'include_in_all' => true),
+ 'tstamp' => array('type' => 'date', 'include_in_all' => false),
+ 'location' => array('type' => 'geo_point', 'include_in_all' => false),
+ '_boost' => array('type' => 'float', 'include_in_all' => false),
+ ));
+
+ $type->setMapping($mapping);
+ $index->refresh();
+
+ $times = array();
+ for ($i = 0; $i < $this->_max; $i++) {
+ $response = $type->request('_mapping', \Elastica\Request::GET);
+ $times[] = $response->getQueryTime();
+ }
+ self::logResults('get mapping', $transport, $times);
+ }
+
+ public function providerTransport()
+ {
+ return array(
+ array(
+ array(
+ 'transport' => 'Http',
+ 'host' => $this->_getHost(),
+ 'port' => $this->_getPort(),
+ 'persistent' => false,
+ ),
+ 'Http:NotPersistent',
+ ),
+ array(
+ array(
+ 'transport' => 'Http',
+ 'host' => $this->_getHost(),
+ 'port' => $this->_getPort(),
+ 'persistent' => true,
+ ),
+ 'Http:Persistent',
+ ),
+ array(
+ array(
+ 'transport' => 'Thrift',
+ 'host' => $this->_getHost(),
+ 'port' => 9500,
+ 'config' => array(
+ 'framedTransport' => false,
+ ),
+ ),
+ 'Thrift:Buffered',
+ ),
+ );
+ }
+
+ /**
+ * @param string $test
+ *
+ * @return array
+ */
+ protected function getData($test)
+ {
+ $data = array(
+ 'test' => $test,
+ 'name' => array(),
+ );
+ for ($i = 0; $i < $this->_maxData; $i++) {
+ $data['name'][] = uniqid();
+ }
+
+ return $data;
+ }
+
+ /**
+ * @param $name
+ * @param $transport
+ * @param array $times
+ */
+ protected static function logResults($name, $transport, array $times)
+ {
+ self::$_results[$name][$transport] = array(
+ 'count' => count($times),
+ 'max' => max($times) * 1000,
+ 'min' => min($times) * 1000,
+ 'mean' => (array_sum($times) / count($times)) * 1000,
+ );
+ }
+
+ protected static function printResults()
+ {
+ echo sprintf(
+ "\n%-12s | %-20s | %-12s | %-12s | %-12s | %-12s\n\n",
+ 'NAME',
+ 'TRANSPORT',
+ 'COUNT',
+ 'MAX',
+ 'MIN',
+ 'MEAN',
+ '%'
+ );
+ foreach (self::$_results as $name => $values) {
+ $means = array();
+ foreach ($values as $times) {
+ $means[] = $times['mean'];
+ }
+ $minMean = min($means);
+ foreach ($values as $transport => $times) {
+ $perc = (($times['mean'] - $minMean) / $minMean) * 100;
+ echo sprintf(
+ "%-12s | %-20s | %-12d | %-12.2f | %-12.2f | %-12.2f | %+03.2f\n",
+ $name,
+ $transport,
+ $times['count'],
+ $times['max'],
+ $times['min'],
+ $times['mean'],
+ $perc
+ );
+ }
+ echo "\n";
+ }
+ }
+
+ protected function _checkThrift($transport)
+ {
+ if (strpos($transport, 'Thrift') !== false && !class_exists('Elasticsearch\\RestClient')) {
+ self::markTestSkipped('munkie/elasticsearch-thrift-php package should be installed to run thrift transport tests');
+ }
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/Type/MappingTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/Type/MappingTest.php
new file mode 100644
index 00000000..925c23bb
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/Type/MappingTest.php
@@ -0,0 +1,331 @@
+<?php
+namespace Elastica\Test\Type;
+
+use Elastica\Document;
+use Elastica\Query;
+use Elastica\Query\QueryString;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Type\Mapping;
+
+class MappingTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testMappingStoreFields()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type,
+ array(
+ 'firstname' => array('type' => 'string', 'store' => 'yes'),
+ // default is store => no expected
+ 'lastname' => array('type' => 'string'),
+ )
+ );
+ $mapping->disableSource();
+
+ $type->setMapping($mapping);
+
+ $firstname = 'Nicolas';
+ $doc = new Document(1,
+ array(
+ 'firstname' => $firstname,
+ 'lastname' => 'Ruflin',
+ )
+ );
+
+ $type->addDocument($doc);
+
+ $index->refresh();
+ $queryString = new QueryString('ruflin');
+ $query = Query::create($queryString);
+ $query->setFields(array('*'));
+
+ $resultSet = $type->search($query);
+ $result = $resultSet->current();
+ $fields = $result->getFields();
+
+ $this->assertEquals($firstname, $fields['firstname'][0]);
+ $this->assertArrayNotHasKey('lastname', $fields);
+ $this->assertEquals(1, count($fields));
+
+ $index->flush();
+ $document = $type->getDocument(1);
+
+ $this->assertEmpty($document->getData());
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testEnableAllField()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array());
+
+ $mapping->enableAllField();
+
+ $data = $mapping->toArray();
+ $this->assertTrue($data[$type->getName()]['_all']['enabled']);
+
+ $response = $mapping->send();
+ $this->assertTrue($response->isOk());
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testEnableTtl()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ $mapping = new Mapping($type, array());
+
+ $mapping->enableTtl();
+
+ $data = $mapping->toArray();
+ $this->assertTrue($data[$type->getName()]['_ttl']['enabled']);
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testNestedMapping()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('test');
+
+ $index->create(array(), true);
+ $type = $index->getType('test');
+
+ //$this->markTestIncomplete('nested mapping is not set right yet');
+ $mapping = new Mapping($type,
+ array(
+ 'test' => array(
+ 'type' => 'object', 'store' => 'yes', 'properties' => array(
+ 'user' => array(
+ 'properties' => array(
+ 'firstname' => array('type' => 'string', 'store' => 'yes'),
+ 'lastname' => array('type' => 'string', 'store' => 'yes'),
+ 'age' => array('type' => 'integer', 'store' => 'yes'),
+ ),
+ ),
+ ),
+ ),
+ )
+ );
+
+ $response = $type->setMapping($mapping);
+ $this->assertFalse($response->hasError());
+
+ $doc = new Document(1, array(
+ 'user' => array(
+ 'firstname' => 'Nicolas',
+ 'lastname' => 'Ruflin',
+ 'age' => 9,
+ ),
+ ));
+
+ $type->addDocument($doc);
+
+ $index->refresh();
+ $resultSet = $type->search('ruflin');
+ $this->assertEquals($resultSet->count(), 1);
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testParentMapping()
+ {
+ $index = $this->_createIndex();
+ $parenttype = new Type($index, 'parenttype');
+ $parentmapping = new Mapping($parenttype,
+ array(
+ 'name' => array('type' => 'string', 'store' => 'yes'),
+ )
+ );
+
+ $parenttype->setMapping($parentmapping);
+
+ $childtype = new Type($index, 'childtype');
+ $childmapping = new Mapping($childtype,
+ array(
+ 'name' => array('type' => 'string', 'store' => 'yes'),
+ )
+ );
+ $childmapping->setParent('parenttype');
+
+ $childtype->setMapping($childmapping);
+
+ $data = $childmapping->toArray();
+ $this->assertEquals('parenttype', $data[$childtype->getName()]['_parent']['type']);
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMappingExample()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('notes');
+
+ $mapping = new Mapping($type,
+ array(
+ 'note' => array(
+ 'store' => 'yes', 'properties' => array(
+ 'titulo' => array('type' => 'string', 'store' => 'no', 'include_in_all' => true, 'boost' => 1.0),
+ 'contenido' => array('type' => 'string', 'store' => 'no', 'include_in_all' => true, 'boost' => 1.0),
+ ),
+ ),
+ )
+ );
+
+ $type->setMapping($mapping);
+
+ $doc = new Document(1, array(
+ 'note' => array(
+ array(
+ 'titulo' => 'nota1',
+ 'contenido' => 'contenido1',
+ ),
+ array(
+ 'titulo' => 'nota2',
+ 'contenido' => 'contenido2',
+ ),
+ ),
+ )
+ );
+
+ $type->addDocument($doc);
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ *
+ * Test setting a dynamic template and validate whether the right mapping is applied after adding a document which
+ * should match the dynamic template. The example is the template_1 from the Elasticsearch documentation.
+ *
+ * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-root-object-type.html
+ */
+ public function testDynamicTemplate()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('person');
+
+ // set a dynamic template "template_1" which creates a multi field for multi* matches.
+ $mapping = new Mapping($type);
+ $mapping->setParam('dynamic_templates', array(
+ array('template_1' => array(
+ 'match' => 'multi*',
+ 'mapping' => array(
+ 'type' => 'multi_field',
+ 'fields' => array(
+ '{name}' => array('type' => '{dynamic_type}', 'index' => 'analyzed'),
+ 'org' => array('type' => '{dynamic_type}', 'index' => 'not_analyzed'),
+ ),
+ ),
+ )),
+ ));
+
+ $mapping->send();
+
+ // when running the tests, the mapping sometimes isn't available yet. Optimize index to enforce reload mapping.
+ $index->optimize();
+
+ // create a document which should create a mapping for the field: multiname.
+ $testDoc = new Document('person1', array('multiname' => 'Jasper van Wanrooy'), $type);
+ $index->addDocuments(array($testDoc));
+ sleep(1); //sleep 1 to ensure that the test passes every time
+
+ // read the mapping from Elasticsearch and assert that the multiname.org field is "not_analyzed"
+ $newMapping = $type->getMapping();
+ $this->assertArrayHasKey('person', $newMapping,
+ 'Person type not available in mapping from ES. Mapping set at all?');
+ $this->assertArrayHasKey('properties', $newMapping['person'],
+ 'Person type doesnt have any properties. Document properly added?');
+ $this->assertArrayHasKey('multiname', $newMapping['person']['properties'],
+ 'The multiname property is not added to the mapping. Document properly added?');
+ $this->assertArrayHasKey('fields', $newMapping['person']['properties']['multiname'],
+ 'The multiname field of the Person type is presumably not a multi_field type. Dynamic mapping not applied?');
+ $this->assertArrayHasKey('org', $newMapping['person']['properties']['multiname']['fields'],
+ 'The multi* matcher did not create a mapping for the multiname.org property when indexing the document.');
+ $this->assertArrayHasKey('index', $newMapping['person']['properties']['multiname']['fields']['org'],
+ 'Indexing status of the multiname.org not available. Dynamic mapping not fully applied!');
+ $this->assertEquals('not_analyzed', $newMapping['person']['properties']['multiname']['fields']['org']['index']);
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testSetMeta()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $mapping = new Mapping($type, array(
+ 'firstname' => array('type' => 'string', 'store' => 'yes'),
+ 'lastname' => array('type' => 'string'),
+ ));
+ $mapping->setMeta(array('class' => 'test'));
+ $type->setMapping($mapping);
+
+ $mappingData = $type->getMapping();
+ $this->assertEquals('test', $mappingData['test']['_meta']['class']);
+
+ $index->delete();
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetters()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test');
+ $properties = array(
+ 'firstname' => array('type' => 'string', 'store' => 'yes'),
+ 'lastname' => array('type' => 'string'),
+ );
+ $mapping = new Mapping($type, $properties);
+ $all = array(
+ 'enabled' => true,
+ 'store' => 'yes',
+ );
+ $mapping->setParam('_all', $all);
+ $get_all = $mapping->getParam('_all');
+
+ $this->assertEquals($get_all, $all);
+
+ $this->assertNull($mapping->getParam('_boost', $all));
+
+ $this->assertEquals($properties, $mapping->getProperties());
+
+ $index->delete();
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/TypeTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/TypeTest.php
new file mode 100644
index 00000000..dcb74ac5
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/TypeTest.php
@@ -0,0 +1,968 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Document;
+use Elastica\Exception\NotFoundException;
+use Elastica\Exception\ResponseException;
+use Elastica\Filter\Term;
+use Elastica\Index;
+use Elastica\Query;
+use Elastica\Query\MatchAll;
+use Elastica\Query\SimpleQueryString;
+use Elastica\Script;
+use Elastica\Search;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Type;
+use Elastica\Type\Mapping;
+
+class TypeTest extends BaseTest
+{
+ /**
+ * @group functional
+ */
+ public function testSearch()
+ {
+ $index = $this->_createIndex();
+
+ $type = new Type($index, 'user');
+
+ // Adds 1 document to the index
+ $doc1 = new Document(1,
+ array('username' => 'hans', 'test' => array('2', '3', '5'))
+ );
+ $type->addDocument($doc1);
+
+ // Adds a list of documents with _bulk upload to the index
+ $docs = array();
+ $docs[] = new Document(2,
+ array('username' => 'john', 'test' => array('1', '3', '6'))
+ );
+ $docs[] = new Document(3,
+ array('username' => 'rolf', 'test' => array('2', '3', '7'))
+ );
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $resultSet = $type->search('rolf');
+ $this->assertEquals(1, $resultSet->count());
+
+ $count = $type->count('rolf');
+ $this->assertEquals(1, $count);
+
+ // Test if source is returned
+ $result = $resultSet->current();
+ $this->assertEquals(3, $result->getId());
+ $data = $result->getData();
+ $this->assertEquals('rolf', $data['username']);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCreateSearch()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test_index');
+ $type = new Type($index, 'test_type');
+
+ $query = new Query\QueryString('test');
+ $options = array(
+ 'limit' => 5,
+ 'explain' => true,
+ );
+
+ $search = $type->createSearch($query, $options);
+
+ $expected = array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'test',
+ ),
+ ),
+ 'size' => 5,
+ 'explain' => true,
+ );
+ $this->assertEquals($expected, $search->getQuery()->toArray());
+ $this->assertEquals(array('test_index'), $search->getIndices());
+ $this->assertTrue($search->hasIndices());
+ $this->assertTrue($search->hasIndex($index));
+ $this->assertTrue($search->hasIndex('test_index'));
+ $this->assertFalse($search->hasIndex('test'));
+ $this->assertEquals(array('test_type'), $search->getTypes());
+ $this->assertTrue($search->hasTypes());
+ $this->assertTrue($search->hasType($type));
+ $this->assertTrue($search->hasType('test_type'));
+ $this->assertFalse($search->hasType('test_type2'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testCreateSearchWithArray()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'test_index');
+ $type = new Type($index, 'test_type');
+
+ $query = array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'test',
+ ),
+ ),
+ );
+
+ $options = array(
+ 'limit' => 5,
+ 'explain' => true,
+ );
+
+ $search = $type->createSearch($query, $options);
+
+ $expected = array(
+ 'query' => array(
+ 'query_string' => array(
+ 'query' => 'test',
+ ),
+ ),
+ 'size' => 5,
+ 'explain' => true,
+ );
+ $this->assertEquals($expected, $search->getQuery()->toArray());
+ $this->assertEquals(array('test_index'), $search->getIndices());
+ $this->assertTrue($search->hasIndices());
+ $this->assertTrue($search->hasIndex($index));
+ $this->assertTrue($search->hasIndex('test_index'));
+ $this->assertFalse($search->hasIndex('test'));
+ $this->assertEquals(array('test_type'), $search->getTypes());
+ $this->assertTrue($search->hasTypes());
+ $this->assertTrue($search->hasType($type));
+ $this->assertTrue($search->hasType('test_type'));
+ $this->assertFalse($search->hasType('test_type2'));
+ }
+
+ /**
+ * @group functional
+ */
+ public function testNoSource()
+ {
+ $index = $this->_createIndex();
+
+ $type = new Type($index, 'user');
+ $mapping = new Mapping($type, array(
+ 'id' => array('type' => 'integer', 'store' => 'yes'),
+ 'username' => array('type' => 'string', 'store' => 'no'),
+ ));
+ $mapping->setSource(array('enabled' => false));
+ $type->setMapping($mapping);
+
+ $mapping = $type->getMapping();
+
+ $this->assertArrayHasKey('user', $mapping);
+ $this->assertArrayHasKey('properties', $mapping['user']);
+ $this->assertArrayHasKey('id', $mapping['user']['properties']);
+ $this->assertArrayHasKey('type', $mapping['user']['properties']['id']);
+ $this->assertEquals('integer', $mapping['user']['properties']['id']['type']);
+
+ // Adds 1 document to the index
+ $doc1 = new Document(1,
+ array('username' => 'hans', 'test' => array('2', '3', '5'))
+ );
+ $type->addDocument($doc1);
+
+ // Adds a list of documents with _bulk upload to the index
+ $docs = array();
+ $docs[] = new Document(2,
+ array('username' => 'john', 'test' => array('1', '3', '6'))
+ );
+ $docs[] = new Document(3,
+ array('username' => 'rolf', 'test' => array('2', '3', '7'))
+ );
+ $type->addDocuments($docs);
+
+ // To update index
+ $index->refresh();
+
+ $resultSet = $type->search('rolf');
+
+ $this->assertEquals(1, $resultSet->count());
+
+ // Tests if no source is in response except id
+ $result = $resultSet->current();
+ $this->assertEquals(3, $result->getId());
+ $this->assertEmpty($result->getData());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteById()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'user');
+
+ // Adds hans, john and rolf to the index
+ $docs = array(
+ new Document(1, array('username' => 'hans', 'test' => array('2', '3', '5'))),
+ new Document(2, array('username' => 'john', 'test' => array('1', '3', '6'))),
+ new Document(3, array('username' => 'rolf', 'test' => array('2', '3', '7'))),
+ new Document('foo/bar', array('username' => 'georg', 'test' => array('4', '2', '5'))),
+ );
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ // sanity check for rolf
+ $resultSet = $type->search('rolf');
+ $this->assertEquals(1, $resultSet->count());
+ $data = $resultSet->current()->getData();
+ $this->assertEquals('rolf', $data['username']);
+
+ // delete rolf
+ $type->deleteById(3);
+ $index->refresh();
+
+ // rolf should no longer be there
+ $resultSet = $type->search('rolf');
+ $this->assertEquals(0, $resultSet->count());
+
+ // sanity check for id with slash
+ $resultSet = $type->search('georg');
+ $this->assertEquals(1, $resultSet->count());
+
+ // delete georg
+ $type->deleteById('foo/bar');
+ $index->refresh();
+
+ // georg should no longer be there
+ $resultSet = $type->search('georg');
+ $this->assertEquals(0, $resultSet->count());
+
+ // it should not be possible to delete the entire type with this method
+ try {
+ $type->deleteById('');
+ $this->fail('Delete with empty string id should fail');
+ } catch (\InvalidArgumentException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $type->deleteById(' ');
+ $this->fail('Delete with one space string id should fail');
+ } catch (\InvalidArgumentException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $type->deleteById(null);
+ $this->fail('Delete with null id should fail');
+ } catch (\InvalidArgumentException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $type->deleteById(array());
+ $this->fail('Delete with empty array id should fail');
+ } catch (\InvalidArgumentException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $type->deleteById('*');
+ $this->fail('Delete request should fail because of invalid id: *');
+ } catch (NotFoundException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $type->deleteById('*:*');
+ $this->fail('Delete request should fail because document with id *.* does not exist');
+ } catch (NotFoundException $e) {
+ $this->assertTrue(true);
+ }
+
+ try {
+ $type->deleteById('!');
+ $this->fail('Delete request should fail because document with id ! does not exist');
+ } catch (NotFoundException $e) {
+ $this->assertTrue(true);
+ }
+
+ $index->refresh();
+
+ // rolf should no longer be there
+ $resultSet = $type->search('john');
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteDocument()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'user');
+
+ // Adds hans, john and rolf to the index
+ $docs = array(
+ new Document(1, array('username' => 'hans', 'test' => array('2', '3', '5'))),
+ new Document(2, array('username' => 'john', 'test' => array('1', '3', '6'))),
+ new Document(3, array('username' => 'rolf', 'test' => array('2', '3', '7'))),
+ );
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ $document = $type->getDocument(1);
+ $this->assertEquals(1, $document->getId());
+ $this->assertEquals('hans', $document->get('username'));
+
+ $this->assertEquals(3, $type->count());
+
+ $type->deleteDocument($document);
+ $index->refresh();
+
+ try {
+ $type->getDocument(1);
+ $this->fail('Document was not deleted');
+ } catch (NotFoundException $e) {
+ $this->assertTrue(true);
+ $this->assertEquals(2, $type->count(), 'Documents count in type should be 2');
+ }
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\NotFoundException
+ */
+ public function testGetDocumentNotExist()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+ $type->addDocument(new Document(1, array('name' => 'ruflin')));
+ $index->refresh();
+
+ $type->getDocument(1);
+
+ $type->getDocument(2);
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\ResponseException
+ */
+ public function testGetDocumentNotExistingIndex()
+ {
+ $client = $this->_getClient();
+ $index = new Index($client, 'index');
+ $type = new Type($index, 'type');
+
+ $type->getDocument(1);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteByQueryWithQueryString()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+ $type->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type->addDocument(new Document(2, array('name' => 'ruflin')));
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(2, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(1, $response->count());
+
+ // Delete first document
+ $response = $type->deleteByQuery('nicolas');
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ // Makes sure, document is deleted
+ $response = $index->search('ruflin*');
+ $this->assertEquals(1, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(0, $response->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteByQueryWithQuery()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+ $type->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type->addDocument(new Document(2, array('name' => 'ruflin')));
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(2, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(1, $response->count());
+
+ // Delete first document
+ $response = $type->deleteByQuery(new SimpleQueryString('nicolas'));
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ // Makes sure, document is deleted
+ $response = $index->search('ruflin*');
+ $this->assertEquals(1, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(0, $response->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testDeleteByQueryWithQueryAndOptions()
+ {
+ $index = $this->_createIndex(null, true, 2);
+ $type = new Type($index, 'test');
+ $type->addDocument(new Document(1, array('name' => 'ruflin nicolas')));
+ $type->addDocument(new Document(2, array('name' => 'ruflin')));
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(2, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(1, $response->count());
+
+ // Route to the wrong document id; should not delete
+ $response = $type->deleteByQuery(new SimpleQueryString('nicolas'), array('routing' => '2'));
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ $response = $index->search('ruflin*');
+ $this->assertEquals(2, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(1, $response->count());
+
+ // Delete first document
+ $response = $type->deleteByQuery(new SimpleQueryString('nicolas'), array('routing' => '1'));
+ $this->assertTrue($response->isOk());
+
+ $index->refresh();
+
+ // Makes sure, document is deleted
+ $response = $index->search('ruflin*');
+ $this->assertEquals(1, $response->count());
+
+ $response = $index->search('nicolas');
+ $this->assertEquals(0, $response->count());
+ }
+
+ /**
+ * Test to see if Elastica_Type::getDocument() is properly using
+ * the fields array when available instead of _source.
+ *
+ * @group functional
+ */
+ public function testGetDocumentWithFieldsSelection()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+ $type->addDocument(new Document(1, array('name' => 'loris', 'country' => 'FR', 'email' => 'test@test.com')));
+ $index->refresh();
+
+ $document = $type->getDocument(1, array('fields' => 'name,email'));
+ $data = $document->getData();
+
+ $this->assertArrayHasKey('name', $data);
+ $this->assertArrayHasKey('email', $data);
+ $this->assertArrayNotHasKey('country', $data);
+ }
+
+ /**
+ * Test to see if search Default Limit works.
+ *
+ * @group functional
+ */
+ public function testLimitDefaultType()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('zero');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $docs = array();
+ $docs[] = new Document(1, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(2, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(3, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(4, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(5, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(6, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(7, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(8, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(9, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(10, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+ $docs[] = new Document(11, array('id' => 1, 'email' => 'test@test.com', 'username' => 'farrelley'));
+
+ $type = $index->getType('zeroType');
+ $type->addDocuments($docs);
+ $index->refresh();
+
+ // default results (limit default is 10)
+ $resultSet = $type->search('farrelley');
+ $this->assertEquals(10, $resultSet->count());
+
+ // limit = 1
+ $resultSet = $type->search('farrelley', 1);
+ $this->assertEquals(1, $resultSet->count());
+ }
+
+ /**
+ * Test Delete of index type. After delete will check for type mapping.
+ *
+ * @group functional
+ */
+ public function testDeleteType()
+ {
+ $index = $this->_createIndex();
+ $type = new Type($index, 'test');
+ $type->addDocuments(array(
+ new Document(1, array('name' => 'ruflin nicolas')),
+ new Document(2, array('name' => 'ruflin')),
+ ));
+ $index->refresh();
+
+ // sleep a moment to be sure that all nodes in cluster has new type
+ sleep(5);
+
+ $type->delete();
+ $index->optimize();
+
+ $this->assertFalse($type->exists());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testMoreLikeThisApi()
+ {
+ $client = $this->_getClient(array('persistent' => false));
+ $index = $client->getIndex('elastica_test');
+ $index->create(array('index' => array('number_of_shards' => 1, 'number_of_replicas' => 0)), true);
+
+ $type = new Type($index, 'mlt_test');
+ $type->addDocuments(array(
+ new Document(1, array('visible' => true, 'name' => 'bruce wayne batman')),
+ new Document(2, array('visible' => true, 'name' => 'bruce wayne')),
+ new Document(3, array('visible' => false, 'name' => 'bruce wayne')),
+ new Document(4, array('visible' => true, 'name' => 'batman')),
+ new Document(5, array('visible' => false, 'name' => 'batman')),
+ new Document(6, array('visible' => true, 'name' => 'superman')),
+ new Document(7, array('visible' => true, 'name' => 'spiderman')),
+ ));
+ $index->refresh();
+
+ $document = $type->getDocument(1);
+
+ // Return all similar
+ $resultSet = $type->moreLikeThis($document, array('min_term_freq' => '1', 'min_doc_freq' => '1'));
+ $this->assertEquals(4, $resultSet->count());
+
+ // Return just the visible similar
+ $query = new Query();
+ $filterTerm = new Term();
+ $filterTerm->setTerm('visible', true);
+ $query->setPostFilter($filterTerm);
+
+ $resultSet = $type->moreLikeThis($document, array('min_term_freq' => '1', 'min_doc_freq' => '1'), $query);
+ $this->assertEquals(2, $resultSet->count());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocument()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_test');
+ $type = $index->getType('update_type');
+ $id = 1;
+ $type->addDocument(new Document($id, array('name' => 'bruce wayne batman', 'counter' => 1)));
+ $newName = 'batman';
+
+ $document = new Document();
+ $script = new Script(
+ 'ctx._source.name = name; ctx._source.counter += count',
+ array(
+ 'name' => $newName,
+ 'count' => 2,
+ ),
+ null,
+ $id
+ );
+ $script->setUpsert($document);
+
+ $type->updateDocument($script, array('refresh' => true));
+ $updatedDoc = $type->getDocument($id)->getData();
+ $this->assertEquals($newName, $updatedDoc['name'], 'Name was not updated');
+ $this->assertEquals(3, $updatedDoc['counter'], 'Counter was not incremented');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentWithIdForwardSlashes()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_test');
+ $type = $index->getType('update_type');
+ $id = '/id/with/forward/slashes';
+ $type->addDocument(new Document($id, array('name' => 'bruce wayne batman', 'counter' => 1)));
+ $newName = 'batman';
+
+ $document = new Document();
+ $script = new Script(
+ 'ctx._source.name = name; ctx._source.counter += count',
+ array(
+ 'name' => $newName,
+ 'count' => 2,
+ ),
+ null,
+ $id
+ );
+ $script->setUpsert($document);
+
+ $type->updateDocument($script, array('refresh' => true));
+ $updatedDoc = $type->getDocument($id)->getData();
+ $this->assertEquals($newName, $updatedDoc['name'], 'Name was not updated');
+ $this->assertEquals(3, $updatedDoc['counter'], 'Counter was not incremented');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentWithParameter()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_test');
+ $type = $index->getType('update_type');
+ $id = 1;
+ $type->addDocument(new Document($id, array('name' => 'bruce wayne batman', 'counter' => 1)));
+ $newName = 'batman';
+
+ $document = new Document();
+ $script = new Script(
+ 'ctx._source.name = name; ctx._source.counter += count',
+ array(
+ 'name' => $newName,
+ 'count' => 2,
+ ),
+ null,
+ $id
+ );
+ $script->setUpsert($document);
+
+ try {
+ $type->updateDocument($script, array('version' => 999)); // Wrong version number to make the update fail
+ } catch (ResponseException $e) {
+ $this->assertContains('VersionConflictEngineException', $e->getMessage());
+ }
+ $updatedDoc = $type->getDocument($id)->getData();
+ $this->assertNotEquals($newName, $updatedDoc['name'], 'Name was updated');
+ $this->assertNotEquals(3, $updatedDoc['counter'], 'Counter was incremented');
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentWithFieldsSource()
+ {
+ $client = $this->_getClient();
+ $index = $client->getIndex('elastica_test');
+ $type = $index->getType('update_type');
+
+ $client->setConfigValue('document', array('autoPopulate' => true));
+
+ $newDocument = new Document(null, array('counter' => 5, 'name' => 'Batman'));
+
+ $this->assertFalse($newDocument->hasVersion());
+
+ $response = $type->addDocument($newDocument);
+ $responseData = $response->getData();
+
+ $this->assertTrue($newDocument->hasVersion());
+ $this->assertArrayHasKey('_version', $responseData, '_version is missing in response data it is weird');
+ $this->assertEquals(1, $responseData['_version']);
+ $this->assertEquals($responseData['_version'], $newDocument->getVersion());
+
+ $this->assertTrue($newDocument->hasId());
+
+ $script = new Script('ctx._source.counter += count; ctx._source.realName = realName');
+ $script->setId($newDocument->getId());
+ $script->setParam('count', 7);
+ $script->setParam('realName', 'Bruce Wayne');
+ $script->setUpsert($newDocument);
+
+ $newDocument->setFieldsSource();
+
+ $response = $type->updateDocument($script);
+ $responseData = $response->getData();
+
+ $data = $type->getDocument($newDocument->getId())->getData();
+
+ $this->assertEquals(12, $data['counter']);
+ $this->assertEquals('Batman', $data['name']);
+ $this->assertEquals('Bruce Wayne', $data['realName']);
+
+ $this->assertTrue($newDocument->hasVersion());
+ $this->assertArrayHasKey('_version', $responseData, '_version is missing in response data it is weird');
+ $this->assertEquals(2, $responseData['_version']);
+
+ $document = $type->getDocument($newDocument->getId());
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\InvalidException
+ */
+ public function testUpdateDocumentWithoutId()
+ {
+ $index = $this->_createIndex();
+ $this->_waitForAllocation($index);
+ $type = $index->getType('elastica_type');
+
+ $document = new Document();
+
+ $type->updateDocument($document);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testUpdateDocumentWithoutSource()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('elastica_type');
+
+ $mapping = new Mapping();
+ $mapping->setProperties(array(
+ 'name' => array(
+ 'type' => 'string',
+ 'store' => 'yes', ),
+ 'counter' => array(
+ 'type' => 'integer',
+ 'store' => 'no',
+ ),
+ ));
+ $mapping->disableSource();
+ $type->setMapping($mapping);
+
+ $newDocument = new Document();
+ $newDocument->setAutoPopulate();
+ $newDocument->set('name', 'Batman');
+ $newDocument->set('counter', 1);
+
+ $type->addDocument($newDocument);
+
+ $script = new Script('ctx._source.counter += count; ctx._source.name = name');
+ $script->setId($newDocument->getId());
+ $script->setParam('count', 2);
+ $script->setParam('name', 'robin');
+
+ $script->setUpsert($newDocument);
+
+ try {
+ $type->updateDocument($script);
+ $this->fail('Update request should fail because source is disabled. Fields param is not set');
+ } catch (ResponseException $e) {
+ $this->assertContains('DocumentSourceMissingException', $e->getMessage());
+ }
+
+ $newDocument->setFieldsSource();
+
+ try {
+ $type->updateDocument($newDocument);
+ $this->fail('Update request should fail because source is disabled. Fields param is set to _source');
+ } catch (ResponseException $e) {
+ $this->assertContains('DocumentSourceMissingException', $e->getMessage());
+ }
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddDocumentHashId()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('test2');
+
+ $hashId = '#1';
+
+ $doc = new Document($hashId, array('name' => 'ruflin'));
+ $type->addDocument($doc);
+
+ $index->refresh();
+
+ $search = new Search($index->getClient());
+ $search->addIndex($index);
+ $resultSet = $search->search(new MatchAll());
+ $this->assertEquals($hashId, $resultSet->current()->getId());
+
+ $doc = $type->getDocument($hashId);
+ $this->assertEquals($hashId, $doc->getId());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddDocumentAutoGeneratedId()
+ {
+ $index = $this->_createIndex();
+ $type = $index->getType('elastica_type');
+
+ $document = new Document();
+ $document->setAutoPopulate();
+ $document->set('name', 'ruflin');
+ $this->assertEquals('', $document->getId());
+ $this->assertFalse($document->hasId());
+
+ $type->addDocument($document);
+
+ $this->assertNotEquals('', $document->getId());
+ $this->assertTrue($document->hasId());
+
+ $foundDoc = $type->getDocument($document->getId());
+ $this->assertInstanceOf('Elastica\Document', $foundDoc);
+ $this->assertEquals($document->getId(), $foundDoc->getId());
+ $data = $foundDoc->getData();
+ $this->assertArrayHasKey('name', $data);
+ $this->assertEquals('ruflin', $data['name']);
+ }
+
+ /**
+ * @group functional
+ * @expectedException \Elastica\Exception\RuntimeException
+ */
+ public function testAddDocumentWithoutSerializer()
+ {
+ $index = $this->_createIndex();
+ $this->_waitForAllocation($index);
+
+ $type = new Type($index, 'user');
+
+ $type->addObject(new \stdClass());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testAddObject()
+ {
+ $index = $this->_createIndex();
+
+ $type = new Type($index, 'user');
+ $type->setSerializer('get_object_vars');
+
+ $userObject = new \stdClass();
+ $userObject->username = 'hans';
+ $userObject->test = array('2', '3', '5');
+
+ $type->addObject($userObject);
+
+ $index->refresh();
+
+ $resultSet = $type->search('hans');
+ $this->assertEquals(1, $resultSet->count());
+
+ // Test if source is returned
+ $result = $resultSet->current();
+ $data = $result->getData();
+ $this->assertEquals('hans', $data['username']);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testSetSerializer()
+ {
+ $index = $this->_getClient()->getIndex('foo');
+ $type = $index->getType('user');
+ $ret = $type->setSerializer('get_object_vars');
+ $this->assertInstanceOf('Elastica\Type', $ret);
+ }
+
+ /**
+ * @group functional
+ */
+ public function testExists()
+ {
+ $index = $this->_createIndex();
+ $this->assertTrue($index->exists());
+
+ $type = new Type($index, 'user');
+ $this->assertFalse($type->exists());
+
+ $type->addDocument(new Document(1, array('name' => 'test name')));
+ $index->optimize();
+
+ // sleep a moment to be sure that all nodes in cluster has new type
+ sleep(5);
+
+ //Test if type exists
+ $this->assertTrue($type->exists());
+
+ $index->delete();
+ $this->assertFalse($index->exists());
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetMapping()
+ {
+ $typeName = 'test-type';
+
+ $index = $this->_createIndex();
+ $indexName = $index->getName();
+ $type = new Type($index, $typeName);
+ $mapping = new Mapping($type, $expect = array(
+ 'id' => array('type' => 'integer', 'store' => true),
+ ));
+ $type->setMapping($mapping);
+
+ $client = $index->getClient();
+
+ $this->assertEquals(
+ array('test-type' => array('properties' => $expect)),
+ $client->getIndex($indexName)->getType($typeName)->getMapping()
+ );
+ }
+
+ /**
+ * @group functional
+ */
+ public function testGetMappingAlias()
+ {
+ $aliasName = 'test-alias';
+ $typeName = 'test-alias-type';
+
+ $index = $this->_createIndex();
+ $index->addAlias($aliasName);
+ $type = new Type($index, $typeName);
+ $mapping = new Mapping($type, $expect = array(
+ 'id' => array('type' => 'integer', 'store' => true),
+ ));
+ $type->setMapping($mapping);
+
+ $client = $index->getClient();
+
+ $this->assertEquals(
+ array('test-alias-type' => array('properties' => $expect)),
+ $client->getIndex($aliasName)->getType($typeName)->getMapping()
+ );
+ }
+}
diff --git a/vendor/ruflin/elastica/test/lib/Elastica/Test/UtilTest.php b/vendor/ruflin/elastica/test/lib/Elastica/Test/UtilTest.php
new file mode 100644
index 00000000..a5b0f42e
--- /dev/null
+++ b/vendor/ruflin/elastica/test/lib/Elastica/Test/UtilTest.php
@@ -0,0 +1,139 @@
+<?php
+namespace Elastica\Test;
+
+use Elastica\Connection;
+use Elastica\Request;
+use Elastica\Test\Base as BaseTest;
+use Elastica\Util;
+
+class UtilTest extends BaseTest
+{
+ /**
+ * @group unit
+ * @dataProvider getEscapeTermPairs
+ */
+ public function testEscapeTerm($unescaped, $escaped)
+ {
+ $this->assertEquals($escaped, Util::escapeTerm($unescaped));
+ }
+
+ public function getEscapeTermPairs()
+ {
+ return array(
+ array('', ''),
+ array('pragmatic banana', 'pragmatic banana'),
+ array('oh yeah!', 'oh yeah\\!'),
+ // Seperate test below because phpunit seems to have some problems
+ //array('\\+-&&||!(){}[]^"~*?:', '\\\\\\+\\-\\&&\\||\\!\\(\\)\\{\\}\\[\\]\\^\\"\\~\\*\\?\\:'),
+ array('some signs, can stay.', 'some signs, can stay.'),
+ );
+ }
+
+ /**
+ * @group unit
+ * @dataProvider getReplaceBooleanWordsPairs
+ */
+ public function testReplaceBooleanWords($before, $after)
+ {
+ $this->assertEquals($after, Util::replaceBooleanWords($before));
+ }
+
+ public function getReplaceBooleanWordsPairs()
+ {
+ return array(
+ array('to be OR not to be', 'to be || not to be'),
+ array('ORIGINAL GIFTS', 'ORIGINAL GIFTS'),
+ array('Black AND White', 'Black && White'),
+ array('TIMBERLAND Men`s', 'TIMBERLAND Men`s'),
+ array('hello NOT kitty', 'hello !kitty'),
+ array('SEND NOTIFICATION', 'SEND NOTIFICATION'),
+ );
+ }
+
+ /**
+ * @group unit
+ */
+ public function testEscapeTermSpecialCharacters()
+ {
+ $before = '\\+-&&||!(){}[]^"~*?:/<>';
+ $after = '\\\\\\+\\-\\&&\\||\\!\\(\\)\\{\\}\\[\\]\\^\\"\\~\\*\\?\\:\\/\<\>';
+
+ $this->assertEquals(Util::escapeTerm($before), $after);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToCamelCase()
+ {
+ $string = 'hello_world';
+ $this->assertEquals('HelloWorld', Util::toCamelCase($string));
+
+ $string = 'how_are_you_today';
+ $this->assertEquals('HowAreYouToday', Util::toCamelCase($string));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testToSnakeCase()
+ {
+ $string = 'HelloWorld';
+ $this->assertEquals('hello_world', Util::toSnakeCase($string));
+
+ $string = 'HowAreYouToday';
+ $this->assertEquals('how_are_you_today', Util::toSnakeCase($string));
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConvertRequestToCurlCommand()
+ {
+ $path = 'test';
+ $method = Request::POST;
+ $query = array('no' => 'params');
+ $data = array('key' => 'value');
+
+ $connection = new Connection();
+ $connection->setHost($this->_getHost());
+ $connection->setPort('9200');
+
+ $request = new Request($path, $method, $data, $query, $connection);
+
+ $curlCommand = Util::convertRequestToCurlCommand($request);
+
+ $expected = 'curl -XPOST \'http://'.$this->_getHost().':9200/test?no=params\' -d \'{"key":"value"}\'';
+ $this->assertEquals($expected, $curlCommand);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConvertDateTimeObjectWithTimezone()
+ {
+ $dateTimeObject = new \DateTime();
+ $timestamp = $dateTimeObject->getTimestamp();
+
+ $convertedString = Util::convertDateTimeObject($dateTimeObject);
+
+ $date = date('Y-m-d\TH:i:sP', $timestamp);
+
+ $this->assertEquals($convertedString, $date);
+ }
+
+ /**
+ * @group unit
+ */
+ public function testConvertDateTimeObjectWithoutTimezone()
+ {
+ $dateTimeObject = new \DateTime();
+ $timestamp = $dateTimeObject->getTimestamp();
+
+ $convertedString = Util::convertDateTimeObject($dateTimeObject, false);
+
+ $date = date('Y-m-d\TH:i:s\Z', $timestamp);
+
+ $this->assertEquals($convertedString, $date);
+ }
+}
diff --git a/vendor/ruflin/elastica/test/phpunit.xhprof.xml b/vendor/ruflin/elastica/test/phpunit.xhprof.xml
new file mode 100644
index 00000000..59878cc2
--- /dev/null
+++ b/vendor/ruflin/elastica/test/phpunit.xhprof.xml
@@ -0,0 +1,39 @@
+<phpunit backupGlobals="false"
+ backupStaticAttributes="true"
+ bootstrap="../bootstrap.php"
+ colors="true">
+ <testsuites>
+ <testsuite name="Transport">
+ <file>lib/Elastica/Test/Transport/TransportBenchmarkTest.php</file>
+ </testsuite>
+ </testsuites>
+ <listeners>
+ <listener class="PHPUnit_Util_Log_XHProf" file="/home/munkie/Projects/phpunit-testlistener-xhprof/PHPUnit/Util/Log/XHProf.php">
+ <arguments>
+ <array>
+ <element key="xhprofLibFile">
+ <string>/var/www/xhprof/xhprof_lib/utils/xhprof_lib.php</string>
+ </element>
+ <element key="xhprofRunsFile">
+ <string>/var/www/xhprof/xhprof_lib/utils/xhprof_runs.php</string>
+ </element>
+ <element key="xhprofWeb">
+ <string>http://xhprof.local/</string>
+ </element>
+ <element key="appNamespace">
+ <string>Elastica</string>
+ </element>
+ <element key="xhprofFlags">
+ <string>XHPROF_FLAGS_CPU,XHPROF_FLAGS_MEMORY</string>
+ </element>
+ <element key="xhprofConfigFile">
+ <string>/var/www/xhprof/xhprof_lib/config.php</string>
+ </element>
+ <element key="xhprofIgnore">
+ <string>call_user_func,call_user_func_array</string>
+ </element>
+ </array>
+ </arguments>
+ </listener>
+ </listeners>
+</phpunit>
diff --git a/vendor/ruflin/elastica/test/phpunit.xml.dist b/vendor/ruflin/elastica/test/phpunit.xml.dist
new file mode 100644
index 00000000..51993e0a
--- /dev/null
+++ b/vendor/ruflin/elastica/test/phpunit.xml.dist
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<phpunit
+ backupGlobals="false"
+ backupStaticAttributes="false"
+ bootstrap="./bootstrap.php"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnError="false"
+ stopOnFailure="false"
+ stopOnIncomplete="false"
+ stopOnSkipped="false"
+ syntaxCheck="false"
+ verbose="true"
+ >
+ <filter>
+ <whitelist>
+ <directory suffix=".php">../lib/</directory>
+ </whitelist>
+ </filter>
+ <testsuites>
+ <testsuite name="default">
+ <directory>./lib/Elastica/</directory>
+ </testsuite>
+ </testsuites>
+</phpunit>