Compare commits

...

949 commits

Author SHA1 Message Date
Simon Vieille 30e351b1d5 Propel provider: query_builder_method set to null 2015-05-20 11:13:43 +02:00
Simon Vieille e3abbdc700 Propel provider: default options 2015-05-20 11:12:03 +02:00
Tim Nagel 4451bd07c6 Merge pull request #860 from kayue/patch-1
Count the number of results for the query directly
2015-04-28 12:56:12 +10:00
Tim Nagel 1f8a330140 Merge pull request #870 from davidfuhr/patch-1
Fixed parameter name to kernel.environment
2015-04-28 12:55:14 +10:00
David Fuhr 8f7f24e6d3 Fixed parameter nam to kernel.environment
The parameter %kernel.env% does not exist. It throws the error message 'You have requested a non-existent parameter "kernel.env". Did you mean this: "kernel.environment"?'
2015-04-27 23:00:50 +02:00
Ka Yue Yeung e71ec4ac8a Count the number of results for the query directly 2015-04-18 00:42:02 +08:00
Lukas Kahwe Smith adf7fb21e3 Merge pull request #848 from thierrymarianne/patch-1
Fix typo
2015-04-05 23:20:26 +02:00
Thierry Marianne 1287d9f0df Fix typo 2015-04-05 22:07:41 +02:00
Tim Nagel c5728b5870 Merge branch '3.1.x' 2015-04-02 10:39:05 +11:00
Tim Nagel 7baf494c56 release 3.1.3 2015-04-02 10:34:08 +11:00
Tim Nagel ad20382e08 Merge pull request #842 from merk/fix-provider-symfony-23
Fix symfony 2.3 compatibility with 3.1
2015-04-02 10:33:05 +11:00
Tim Nagel e933a49d07 Use deprecated optionsResolver interface 2015-04-02 10:23:30 +11:00
Tim Nagel 69470d7e20 Fix the previous release. 2015-03-27 12:01:39 +11:00
Tim Nagel b6e01cd332 Fix issues with Provider's batch_size and PopulateCommand's batch_size 2015-03-27 11:45:03 +11:00
Tim Nagel 35276f469a Merge pull request #835 from TomasVotruba/patch-2
Setup.md: fix link to Elasticsearch installation
2015-03-27 08:59:18 +11:00
Tim Nagel ec9f23bd8d Merge pull request #834 from TomasVotruba/patch-1
Setup.md - composer picks last stable version
2015-03-27 08:58:33 +11:00
Tomáš Votruba ae4cfd7e04 Setup.md: fix link to Elasticsearch installation 2015-03-26 15:05:28 +01:00
Tomáš Votruba 49a0c22724 Setup.md - composer picks last stable version 2015-03-26 15:03:20 +01:00
Tim Nagel 8d8b04ead8 Fixes populate command error 2015-03-23 21:39:13 +11:00
Tim Nagel a59f2015b4 Merge branch '3.1.x' 2015-03-18 09:40:06 +11:00
Tim Nagel 447d29ab9c Release 3.1.0 2015-03-18 09:38:47 +11:00
Tim Nagel 73093beadb Merge pull request #823 from merk/more-tests
More test coverage
2015-03-18 09:37:23 +11:00
Tim Nagel 5181b02933 Resetter tests 2015-03-14 22:14:24 +11:00
Tim Nagel ac98549eb5 Fix translation of option keys for the Provider 2015-03-14 19:54:23 +11:00
Tim Nagel 9c1c771799 Mark getSlice private 2015-03-14 19:54:01 +11:00
Tim Nagel 3bb2f384ba Provider refactoring 2015-03-14 19:53:05 +11:00
Tim Nagel d4f01e8d2e Cast result from ExpressionLanguage eval to bool 2015-03-14 18:48:59 +11:00
Tim Nagel 72a9dfa267 Indexable service improvements 2015-03-14 16:08:50 +11:00
Tim Nagel 9cf0117c71 AliasProcessor 2015-03-14 00:51:07 +11:00
Tim Nagel bb4618c101 Even more QA 2015-03-13 19:34:56 +11:00
Tim Nagel 6a07f7b24e More QA 2015-03-13 19:10:24 +11:00
Tim Nagel dd3269d1ef Merge branch 'code-qa' into 3.1.x 2015-03-13 15:17:52 +11:00
Tim Nagel 84e5831a81 Fixing scrutinizer issues 2015-03-13 14:57:36 +11:00
Tim Nagel d5a9b7b235 Add missing method to HighlightableModelInterface.
This is not a BC break - the method has always been required and lacking the method would cause a fatal error.
2015-03-13 14:56:07 +11:00
Tim Nagel 4af9f442fd Move common sorting code to base Transformer class 2015-03-13 14:56:07 +11:00
Christophe Coevoet 4081c32ca0 Merge branch '3.1.x' 2015-03-12 17:54:38 +01:00
Christophe Coevoet 925410a66e Merge branch '3.0.x' into 3.1.x 2015-03-12 17:54:30 +01:00
Christophe Coevoet b6c252aac3 Update the changelog for 3.0.9 2015-03-12 17:54:08 +01:00
Christophe Coevoet 133f71b88a Merge branch '3.1.x' 2015-03-12 17:49:49 +01:00
Christophe Coevoet c013ed9657 Merge branch '3.0.x' into 3.1.x
Conflicts:
	Resources/config/orm.xml
2015-03-12 17:49:25 +01:00
Christophe Coevoet f72c51503a Fix the service definitions when the logger is not set in listener
The empty tag is parsed to an empty string, not to null. And this is not
a valid value for the service
2015-03-12 17:44:57 +01:00
Tim Nagel 4e087af50d Fix issues with CS merge 2015-03-12 22:41:48 +11:00
Tim Nagel 559b14b4a5 Merge branch '3.1.x' 2015-03-12 22:02:06 +11:00
Tim Nagel 2215d07ff8 Merge pull request #818 from merk/cs-fixes-30
php-cs-fixer for 3.0.x
2015-03-12 21:58:21 +11:00
Tim Nagel 89db88c2a0 CS fixes for 3.1 2015-03-12 21:58:02 +11:00
Tim Nagel 345b5d423d Merge cs-fixes-30 into cs-fixes-31 2015-03-12 21:57:26 +11:00
Tim Nagel a8f41fa5ef We do not provide API guarantees 2015-03-12 21:47:19 +11:00
Tim Nagel e796d6179b Elastica, Doctrine\Common and Doctrine\ORM are required for tests 2015-03-12 21:21:18 +11:00
Tim Nagel dd388e4b25 CS fixes 2015-03-12 21:20:00 +11:00
Tim Nagel 81186e40db Bump master to 3.2-dev 2015-03-12 20:36:50 +11:00
Tim Nagel 14af748840 Fix bad merge 2015-03-12 18:22:04 +11:00
Tim Nagel 19e9abaa53 Update documentation links for 3.1 and 3.0 2015-03-11 22:21:56 +11:00
Tim Nagel 5b88baeca6 Merge branch 'pr/744'
Conflicts:
	CHANGELOG-3.1.md
	Command/PopulateCommand.php
2015-03-11 22:17:14 +11:00
Tim Nagel b7c7f77383 Merge branch 'pr/725'
Conflicts:
	CHANGELOG-3.1.md
	Doctrine/AbstractProvider.php
2015-03-11 22:10:54 +11:00
Tim Nagel 181b5a0ac0 Merge pull request #815 from merk/command-tidy
Command tidy
2015-03-11 22:09:00 +11:00
Tim Nagel 0009c858a7 Fixes for errors when with the progress closure 2015-03-11 21:31:23 +11:00
Tim Nagel f834499a2c Fixes after review 2015-03-11 15:54:04 +11:00
Tim Nagel 3d69c08b5a Merge branch 'master' into pr/725
Conflicts:
	Doctrine/AbstractProvider.php
2015-03-11 15:47:03 +11:00
Tim Nagel cbb247978a Update changeling for aggregations 2015-03-11 15:37:34 +11:00
Tim Nagel a830a9b7b6 Merge pull request #726 from cassianotartari/master
Add aggregations
2015-03-11 15:34:47 +11:00
Tim Nagel 7b90c84daa Merge pull request #728 from ugomeda/master
Add missing KnpPaginator example in the usage documentation
2015-03-11 15:33:03 +11:00
Tim Nagel 034b3a9c60 Merge branch '3.0.x' 2015-03-11 15:30:09 +11:00
Evgeniy Sokolov cf9f7c6be8 fix error for empty type configuration 2015-03-11 15:29:17 +11:00
Tim Nagel 4a564401b4 Symfony <=2.5 uses the legacy progress closure 2015-03-11 15:17:06 +11:00
Tim Nagel ef2671dd36 Moved the progress helper closure building to a dedicated class 2015-03-11 15:11:42 +11:00
Tim Nagel 47785260a4 Fix an error that PopulateCommand would always ignore errors 2015-03-11 15:11:13 +11:00
Tim Nagel cb7b4c1dca Configurable ProgressBar format definition overrides 2015-03-11 15:09:48 +11:00
Tim Nagel 4c87d24fc1 Changes after review 2015-03-11 14:55:13 +11:00
Tim Nagel f6df88cc67 Merge branch 'master' into pr/744
Conflicts:
	Command/PopulateCommand.php
2015-03-11 14:11:18 +11:00
Tim Nagel 7fa14f713c Merge branch '3.0.x' 2015-03-10 22:01:24 +11:00
Tim Nagel 55bfee22e8 Cache composer 2015-03-10 22:00:09 +11:00
Tim Nagel 07995d9b75 Merge pull request #794 from merk/property-paths
Added capability to define property paths
2015-03-10 21:58:32 +11:00
Tim Nagel 72a981ab51 Attempted fix for php 5.3 2015-03-10 21:49:26 +11:00
Tim Nagel 1be1cb645c Merge pull request #809 from chtipepere/patch-1
Update usage.md
2015-03-10 21:13:21 +11:00
Marichez Pierre 70fe702ccf Update usage.md
Fix indent in yml
2015-03-07 22:06:32 +01:00
WouterJ.nl bot 3c87cc16c7 Merge branch '3.0.x' 2015-02-18 11:38:02 +01:00
Tim Nagel c5185a0307 Added capability to define property paths 2015-02-09 09:40:49 +11:00
Tim Nagel e1d5ef72d2 Merge pull request #792 from FriendsOfSymfony/progress-bar-bc
Additional change for 2.5 ProgressBar support
2015-02-07 00:03:50 +11:00
Tim Nagel 797d066286 Additional change for 2.5 ProgressBar support
getProgress() is not available and getStep() throws a deprecation warning.
2015-02-06 23:50:39 +11:00
Tim Nagel 72589f8341 Fix ProgressBar for Symfony 2.5 2015-02-06 22:07:13 +11:00
Tim Nagel 2401b1083c Bump version 2015-01-31 18:33:07 +11:00
Tim Nagel 8e627ee011 Merge pull request #788 from FriendsOfSymfony/elastica-bump
Update Elastica dependency
2015-01-31 18:31:08 +11:00
Tim Nagel 6992beeb47 Update Elastica dependency 2015-01-31 18:24:47 +11:00
Tim Nagel 7bc88494a1 Merge branch '3.0.x' 2015-01-27 08:21:57 +11:00
Tim Nagel 30d52bf0f0 Merge pull request #782 from allanbrault/patch-1
Update PopulateCommand.php
2015-01-27 08:08:31 +11:00
Allan Brault 58eed2dc7f Update PopulateCommand.php
in the case i have 110 objects, it was doing :
Populating abc/Index 90.9% (100/110)
Populating abc/index 181.8% (200/110)

now :
Populating abc/Index 90.9% (100/110)
Populating abc/index 100.0% (110/110)
2015-01-26 16:59:55 +01:00
Tim Nagel d44525f6f3 Merge pull request #780 from merk/pr/770
Continued work on ProgressBar
2015-01-25 19:54:53 +11:00
Tim Nagel 67c0b79505 Tidy up ProgressBar use, move most calculations for loggerClosure
into PopulateCommand rather than in AbstractProvider
2015-01-25 19:53:58 +11:00
Pablo Martelletti 6bb2def21e Use ProgressBar in populate commande when available. 2015-01-25 19:53:06 +11:00
Tim Nagel e5d9c3ddbb Merge branch 'pr/732' into 3.0.x 2015-01-25 19:41:57 +11:00
Tim Nagel 906e2e0749 Ability to set connectionStrategy for elastica clients 2015-01-25 19:38:01 +11:00
Tim Nagel 81f5f983c0 Fix line break 2015-01-25 19:06:41 +11:00
Tim Nagel 030b194c7b Fix tests 2015-01-22 11:49:28 +11:00
Tim Nagel 7f28be3c4e Merge branch '3.0.x' 2015-01-22 11:26:07 +11:00
Tim Nagel 79e263d7a7 Merge pull request #779 from merk/index-name-doc
Clarified what index_name does. Closes #731
2015-01-22 11:25:47 +11:00
Tim Nagel e772ca6450 Fix php 5.3 compatibility 2015-01-22 11:23:51 +11:00
Tim Nagel 55abe132c6 Update changelog 2015-01-22 09:36:33 +11:00
Tim Nagel aef5940578 Merge branch 'pr/760' into 3.0.x 2015-01-22 09:34:10 +11:00
Tim Nagel b9b0c1b961 Move TypeConfig creation to its own method 2015-01-22 09:33:46 +11:00
Michaël Perrin 64fa26e3d9 Fix PHP notice when using indexes without defined types 2015-01-22 09:24:59 +11:00
Tim Nagel c4a2858265 Merge branch 'pr/772' into 3.0.x 2015-01-22 09:23:24 +11:00
CedCannes 7471c13d75 Update manual-provider.md
Typo in class path
2015-01-22 09:22:34 +11:00
Tim Nagel c901d60552 Clarified what index_name does. Closes #731 2015-01-22 09:15:38 +11:00
Tim Nagel 401446e1c4 Add integration testing around _parent mapping 2015-01-22 09:06:21 +11:00
Christophe Coevoet 1cea135dc5 Merge branch '3.0.x' 2015-01-21 18:11:18 +01:00
Christophe Coevoet 32d190f554 Bump the changelog for 3.0.7 2015-01-21 18:10:33 +01:00
Christophe Coevoet 5060fa4d4a Move the test file to a better location
The test of the DI extension is not a functional test.
2015-01-21 17:51:56 +01:00
Christophe Coevoet b4c01f3641 Merge branch 'formapro-forks/fixing-bug-with-parent' into 3.0.x 2015-01-21 17:43:36 +01:00
Tim Nagel 1bf59d5b66 Merge pull request #773 from merk/transformer-event
Dispatch an event when transforming objects
2015-01-21 13:29:23 +11:00
Tim Nagel 9188566dfe Dispatch an event when transforming objects 2015-01-20 14:41:11 +11:00
Tim Nagel d7e9d9b8a6 Merge pull request #718 from WouterJ/patch-1
Applied standard installation template
2015-01-12 10:48:42 +11:00
Wouter J a28b9d3069 Applied standard installation template 2015-01-11 17:48:13 +01:00
Tim Nagel c2c87a53e4 Merge branch '3.0.x' 2015-01-09 08:56:41 +11:00
Tim Nagel 2ce2d7e610 Add test for multi_field 2015-01-09 08:55:57 +11:00
Vladimir Kartaviy 905265ea0e "multi_field" type fields are not normalized
Fix for #764
2015-01-09 08:47:15 +11:00
Tim Nagel ee9f7e5297 Merge pull request #768 from vkartaviy/patch-1
Fix ODM listener service arguments
2015-01-09 08:44:44 +11:00
Vladimir Kartaviy a0f11ff36f Fix ODM listener service arguments
It became broken after d731443aa5 commit
2015-01-07 16:45:18 +02:00
Oleg Andreyev 7c90660e02 attempt to make scrutinizer happy, about duplicate code in test 2015-01-04 20:57:08 +02:00
Oleg Andreyev 7efcdad97c adding ResetEvent (pre/post index and pre/post type reset), injected EventDispatcher into Resetter 2015-01-04 14:51:21 +02:00
Oleg Andreyev afbe1e03a1 adding unit test for PopulateListener 2015-01-04 14:51:21 +02:00
Oleg Andreyev 303af508b2 adding populate events 2015-01-04 14:17:25 +02:00
Tim Nagel c39b86c6c5 Merge branch 'detection-config' 2015-01-04 22:12:21 +11:00
Tim Nagel b6d46dba4a Merge tag 'v3.0.6' 2015-01-04 22:10:18 +11:00
Tim Nagel 9f5ce217dc Release 3.0.6 2015-01-04 22:08:20 +11:00
Tim Nagel 6ef6092f3f Update 3.0 changeling 2015-01-04 22:03:19 +11:00
Tim Nagel 92aab4bcf6 Add PR# to changelog 2015-01-04 22:02:54 +11:00
Tim Nagel e361b7c53b Implement additional configuration options for types. 2015-01-04 21:58:53 +11:00
Tim Nagel 7fac93ff8b Fix mongodb doctrine listener 2015-01-04 20:16:32 +11:00
Dmitry Korotovsky d731443aa5 Avoid Doctrine\Listener::getSubscribedEvents() call on each page where doctrine is active 2015-01-04 20:05:47 +11:00
Evan Owens 156884527c Update example
FOS\ElasticaBundle\Client has been deprecated.
2015-01-04 20:01:04 +11:00
DjangoFR 5eaff9e61b removed unused image (being base64 encoded - see #742) 2015-01-04 19:49:30 +11:00
Danijel Brkic 3975ed3d5b Built-in templates use a base64 encoded image for the toolbar 2015-01-04 19:49:25 +11:00
Tim Nagel d33e064801 Merge commit '1f7acc5' into 3.0.x 2014-12-24 09:10:41 +11:00
Tim Nagel 1f7acc563a Ignore strings starting with @ 2014-12-24 09:09:45 +11:00
Christophe Coevoet eaa32cbf22 Fix the BC layer for indexable callbacks
Using services was not based on a @ prefix in the string in the old API
but based on the existence of the class.
2014-12-23 15:21:25 +01:00
Christophe Coevoet f3e31e613e Merge branch '3.0.x'
Conflicts:
	.travis.yml

Duplicate testing on Symfony 2.6 is removed (it is already done by the
normal testing as it is the latest stable), and testing on 2.4 is
removed again because it is EOLed.
2014-12-17 14:25:15 +01:00
Christophe Coevoet 97848ca0d0 Removed the testing on Symfony dev-master
dev-master is Symfony 3.0, and we are not yet marking it as compatible
2014-12-17 14:23:00 +01:00
Tim Nagel 88e9f5aac6 Merge pull request #748 from NinjDS/totalhits
Genuine ES behaviour for getTotalHits()
2014-12-01 22:04:25 +11:00
Tim Nagel ca57c42489 Merge pull request #738 from FriendsOfSymfony/adjust-build-matrix
adjust to symfony 3.0 development having started
2014-12-01 22:02:10 +11:00
David Buchmann 2664fec35e adjust to symfony 3.0 development having started. whenever there is a new 2.x branch in symfony, we should add it to the matrix 2014-12-01 09:21:43 +01:00
Nikolai Zujev c45dcd955d Clean filtered objects if the entire batch was filtered away, to prevent memory allocation issue. 2014-12-01 09:47:32 +11:00
Tim Nagel 7dc2f833c4 Merge branch '3.0.x' 2014-12-01 09:46:49 +11:00
Tim Nagel e211f31658 Merge pull request #743 from KingCrunch/patch-1
Update custom-repositories.md to use code highlighting
2014-12-01 09:36:45 +11:00
Tim Nagel 00df6c586f Merge pull request #737 from jaymecd/clean_filtered
Doctrine provider: memory allocation caused by "entire batch was filtered away"
2014-12-01 09:34:21 +11:00
Tim Nagel 921377d5ed Merge pull request #750 from javiereguiluz/update_installation_instructions
Updated installation instructions
2014-12-01 08:52:01 +11:00
Javier Eguiluz c4ee9fa83e Updated installation instructions 2014-11-29 17:17:31 +01:00
Adrien Morel b09bf3cf10 RawPaginatorAdapter::getTotalHits() can retrieve the genuine total hits returned by elasticsearch 2014-11-26 16:25:23 +01:00
Sebastian Krebs 1e2da2d84f Update custom-repositories.md to use code highlighting
Looks better this way
2014-11-21 14:21:26 +01:00
David Buchmann 2d8903a330 Merge pull request #736 from piotrantosik/patch-2
Fix changelog header
2014-11-14 15:59:43 +01:00
Nikolai Zujev e6d50c584c Clean filtered objects if the entire batch was filtered away, to prevent memory allocation issue. 2014-11-13 17:34:21 +02:00
Piotr Antosik 2a7459f327 Fix changelog header 2014-11-10 14:05:56 +01:00
Gnucki c80b4efd3e Merge branch master 2014-11-02 14:28:44 +01:00
Gnucki 1369a01dd7 Add slice fetching abstraction 2014-11-02 14:24:28 +01:00
Gnucki 901ea49a32 Factorize manager call 2014-11-02 14:22:26 +01:00
Ugo Méda 1b01aef46f Add missing KnpPaginator example in the usage documentation 2014-10-16 15:46:40 +02:00
Gnucki be75b387a5 Add slice fetching abstraction 2014-10-13 15:41:29 +02:00
Gnucki 445f2f93f6 Add slice fetching abstraction 2014-10-13 15:40:31 +02:00
Cassiano e7634d8ba2 Update RawPaginatorAdapter.php 2014-10-08 17:15:57 -03:00
Cassiano Tartari 419bf2ccf6 Merge remote-tracking branch 'upstream/master'
Conflicts:
	Paginator/RawPaginatorAdapter.php
2014-10-08 17:08:13 -03:00
Cassiano 6f4e389dfd Update RawPaginatorAdapter.php 2014-10-08 15:19:48 -03:00
Cassiano 196aed6630 Update PaginateElasticaQuerySubscriber.php 2014-10-08 14:33:15 -03:00
Cassiano 7c6fe4eaab Update FantaPaginatorAdapter.php 2014-10-08 14:32:24 -03:00
Cassiano d2de7ba6e8 Update PaginatorAdapterInterface.php 2014-10-08 14:31:39 -03:00
Cassiano 197bb3ebad Update PartialResultsInterface.php 2014-10-08 14:31:19 -03:00
Cassiano f9ce1dcd4e Update RawPaginatorAdapter.php 2014-10-08 14:30:03 -03:00
Cassiano 4c4e9ffe36 Update RawPartialResults.php 2014-10-08 14:27:50 -03:00
Gnucki 7fa7e44bee Fix mongodb populate falling down performances for big collections 2014-10-08 10:44:49 +02:00
Tim Nagel 67ae044309 #724 Fix debug_logging option on the provider 2014-10-08 08:59:45 +11:00
Tim Nagel 25d56d0a0f 3.1.x requires doctrine 2.4+ 2014-10-03 08:21:02 +10:00
Tim Nagel a88e4e38f8 Merge branch 'cs-fixes-31' 2014-09-21 21:09:39 +10:00
Tim Nagel 5cdeac9b45 Merge branch '3.0.x' 2014-09-21 21:09:33 +10:00
Michael Schramm b3f87e414f move classes to parametes 2014-09-21 21:08:41 +10:00
Tim Nagel 71a86cada5 BC BREAK: Add handlesObject method to ObjectPersisterInterface 2014-09-21 20:25:32 +10:00
Tim Nagel d0ce82ac2a Adjust DoctrineListener to remove unnecessary method getDoctrineObject 2014-09-21 20:25:25 +10:00
Tim Nagel 428a1014ca Move query logging into its own method 2014-09-21 20:12:30 +10:00
Tim Nagel 1d5fe44ca4 Fix CS from scrutiniser-ci 2014-09-21 20:12:30 +10:00
Tim Nagel cf586a4ef4 Merge branch '3.0.x' 2014-09-04 09:39:54 +10:00
Tim Nagel c4210a5c6d Fix previous merge 2014-09-04 09:37:27 +10:00
Tim Nagel 029ebb153a Merge remote-tracking branch 'upstream/pr/705' into 3.0.x
Conflicts:
	Index/AliasProcessor.php
2014-09-04 09:26:53 +10:00
Tim Nagel 736163551c Merge remote-tracking branch 'upstream/pr/704' into 3.0.x 2014-09-04 09:17:34 +10:00
Patrick McAndrew 76dcd2f62e fix warning if no aliases
PHP Warning:  array_keys() expects parameter 1 to be array, AliasProcessor.php on line 128
2014-08-29 15:52:46 +01:00
Patrick McAndrew 2958833012 Ability to delete an index if expecting an alias 2014-08-28 17:59:58 +01:00
Tim Nagel 6bea3c2154 Add code quality badge 2014-08-21 23:23:20 +10:00
Tim Nagel 001daeeac0 Merge branch '3.0.x' 2014-08-21 23:17:42 +10:00
Tim Nagel a7a23b92cb Merge pull request #698 from merk/new-testing
Update testing
2014-08-21 23:15:38 +10:00
Tim Nagel 598a59927e Update travis testing 2014-08-21 22:54:12 +10:00
Patrick McAndrew 0425379420 add back fos_elastica.client tag that was removed in e78950ddb7 2014-08-21 22:18:53 +10:00
Tim Nagel 380727afbe Merge pull request #695 from notFloran/fix-search-annotation
Use the new Search annotation
2014-08-21 21:54:23 +10:00
Floran Brutel 69c2214bc5 Use the new Search annotation
Use "FOS\ElasticaBundle\Annotation\Search" instead of "FOS\ElasticaBundle\Configuration\Search" in the repository manager.
Update the cookbook
2014-08-18 13:30:45 +02:00
Tim Nagel af5fb7e97e Merge pull request #694 from notFloran/update-version-setup
Update version in setup.md
2014-08-17 21:13:11 +10:00
Floran Brutel 22a2a223cc Update version in setup.md
Use "~3.0" instead of "~3.0.2" to get version 3.0.3 and future minor
versions
2014-08-17 12:16:15 +02:00
Tim Nagel c08d86124a Merge branch '3.0.x' 2014-08-11 08:44:22 +10:00
Luis Cordova 33ee047f83 fix dependency on elastic extension
i had a weird error in which just installing the bundle with "friendsofsymfony/elastica-bundle":     "~3.0.2",
game me a version back even before it had a composer! 😊
i checked and found out composer gets really confused or glitchy with packages not following semver.
In any case 1.3.0 is out, and i remove the 4th digit which i think composer ignores totally or gets confused about.
2014-08-11 08:44:15 +10:00
Tim Nagel 49c5b2ee63 Merge branch 'pr/685' 2014-08-08 21:37:20 +10:00
Oleg Andreyev 27385046ca changing AliasProcessor::setRootName, so to use "Y-m-d-His" instead of random string 2014-08-08 21:36:49 +10:00
Tim Nagel 517d6e679c Merge branch '3.0.x' 2014-08-08 21:31:14 +10:00
Tim Nagel 420135dc85 Merge branch 'travis-fixing' into 3.0.x 2014-08-08 10:00:55 +10:00
Tim Nagel 20033709cf Fix empty mappings for old ES versions 2014-08-08 09:59:24 +10:00
Tim Nagel 229d4cb982 Merge branch '3.0.x' 2014-08-08 08:36:36 +10:00
Tim Nagel 84cf6c79c2 Merge remote-tracking branch 'upstream/pr/684' into 3.0.x 2014-08-08 08:33:59 +10:00
Tim Nagel 9d45de8b64 Merge pull request #684 from cygnusb2b/deep-merging-config
Configuration Bug: Restored noDeepMerging
2014-08-08 08:33:09 +10:00
Josh Worden f5987a48b9 BC Break: Restored noDeepMerging to Configuration
When performNoDeepMerging is not used, Symfony environment-specific server configurations no longer work.
2014-08-07 16:33:14 -05:00
Tim Nagel dafe8abe0e Output ES version 2014-08-07 09:32:30 +10:00
Tim Nagel 0d22c20d37 Merge remote-tracking branch 'upstream/pr/682' into 3.0.x 2014-08-07 09:26:11 +10:00
Tim Nagel f9eb6577d1 Add tests to cover no mappings for serializer enabled type 2014-08-07 09:25:49 +10:00
Tim Nagel c44f676224 Test mappings key being null still causes appropriate configuration changes 2014-08-07 09:25:09 +10:00
Luis Cordova 9296534d30 Update setup.md 2014-08-06 17:25:05 -05:00
Tim Nagel f6e018f011 Merge remote-tracking branch 'upstream/pr/679' into 3.0.x 2014-08-04 08:53:14 +10:00
Lukasz Cybula 9a5b80e723 Ignore missing Doctrine results during hybridTransform() 2014-07-31 14:13:01 +02:00
Tim Nagel eaa6c2e085 Merge branch '3.0.x' 2014-07-31 15:55:37 +10:00
Tim Nagel 64c5c19831 Merge branch 'pr/675' into 3.0.x
Closes #675
2014-07-31 15:54:53 +10:00
Pablo 9befa90f41 Return repository in Manager Class MongoDB 2014-07-31 15:54:22 +10:00
esodin 659468ae3a Issue: Parent is missing in the fields list that causes RoutingMissingException on flushing - test 2014-07-24 17:36:45 +03:00
esodin 001b38cf59 Issue: Parent is missing in the fields list that causes RoutingMissingException on flushing - test 2014-07-24 17:07:22 +03:00
esodin 1ef55b1239 Issue: Parent is missing in the fields list that causes RoutingMissingException on flushing - test 2014-07-24 17:03:26 +03:00
Tim Nagel c748ec64e9 Merge pull request #672 from merk/gh663
Fix indexable callbacks being overwritten by another index
2014-07-23 23:10:24 +10:00
Tobias Nyholm 11ee25cfea Added PHP 5.6 2014-07-23 21:47:10 +10:00
Tim Nagel e5410a5b65 Fix indexable callbacks being overwritten by another index
closes #663
2014-07-23 21:38:46 +10:00
Tim Nagel 9fbc622929 Merge pull request #671 from merk/completion-type-fix
Fix completion type
2014-07-23 20:06:33 +10:00
Tim Nagel fad481d822 Fix completion type 2014-07-23 20:00:14 +10:00
esodin 714502fa1f Issue: Parent is missing in the fields list that causes RoutingMissingException on flushing 2014-07-17 16:01:10 +03:00
Tim Nagel 7cedc5ba5a Merge pull request #653 from notFloran/fix-doc
Fix "Faceted Searching" doc
2014-07-08 09:35:40 +10:00
Floran Brutel d797af5b80 Fix "Faceted Searching" doc 2014-07-07 18:35:23 +02:00
Tim Nagel cdaf7105e0 Bump dev version to 3.1 2014-07-05 15:14:29 +10:00
Tim Nagel d88d96bf55 Fix invalid service reference in production 2014-07-04 22:10:24 +10:00
Tim Nagel bf38e59e49 Documentation on aliased repopulation 2014-07-04 13:07:35 +10:00
Tim Nagel 90a554f627 Merge branch 'pr/622' 2014-07-04 12:49:13 +10:00
tamirvs d57d430ab3 Ignore iterator keys when converting to array 2014-07-04 12:48:27 +10:00
Tim Nagel be4af0d1af Merge pull request #644 from merk/elastica-connections
Rename servers to connections
2014-07-04 11:28:44 +10:00
Tim Nagel 425aa3d3e1 Merge pull request #645 from merk/stopwatch
Add stopwatch support for Elastica\Client
2014-07-04 11:25:37 +10:00
Tim Nagel 21e5d906a7 Simplify *One methods in the persister 2014-07-03 23:37:44 +10:00
Tim Nagel 815b836cdc Add stopwatch support for Elastica\Client 2014-07-03 23:20:18 +10:00
Tim Nagel 55dcf6859a Rename servers to connections 2014-07-03 21:58:54 +10:00
Tim Nagel c200e8fdfd Add tests for attachment type 2014-07-03 20:21:01 +10:00
Maksim Kotlyar 965b319d82 [transformers] tell container that first argument is collection. 2014-07-01 14:40:03 +03:00
Tim Nagel 7fcbb64a15 Fix edge case for dynamic templates 2014-07-01 18:02:30 +10:00
Tim Nagel 5d65676659 Add tests and normalisation to support old dynamic_templates format 2014-07-01 17:59:22 +10:00
Tobias Schultze c9a24436f3 dynamic templates are a list of hashes and have a mapping key (not properties) 2014-06-30 16:19:10 +02:00
Tim Nagel 9f85db9876 Merge pull request #639 from RonXS/master
[FEATURE] Use static instantiation with max depth check
2014-06-30 08:41:50 +10:00
Ron van der Molen 78db0b9b63 [FEATURE] Use static instantiation with max depth check 2014-06-29 22:14:32 +02:00
Tim Nagel ad37a28356 Fix populating command setting alias before population 2014-06-27 15:08:56 +10:00
Tim Nagel 474cbfa979 Added test coverage for ES store 2014-06-26 19:51:16 +10:00
Tim Nagel 77f2b99a3e Fix Indexable tests 2014-06-26 18:01:34 +10:00
Tim Nagel 5cc8c2978f Merge pull request #635 from merk/fix-array-callable
Fix array format for indexable_callback
2014-06-26 17:47:14 +10:00
Tim Nagel 96dc613c71 Fix array format for indexable_callback 2014-06-26 17:46:29 +10:00
Tim Nagel 4eacb5f4c8 Merge pull request #634 from merk/more-mapping-tests
Fix ClassCastException when no settings are present
2014-06-26 17:32:01 +10:00
Tim Nagel a879d3c1c9 Fix ClassCastException when no settings are present 2014-06-26 17:31:20 +10:00
Tim Nagel ffa73db1d2 Merge pull request #621 from gcds/patch-1
Added elapsed item to toolbar and menu
2014-06-25 13:27:53 +10:00
Tim Nagel 4d52c327aa Add back missing KnpPaginatorSubscriber service 2014-06-25 13:24:02 +10:00
Tim Nagel 524474fdc6 Merge branch 'propel-test' 2014-06-25 13:18:15 +10:00
Tim Nagel ae03b3f3cf Fix propel service definition 2014-06-25 13:18:02 +10:00
Tim Nagel f6264f4149 Fix AbstractProvider tests 2014-06-24 10:30:31 +10:00
Tim Nagel 2437a098ba Fix anonymous service error 2014-06-24 10:20:15 +10:00
Tim Nagel ae3605828e Fix AbstractProvider test 2014-06-24 10:19:26 +10:00
Tim Nagel 2a20bb623c Merge branch 'typed-config'
Conflicts:
	composer.json
2014-06-24 09:09:29 +10:00
Tim Nagel 9a62187329 Fix undefined index_name notice 2014-06-23 23:50:52 +10:00
Tim Nagel ca6991d494 Fix serializer 2014-06-23 23:05:57 +10:00
Tim Nagel 95e445bd0d Merge pull request #623 from merk/provider-fix
Fix provider bailing if the indexable service filters an entire batch of objects
2014-06-19 12:18:57 +10:00
Tim Nagel c97f0f1ddf Fix provider bailing if the indexable service filters an entire batch of objects 2014-06-19 11:14:13 +10:00
Tim Nagel 4e990e0cee Fixed mapping issues 2014-06-19 00:14:41 +10:00
Aurimas Niekis b0749afaf1 Added elapsed item to toolbar and menu
Kind similar to doctrine toolbar item
2014-06-18 16:12:16 +03:00
Tim Nagel 3ae382c933 Add tests to make sure KnpPaginator plays nice 2014-06-18 20:02:05 +10:00
Tim Nagel 949ea6963f Revert "Make the class of fos_elastica.paginator.subscriber service configurable"
This reverts commit fe19df365a.
2014-06-18 19:55:33 +10:00
Tim Nagel b155f304e4 Move IndexManager's resolution to tagged index services 2014-06-18 16:49:57 +10:00
Tim Nagel afbaf875b9 Cache creation of indexes and types in Elastica to avoid recreation 2014-06-18 16:48:00 +10:00
Tim Nagel 8905b4248c Rename Manager to ConfigManager 2014-06-18 16:47:01 +10:00
Tim Nagel 5cbb8ce1b6 Merge pull request #591 from OskarStark/patch-1
use $this->container instead of $container in usage.md
2014-06-18 09:55:16 +10:00
Tim Nagel b3c0d4fd44 Merge pull request #600 from gido/patch-1
Make the class of `fos_elastica.paginator.subscriber` service configurable
2014-06-18 09:54:13 +10:00
Tim Nagel ec5c05e8be dev 2014-06-17 23:22:58 +10:00
Tim Nagel e78950ddb7 Merge branch 'master' into typed-config
Conflicts:
	CHANGELOG-3.0.md
	Client.php
	DependencyInjection/Configuration.php
	DependencyInjection/FOSElasticaExtension.php
	DynamicIndex.php
	Resources/config/config.xml
	Resources/config/mongodb.xml
	Resources/config/orm.xml
	Tests/DependencyInjection/ConfigurationTest.php
	composer.json
2014-06-17 22:42:15 +10:00
Tim Nagel 5f335c37ab Merge pull request #613 from merk/composer-update
Update composer.json
2014-06-17 22:38:56 +10:00
Tim Nagel 1e07d3c7fe Update composer.json 2014-06-17 22:19:19 +10:00
Tim Nagel 089e7f0d2e Add unstable badge
[skip ci]
2014-06-17 12:12:54 +10:00
Tim Nagel aafb8c8e89 Fix indexable callbacks with alias based indexes 2014-06-17 12:03:38 +10:00
Tim Nagel e225d841ed Wrong service. Whoops. 2014-06-17 10:54:09 +10:00
Tim Nagel b49437529c Fix incorrect provider configuration 2014-06-17 10:41:11 +10:00
Tim Nagel 94568d9554 Merge pull request #608 from merk/populate-indexable
Indexable callback refactoring, implemented callback in Provider
2014-06-17 10:11:46 +10:00
Tim Nagel 2e23f4a1bf Added documentation changes for indexable_callback 2014-06-17 10:07:10 +10:00
Tim Nagel 02d864f7e2 Merge pull request #593 from merk/gh-592
Fix nested property configuration
2014-06-17 09:48:22 +10:00
Tim Nagel 12797c60fa Merge pull request #609 from PeerJ/FixLoggerWithNullTransport
make sure headers is set prior to accessing
2014-06-17 09:44:43 +10:00
Patrick McAndrew 934c6af8b8 make PSR2 compliant 2014-06-16 14:30:03 +01:00
Tim Nagel 0383811834 Fix test, add test for failing mappings 2014-06-16 23:28:53 +10:00
Tim Nagel ada3942576 Config Source providers 2014-06-16 23:23:49 +10:00
Tim Nagel 813a4a5d26 Fix previous commits 2014-06-16 22:43:16 +10:00
Tim Nagel 7682d5a80a Update composer.json 2014-06-16 22:33:31 +10:00
Tim Nagel 64be10447d Move Search annotation 2014-06-16 22:33:04 +10:00
Patrick McAndrew 629ca0df2e make sure headers is set prior to accessing 2014-06-16 12:59:09 +01:00
Tim Nagel 391e18dcbf Update changelog 2014-06-16 16:20:17 +10:00
Tim Nagel e54cc3c243 Implement callback checking in the provider 2014-06-16 16:17:04 +10:00
Tim Nagel 66d2410999 Move Indexable callback calculations to a new service 2014-06-16 15:57:42 +10:00
Tim Nagel f5932a8e47 Merge remote-tracking branch 'origin/refactor' into typed-config
Conflicts:
	Resetter.php
2014-06-14 11:11:31 +10:00
Gilles Doge fe19df365a Make the class of fos_elastica.paginator.subscriber service configurable 2014-06-10 18:20:02 +02:00
Tim Nagel 14083496d7 Merge pull request #598 from merk/mapping-tests
Adds initial functional tests
2014-06-08 22:45:40 +10:00
Tim Nagel 5009673b6a Functional Tests v1 2014-06-08 22:35:38 +10:00
Tim Nagel 833feee207 Merge branch 'transport-option' of https://github.com/milan/FOSElasticaBundle into transport-option
Conflicts:
	DependencyInjection/Configuration.php
2014-06-08 18:00:17 +10:00
Tim Nagel f6b9e57a9c Merge pull request #595 from PeerJ/FixResetterException
fix method call
2014-06-08 17:56:15 +10:00
Patrick McAndrew 366fb39606 fix method call 2014-06-04 17:26:25 +01:00
Tim Nagel 8540f13bbf Fix nested property configuration
Fixes #592
2014-06-02 21:35:51 +10:00
Tim Nagel fa65784b47 Merge pull request #583 from merk/rename-mappings
Rename mappings to properties maintaining BC
2014-06-02 00:41:54 +10:00
Tim Nagel 1dc6856ef9 Configuration rework 2014-06-02 00:40:03 +10:00
Oskar Stark 6a822504bc use $this->container instead of $container 2014-06-01 15:57:29 +02:00
Tim Nagel c52c32fb56 Merge pull request #590 from Tornaldo/patch-1
Update usage.md
2014-06-01 16:38:37 +10:00
Tornaldo 2e0aa064a2 Update usage.md 2014-06-01 01:27:20 +02:00
Tim Nagel 12b724dd20 Merge pull request #585 from leberknecht/patch-2
fixing missing flush event handler
2014-05-26 10:17:11 +10:00
Delf Tonder 8060d3dcd7 fixing missing flush event handler
In [commit](843c76b6ca (diff-850942b3ba24ab03a40aaa81b6152852)) the configuration-definition for the flush listener was accidentally removed. 
As the flush listener is no longer set to be enabled in the extensions getDoctrineEvents method, the flush listener is not set. 
This results in a situation were we are only able to have the modified objects on the list for index-update, but never actually sending the update to the ES host.
2014-05-25 18:51:14 +02:00
Tim Nagel dad15d0b38 Deprecate top level classes 2014-05-25 20:51:46 +10:00
Tim Nagel 53180e2810 Bring tidy in line with property renaming 2014-05-25 20:14:51 +10:00
Tim Nagel 8e88505a3f Merge branch 'rename-mappings' into configuration-tidy 2014-05-25 20:13:21 +10:00
Tim Nagel a79fa0242e Simplified Configuration.php 2014-05-25 20:08:01 +10:00
Tim Nagel c38dc107e7 Rename mappings to properties maintaining BC
Fixes #407
2014-05-25 17:56:57 +10:00
Tim Nagel be89ccf825 Merge pull request #582 from tobiassjosten/urllessconfig
Don't default url
2014-05-25 14:56:42 +10:00
Tobias Sjösten f97e66712a Don't default url 2014-05-25 00:31:40 +01:00
Tim Nagel 5a84d55129 Merge pull request #580 from leberknecht/patch-1
update setup.md - immediate is an listener option
2014-05-24 23:10:44 +10:00
Delf Tonder f9745c8d21 update setup.md - immediate is an listener option
fixed yml config example (having immediate as an persistence option will result in parsing error)
2014-05-24 12:49:12 +02:00
Tim Nagel a9ea78443f Support Elastica proxy option 2014-05-24 00:17:59 +10:00
Tim Nagel 458b53240b Merge branch 'configuration-fixes' 2014-05-23 23:21:29 +10:00
Tim Nagel e77aa0c180 Test on php 5.5 2014-05-23 23:20:52 +10:00
Tim Nagel f20392d78b Fix test failures for DoctrineProvider 2014-05-23 23:19:55 +10:00
Tim Nagel f8a445b46c Fix disabling of logger in DoctrineProvider 2014-05-23 23:11:45 +10:00
Tim Nagel d532e6b1e3 Merge pull request #579 from merk/client-overwrite
Surpress server errors cookbook update
2014-05-23 23:01:16 +10:00
Tim Nagel 3addfffc91 Added logging of server errors to example 2014-05-23 23:00:34 +10:00
Tim Nagel 18143449cc Merge branch 'patch-2' of https://github.com/stloyd/FOSElasticaBundle into client-overwrite 2014-05-23 22:52:58 +10:00
Tim Nagel b09c7fb50e Merge branch 'master' of https://github.com/edast/FOSElasticaBundle 2014-05-23 22:51:11 +10:00
Tim Nagel 352e3b68ac Add configuration tests 2014-05-23 22:49:03 +10:00
Tim Nagel 41c4d77b20 Move serializer node to its own method, add serializer to type_prototype 2014-05-23 22:49:03 +10:00
Tim Nagel 843c76b6ca Move persistence node to its own method 2014-05-23 22:49:02 +10:00
Tim Nagel 6d2b7a8367 Combine client normalisation into a single method 2014-05-23 22:48:19 +10:00
Tim Nagel 57fbc70015 Merge pull request #522 from merk/doctrine-provider-speedup
Doctrine provider speedup
2014-05-23 22:46:36 +10:00
Tim Nagel 2029aba76a Ability for FOSElasticaBundle to disable persistence backend logging for population
Update documentation and changelog
2014-05-23 22:46:14 +10:00
Tim Nagel 6253d3f8df Merge pull request #553 from benniekrijger/issue-552-geoshape-mapping
Added GeoShape mapping options
2014-05-23 22:03:58 +10:00
Darius Staisiunas 28d0ee925d added support for geohash 2014-05-23 12:55:33 +03:00
Milan Magudia 2c208a4f10 Allow other transport options to be used i.e. Http, Https, Guzzle etc... 2014-05-22 16:18:08 +01:00
Tim Nagel 70ad5c9b37 Merge pull request #576 from milan/#534-cluster-logger-default
Fix for Issue #543 Client has a dependency on a non-existent service "%kernel.debug%"
2014-05-21 20:58:04 +10:00
Milan Magudia e1bbb87cfe Fix for Issue #543 Client has a dependency on a non-existent service "%kernel.debug%" 2014-05-21 10:24:44 +01:00
Tim Nagel 6748c9c623 Merge pull request #571 from tPl0ch/feature-flush-event
Make it possible to disable flush event through configuration
2014-05-20 08:50:50 +10:00
Tim Nagel 72e7b77dae Merge pull request #562 from evillemez/config
stop config from adding empty arrays into type mappings
2014-05-20 08:49:26 +10:00
Tim Nagel 1c5339ac40 Merge pull request #560 from cassianotartari/master
Update Configuration.php
2014-05-20 08:48:51 +10:00
Thomas Ploch e5754ef5fc Make it possible to disable flush event through configuration 2014-05-13 13:13:06 +02:00
Tim Nagel 6bbe61f319 Merge pull request #567 from caponica/ToModelTransformer_andWhere
Changed QueryBuilder method from ->where() to ->andWhere() ...
2014-05-08 09:43:16 +10:00
caponica b0841c18ec Changed QueryBuilder method from ->where() to ->andWhere() so it works with customised QueryBuilders which have an existing where clause (instead of over-writing any existing DQL 'where' part) 2014-05-08 00:26:30 +01:00
Tim Nagel 62f6cf0f8a Merge pull request #565 from FriendsOfSymfony/elasticsearch-1.1
Elasticsearch 1.*
2014-05-06 16:39:45 +10:00
Lea Haensenberger 5da8ee1a16 still supporting 0.9 versions of elastica 2014-05-06 08:18:37 +02:00
Lea Haensenberger b1d64e358d Also cleanup fields in properties of objects 2014-05-05 13:39:36 +02:00
Lea Haensenberger eaa9f83997 remove empty fields arrays from mapping, this is not ignored anymore by elasticsearch 1.* 2014-05-05 13:39:36 +02:00
Lea Haensenberger ae02364e7c use elastica library 1.1 and higher 2014-05-05 13:39:36 +02:00
Tim Nagel ca50617776 Merge pull request #563 from PeerJ/UpdateElasticaDependency
Update Elastica Dependency
2014-05-03 11:28:52 +10:00
Patrick McAndrew d9f3fa1a59 commit 1dcaadbe6f
Persister/ObjectPersister.php
line 112: $this->type->updateDocuments($documents);
introduces a dependency on Elastica 0.9.10.0
2014-05-02 15:07:15 +01:00
Evan Villemez c93bbb9081 stop config from adding empty arrays into type mappings 2014-05-01 11:05:16 -04:00
Cassiano 39f1033a34 Update Configuration.php
Adding the option to set index_analyzer and search_analyzer to _all field.
2014-04-24 09:39:22 -03:00
Tim Nagel 90abc44968 Merge pull request #556 from ahmedmhmd/master
Revert declaring PaginateElasticaQuerySubscriber as a parameter, so not to break Knp compiler pass
2014-04-20 16:01:38 +10:00
Ahmed Mohamed c9fd1cc5d9 Revert declaring PaginateElasticaQuerySubscriber as a paremeter, so not to break Knp compiler pass 2014-04-20 06:11:20 +02:00
Tim Nagel 1748e9af18 Merge pull request #549 from ahmedmhmd/master
Ensure non-empty properties under fields mappings in case of auto-mapped objects exists along with manual ones
2014-04-20 11:52:03 +10:00
Ahmed Mohamed 806452813a Add test multiple objects mapping of at least one auto-mapped and at least one manually mapped 2014-04-20 03:41:41 +02:00
Tim Nagel 35700cdd78 Merge pull request #551 from piotrantosik/patch-1
Fix immediate doc
2014-04-20 10:20:47 +10:00
Tim Nagel dd7b8d3210 Merge pull request #555 from RuslanZavacky/master
More classes exposed as parameters in config.xml
2014-04-20 10:20:32 +10:00
Ruslan Zavacky 0dcb77d749 More classes exposed as parameters. 2014-04-19 18:31:56 +03:00
ben 2bd6aba7ef Added GeoShape mapping options 2014-04-18 13:57:08 +02:00
Piotr Antosik d33f2e547f Fix immediate doc 2014-04-17 10:14:53 +02:00
Tim Nagel b11d48fe89 Merge pull request #546 from bobvandevijver/master
Fixes multiple updates on multiple flush executions
2014-04-17 07:27:37 +10:00
Tim Nagel 8387667167 Merge pull request #534 from dylanschoenmakers/patch-1
Added example to usage.md
2014-04-16 18:28:11 +10:00
Ahmed Mohamed 4e638a0492 Ensure non-empty properties under fields mappings 2014-04-16 05:27:23 +02:00
Tim Nagel 165696a5a0 Bump Elastica requirement 2014-04-15 08:43:11 +10:00
Bob van de Vijver 449c33aea3 Fixes multiple updates on multiple flush executions 2014-04-12 13:30:52 +02:00
Tim Nagel f93a7d278f Merge pull request #532 from solocommand/master
Added support for getting documents in unified Doctrine Listener
2014-04-11 08:54:03 +10:00
Joshua Worden 4cfe24ae02 Update CS 2014-04-10 07:38:01 -05:00
Dylan Schoenmakers 088452cf88 Added example to usage.md
Added example for using a custom query builder method to usage.md.
2014-04-10 09:25:40 +02:00
Tim Nagel 1bc085141b Fix logger option for listeners 2014-04-10 13:14:03 +10:00
Tim Nagel a97ed80aee Merge branch 'nurikabe-master'
Conflicts:
	Resources/doc/types.md
2014-04-10 13:06:22 +10:00
Tim Nagel b3fdf7b256 Logger for a listener is false by default 2014-04-10 13:05:23 +10:00
nurikabe f07e55417d Re-throw exception if no logger defined 2014-04-07 16:16:37 -04:00
Joshua Worden 22e5a1d4ab CS fix 2014-04-07 10:58:11 -05:00
Tim Nagel d7302847e4 Merge pull request #542 from hugohenrique/patch-1
fix link to documentation of custom repositories
2014-04-07 09:11:12 +10:00
Hugo Henrique 998c69bfc3 Update usage.md
This link to documentation custom repositories is broken
2014-04-06 15:17:02 -03:00
nurikabe a483471694 Set listener loggers to fos_elastica.logger if null 2014-04-04 22:56:47 -04:00
Tim Nagel ab3587980c Merge pull request #539 from nurikabe/patch-2
Fix documentation about `immediate`
2014-04-05 10:34:09 +11:00
Tim Nagel 10fcbfc135 Merge pull request #538 from nurikabe/patch-1
Remove rogue paren
2014-04-05 10:30:36 +11:00
Evan Owens 53332eb057 Allow for catching/logging persistance errors per listener 2014-04-04 18:32:48 -04:00
Evan Owens 377b2843ba Fix documentation about immediate
Unless I misimplemented this, "immediate" means persist to ElasticSearch "immediately"; before flushing.  Default behavior is false; persist to ElasticSearch postFlush.
2014-04-05 07:12:16 +10:00
Evan Owens 10f6149f8c Remove rogue paren 2014-04-05 07:04:52 +10:00
Evan Owens 6f444f1ce8 Bulk upsert 2014-04-04 15:51:55 -04:00
nurikabe 49284a4963 Merge remote-tracking branch 'upstream/master' 2014-04-04 15:29:06 -04:00
Josh Worden b6e2583455 Added getDoctrineObject method to retrieve an entity or document from a LifecycleEventArgs instance in the unified Listener class 2014-04-04 10:47:50 -05:00
Tim Nagel d67d525b66 Merge pull request #485 from piotrantosik/elastica-knp-paginator-sort
Added knp paginator sort functionality to PaginateElasticaQuerySubscribe
2014-04-04 08:46:40 +11:00
Piotr Antosik 1bc148569b Added knp paginator sort functionality to PaginateElasticaQuerySubscriber 2014-04-03 10:44:18 +02:00
Patrick Zahnd 13c2d10e39 Added knp paginator sort functionality to PaginateElasticaQuerySubscriber 2014-04-03 00:02:43 +02:00
Tim Nagel e74acb1e4f Revert "Avoid index reset error in case of unexistant index"
This reverts commit a121a77774.
2014-04-03 08:00:52 +11:00
Josh Worden 1628413e65 Added support for getting documents in unified Doctrine Listener 2014-04-02 10:06:24 -05:00
nurikabe a89856be50 Reset / create new index even if the index doesn't exist 2014-04-02 07:18:46 -04:00
Tim Nagel ff95945819 Merge pull request #527 from baggachipz/master
Upsert-type functionality for existing ORM Entities
2014-04-02 08:47:47 +11:00
Tim Nagel ec7f04a261 Merge pull request #515 from nurikabe/master
Clone entities on delete to preserve ids
2014-04-01 20:22:22 +11:00
Tim Nagel 5855ac6fbd Merge pull request #525 from jvandesande/MultiField
Unset nested "fields" for deeper nested configs too
2014-04-01 09:11:31 +11:00
baggachipz 20810fa415 Upsert-type functionality for existing ORM Entities
This is an attempt to fix the issue: https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/526

It will cause a significant slowdown in a large batch, but it appears to be the only way to prevent an exception from bubbling up during a normal use case.
2014-03-31 15:16:32 -04:00
Joris van de Sande 588c4e2d02 Unset nested "fields" for deeper nested configs too 2014-03-31 12:52:29 +02:00
Joseph Bielawski f15ca02859 Fix documentation for client overwriting. 2014-03-31 11:59:37 +02:00
nurikabe 0de48d2190 Use identifiers for bulk delete rather than cloning objects 2014-03-29 18:36:06 -04:00
Tim Nagel 40e79b2abe Merge pull request #521 from morticue/master
Corrected bundle class name in install instructions
2014-03-28 08:52:27 +11:00
Joakim Friberg a81a630520 Corrected bundle class name in install instructions 2014-03-27 16:33:20 +01:00
Tim Nagel 8c146134da Merge pull request #519 from merk/logger-debug
Change logging to only be enabled in debug mode
2014-03-26 12:42:34 +11:00
Tim Nagel 38b4074745 Update logger documentation based on configuration change 2014-03-26 12:40:27 +11:00
Tim Nagel 9f27c1dade Update changelog 2014-03-26 12:38:20 +11:00
Tim Nagel e25a5420a5 Logger enabled with debugging 2014-03-26 12:38:20 +11:00
Tim Nagel 37db040096 Merge pull request #435 from merk/documentation
Refactored documentation
2014-03-26 10:09:17 +11:00
Tim Nagel eb7758605e Documentation updates 2014-03-26 10:07:50 +11:00
Tim Nagel 49f077cc30 Merge pull request #510 from peterjmit/master
Make fetchSlice compatible with custom repo method
2014-03-26 10:01:18 +11:00
Tim Nagel befb0907cc Merge branch 'master' into documentation
Conflicts:
	DependencyInjection/Configuration.php
	README.md
2014-03-25 16:04:32 +11:00
Tim Nagel e83ea0b6c8 Merge pull request #505 from piotrantosik/fix_docblocks
Fix some block comment
2014-03-25 15:48:18 +11:00
Tim Nagel 1e44051442 Merge pull request #514 from jvandesande/MultiField
Unset fields if no nested fields are defined
2014-03-25 15:47:06 +11:00
nurikabe 361d80a720 Prevent division by zero error 2014-03-24 11:18:55 -04:00
nurikabe 720917f609 Clone entities on delete to preserve ids 2014-03-24 11:16:31 -04:00
Joris van de Sande 455ff9e0f7 Unset fields if no nested fields are defined 2014-03-24 15:06:24 +01:00
Peter Mitchell 2009f88109 Make fetchSlice compatible with custom repo method
If a user configures query_builder_method for the doctrine provider, and
does not alias the root entity to equal Provider::ENTITY_ALIAS then a
DQL error will occur during index population.

> [Semantical Error] [...] near 'a.id ASC': Error: 'a' is not defined.

Provider::countObjects already handles this by dynamically fetching the
alias with QueryBuilder::getRootAliases, and Provider::fetchSlice should
be doing the same.

nb. "Provider" refers to FOS\ElasticaBundle\Doctrine\ORM\Provider
2014-03-19 08:40:58 -04:00
Tim Nagel 514e63f26f Merge pull request #496 from rayrigam/master
Add support for clients requiring basic HTTP authentication
2014-03-19 12:32:48 +11:00
Ray 4dc08cd006 Added notice about added support for HTTP headers. 2014-03-18 20:07:30 -04:30
Ray 41b347dfe4 Merge remote-tracking branch 'upstream/master'
Conflicts:
	Logger/ElasticaLogger.php
	README.md
2014-03-18 19:59:27 -04:30
rayrigam de70e78b53 Update Configuration.php
Updated to support any HTTP request header type in the "headers" section.
2014-03-18 18:14:03 -04:30
Tim Nagel babe20800e Updated changelog 2014-03-18 09:12:11 +11:00
Tim Nagel 7d13823488 Bump symfony requirement 2014-03-18 09:10:44 +11:00
Tim Nagel dc01b189ed Update CHANGELOG-3.0.md 2014-03-17 09:26:16 +11:00
Tim Nagel 5292a2adad Merge pull request #463 from FriendsOfSymfony/add-hotswapping-aliased-indexes-on-populate
Add support for using aliases to allow hot swapping of indexes.
2014-03-17 09:20:12 +11:00
Tim Nagel 49521e9fc4 Merge branch 'master' into add-hotswapping-aliased-indexes-on-populate
Conflicts:
	Resetter.php
2014-03-17 09:18:57 +11:00
Tim Nagel 857c1c8e48 Merge pull request #415 from nurikabe/master
Refactoring to update ElasticSearch index in postFush
2014-03-17 09:11:43 +11:00
Piotr Antosik 6a26c63b2c fix some block comment 2014-03-14 18:41:49 +01:00
Tim Nagel cdd6e3af45 Bump elastica version 2014-03-14 08:59:59 +11:00
Tim Nagel 6cd69ad131 Merge pull request #361 from xphere-forks/master
Add support for include_in_parent and include_in_root options
2014-03-14 08:53:42 +11:00
Tim Nagel 7cf8cd446f Merge pull request #501 from FriendsOfSymfony/reset-type-ignore-type-missing-exception
Ignore TypeMissingException when resetting a single type. This allows to...
2014-03-14 08:48:59 +11:00
Tim Nagel 6beafd23f1 Merge pull request #494 from bastnic/patch-1
[doc] inform about the override of Elastica logger
2014-03-14 08:44:06 +11:00
Tim Nagel da0abca38c Merge pull request #487 from XWB/logger-cleanup
ElasticaLogger cleanup
2014-03-14 08:43:42 +11:00
Tim Nagel 48edc195cd Merge pull request #484 from bits4breakfast/containeraware-callback
Container is now available in Callback
2014-03-14 08:41:15 +11:00
Lea Haensenberger 2f9896c893 Check for TypeMissingException anywhere in exception message 2014-03-13 10:45:57 +01:00
Lea Haensenberger 726892c586 Ignore TypeMissingException when resetting a single type. This allows to create new types without having to recreate the whole index. 2014-03-13 10:43:35 +01:00
Lukas Kahwe Smith 33f85bec22 Merge pull request #499 from mvrhov/patch-2
Fix wrong annotation
2014-03-11 15:18:36 +01:00
Miha Vrhovnik fe871c5ac4 Fix wrong annotation 2014-03-11 14:50:00 +01:00
Ray 0116a6ac4f Add support for clients requiring basic HTTP authentication 2014-03-06 12:38:23 -04:30
Berny Cantos 7f53badad5 Add support for include_in_{parent,root} for nested and objects 2014-03-06 12:31:50 +01:00
Bastien Jaillot a1f7449efc [doc] inform about the override of Elastica logger
Add a documentation related to this change: https://github.com/FriendsOfSymfony/FOSElasticaBundle/pull/395#issuecomment-27729759
2014-03-05 16:13:51 +01:00
Tim Nagel 245732781b Merge pull request #493 from tgallice/url_parameter_fix
Rework configuration validation to fix #461
2014-03-05 09:12:44 +11:00
tgallice 418b9d72ce Rework configuration validation to fix #461 2014-03-04 17:58:10 +01:00
Karel Souffriau 2b04f6cf34 ElasticaLogger cleanup 2014-02-25 11:05:26 +01:00
Matteo Galli eecdd3474a Fixes #459 2014-02-21 16:47:42 +01:00
Tim Nagel c8c72f5f0b Merge pull request #481 from XWB/abstract-provider-cleanup
AbstractProvider cleanup
2014-02-21 09:23:45 +11:00
Tim Nagel 6f8b3a5a0f Fix populate command option 2014-02-21 08:58:43 +11:00
Karel Souffriau 1c74f61b4e AbstractProvider cleanup 2014-02-20 12:57:10 +01:00
Tim Nagel b7d664c665 Merge pull request #480 from XWB/populate-command-hotfix
Fixed bug made in #479
2014-02-19 23:02:13 +11:00
Karel Souffriau 891dd51abe Fixed bug made in #479 2014-02-19 12:50:48 +01:00
Tim Nagel dd718c9a63 Merge pull request #479 from XWB/populate-command-fix
Tweak: use hasOption() in PopulateCommand instead of checking for booleans
2014-02-19 22:45:37 +11:00
Karel Souffriau 63cca11a0b Tweak: use hasOption() in PopulateCommand instead of checking for booleans 2014-02-19 12:43:44 +01:00
Tim Nagel 20b16d4f8c Merge pull request #478 from XWB/fix-tests
Fixes in "stop on error" feature
2014-02-19 22:40:47 +11:00
Karel Souffriau 44180793fc Add changelog file for 3.0 2014-02-19 12:36:39 +01:00
Karel Souffriau 41bf07ec59 Fixed issues in #426 2014-02-19 12:19:34 +01:00
Tim Nagel 5fff46cc60 Merge pull request #477 from XWB/cs-fix
CS fix in AbstractProvider
2014-02-19 20:13:26 +11:00
Karel Souffriau b8cc6d758c CS fix in AbstractProvider 2014-02-19 09:31:22 +01:00
Tim Nagel d03d494d30 Merge remote-tracking branch 'tgabi/stop-on-error' 2014-02-19 13:50:33 +11:00
Tim Nagel efc1794d3f Merge pull request #447 from astina-forks/populate_interactive_fix
Populate command: use isInteractive() instead of option
2014-02-19 13:46:09 +11:00
Tim Nagel e6f1d9ffe8 Merge pull request #454 from elfafa/master
Add RAM (current & peak) in populate evolution information
2014-02-19 13:45:24 +11:00
Tim Nagel 92b7fd981b Merge pull request #458 from digitalkaoz/patch-1
fixes ignore_missing option and unknown index
2014-02-19 13:44:42 +11:00
Tim Nagel cb2eeba318 Merge pull request #461 from tgallice/url_parameter
Force slash at the end of the url parameter
2014-02-19 13:40:18 +11:00
Tim Nagel 13e81fd7bb Merge pull request #462 from oohnoitz/master
added support for setting search options
2014-02-19 13:40:03 +11:00
Tim Nagel aa9d74a8a0 Merge remote-tracking branch 'PeerJ/AddServerTimeout'
Conflicts:
	DependencyInjection/Configuration.php
2014-02-19 13:39:03 +11:00
Tim Nagel 5a36d8f769 Merge pull request #468 from FriendsOfSymfony/fix-reset-index-type
Keep all special mapping fields for types when resetting a single type. ...
2014-02-19 13:31:29 +11:00
Hung Tran 7d2776e27a fixed phpdoc 2014-02-18 10:12:31 -06:00
Patrick McAndrew 3065c96a2c Add ability to specify server timeout 2014-02-14 17:32:22 +00:00
Lea Haensenberger 765e400278 handle _parent separately 2014-02-13 10:06:10 +01:00
Lea Haensenberger ead3c95c88 Keep dynamic templates 2014-02-13 09:45:27 +01:00
Lea Haensenberger 1402bdc9e6 Keep all special mapping fields for types when resetting a single type. Field list is according to the current documentation of elasticsearch 0.90 2014-02-13 09:13:36 +01:00
Richard Miller 03bf793b65 Make real index name use uniqid so can be reset within a second 2014-02-10 10:55:13 +00:00
Richard Miller 3b1a756e6f Add support for using aliases to allow hot swapping of indexes when populating 2014-02-06 21:11:12 +00:00
Hung Tran 5be3a8c22e added query string to collector and updated tests 2014-02-05 11:58:13 -06:00
Hung Tran d04a403f71 added support for setting search options 2014-02-04 19:41:38 -06:00
tgallice 04390b37d1 Force slash at the end of the url parameter 2014-02-04 10:07:58 +01:00
Fabien Somnier 48b785e876 New method getMemoryUsage to get RAM information message 2014-02-03 18:12:20 +01:00
Fabien Somnier 0ae84d56c7 Merge remote-tracking branch 'upstream/master' 2014-02-03 17:51:23 +01:00
Fabien Somnier a121a77774 Avoid index reset error in case of unexistant index 2014-02-03 17:50:35 +01:00
Robert Schönthal f348ebd026 fixes ignore_missing option and unknown index 2014-02-03 09:47:16 +01:00
nurikabe 559d7c13f2 Update tests 2014-02-01 03:37:47 +00:00
nurikabe 93c6085fa5 Merge remote-tracking branch 'upstream/master' 2014-02-01 02:15:52 +00:00
nurikabe 1dcaadbe6f Bulk delete 2014-02-01 02:14:21 +00:00
Tim Nagel 82e9809ceb Merge pull request #453 from pentarim/master
adding ttl for documents
2014-01-30 13:42:09 -08:00
Fabien Somnier 5e54dcd955 Add RAM (current & peak) in populate evolution information 2014-01-30 13:01:13 +01:00
Laszlo Horvath 5480e037e3 adding ttl for documents 2014-01-30 12:39:48 +01:00
Tim Nagel d0457549c6 Merge pull request #452 from piotrantosik/master
Services classes as parameters
2014-01-29 13:57:48 -08:00
Piotr Antosik 076d51ac40 Services classes as parameters 2014-01-29 17:50:42 +01:00
Tim Nagel 1f9c111193 Merge pull request #450 from antistatique/master
[doc] repository methode has to return the query
2014-01-28 02:54:11 -08:00
Simon Perdrisat 1c7da33526 [doc] repository methode has to return the query 2014-01-28 11:34:54 +01:00
pkraeutli 62dc3aaca0 Populate command: use isInteractive() instead of option 2014-01-24 14:20:10 +01:00
nurikabe b6d010a9d7 Bulk update. Still working on bulk delete for indexes and types in Elastica. 2014-01-23 16:20:11 +00:00
Tóth Gábor bbacad4bab no-stop-on-error option added to populate command 2014-01-21 18:38:51 +01:00
Tim Nagel ef872dd22d Merge pull request #439 from FriendsOfSymfony/type-timestamp
Adding support for enabling timestamps
2014-01-20 12:57:02 -08:00
Tim Nagel f0f6fc8129 Merge pull request #441 from klmatom/master
Add similarity as a valid field mapping.  http://www.elasticsearch.org/g...
2014-01-20 12:56:47 -08:00
Tim Nagel b6d0627c2a Merge pull request #440 from vermi0ffh/master
A simple change in conf def for easier allowing new type through prependExtensionConfig()
2014-01-20 12:52:56 -08:00
Tom A 4287a91d50 Add similarity as a valid field mapping. http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-core-types.html#similarity 2014-01-16 23:05:44 -05:00
nurikabe 4a4716a55b Merge remote-tracking branch 'upstream/master' 2014-01-11 16:38:29 +00:00
nurikabe 7481376835 Use bulk insert. Still working on bulk update/delete which is not yet suppored in Elastica. 2014-01-11 16:28:15 +00:00
Vermi 73ee750515 Removing "->performNoDeepMerging()"in indexes configuration, allowing custom Bundle defining new types in an existing index.
Configuration is injected in the new Bundle using prependExtensionConfig()
2014-01-10 16:25:45 +01:00
Lea Haensenberger 274fc00991 Add store and index options to timestamp 2014-01-06 10:19:11 +01:00
Lea Haensenberger 4ee81dc010 Adding support for enabling timestamps 2014-01-06 09:20:44 +01:00
Tim Nagel d33c5d0ece Fix tests 2013-12-17 21:38:08 +11:00
Tim Nagel 21f688e014 Merge pull request #433 from FriendsOfSymfony/fix-reset-command
Fix reset command
2013-12-17 02:34:00 -08:00
Tim Nagel a2d4070fdc Merge pull request #429 from craigmarvelley/improve-code-coverage
Improve test coverage
2013-12-17 02:33:29 -08:00
Tim Nagel 5f8b8003d1 Refactor documentation 2013-12-17 21:17:28 +11:00
Lea Haensenberger e906d780ad Adding tests 2013-12-16 12:06:53 +01:00
Lea Haensenberger 05ee300ddb Fixing reset command to allow resetting of just one type, starting to write test 2013-12-16 11:58:58 +01:00
Tim Nagel 90022b0d0a Move type configuration into independent method 2013-12-15 18:33:45 +11:00
Tim Nagel e2e21b1e0c Allow bundle to be used without clients or indexes defined. 2013-12-15 18:33:31 +11:00
nurikabe 3bd9155f46 Use constants of corresponding events classes rather than making assumption about string values. 2013-12-13 17:51:15 +00:00
Tim Nagel f565ec5638 Merge pull request #432 from hardchor/duplicate-code-removal
Removed duplicate methods
2013-12-12 15:07:28 -08:00
Craig Marvelley 292af9f039 Better variable names 2013-12-12 22:57:02 +00:00
Burkhard Reffeling e0ef8dff23 removed duplicate methods 2013-12-12 22:41:20 +00:00
Craig Marvelley 5d16ffb1bf Remove unused method 2013-12-12 20:50:15 +00:00
Craig Marvelley 11a87c5ce3 Add test for ElasticaToModelTransformerCollection::hybridTransform 2013-12-12 20:48:15 +00:00
Craig Marvelley 090f02b05d Improve test coverage 2013-12-12 11:11:34 +00:00
Tim Nagel 6c4740b292 Merge pull request #423 from FriendsOfSymfony/dynamic-templates
Apply same mapping logic to dynamic templates...
2013-12-11 02:17:52 -08:00
Lea Haensenberger a59385af7b Do not set default value to *, might conflict when using e.g. path_match and match_pattern regex together 2013-12-10 15:37:41 +01:00
Lea Haensenberger 0aa98d2295 Fixing copy&paste error 2013-12-10 15:21:46 +01:00
Lea Haensenberger e55c7e8632 Set match to '*' by default 2013-12-10 15:21:46 +01:00
Lea Haensenberger 09031457cd Allow more matching methods 2013-12-10 15:21:46 +01:00
Lea Haensenberger bad1769c84 Fixing tests 2013-12-10 15:21:46 +01:00
Lea Haensenberger eaf52fa907 Allow a more dynamic mapping for dynamic templates 2013-12-10 15:21:46 +01:00
leahaense ab792952c1 Merge pull request #425 from cs-daniel/patch-1
Fix client configuration missing logger
2013-12-10 05:12:18 -08:00
Császár Dániel e16ece821d Fix client configuration missing logger 2013-12-10 13:54:50 +01:00
Tim Nagel 70e6cb2e7e Fix issue with logger not having logQuery method 2013-12-10 21:25:38 +11:00
Tim Nagel da44ee65f6 Merge pull request #395 from pierredup/logger
Add option to enable logger and define logger class
2013-12-10 02:17:10 -08:00
Tim Nagel e1ed7bdc67 Merge pull request #420 from FriendsOfSymfony/all-field-config
Add support to disable the _all field for a type
2013-12-10 02:16:23 -08:00
Tim Nagel 8668537740 Merge pull request #400 from cordoval/cleanups
clean ups
2013-12-10 02:15:53 -08:00
Jeremy Mikola 21474b844b Merge pull request #403 from cordoval/patch-1
typo
2013-12-10 00:25:55 -08:00
Tim Nagel fc64078575 Merge pull request #413 from damienalexandre/serializer-integration
Serializer support in providers and mapping configuration fixes
2013-12-09 12:35:26 -08:00
Tim Nagel 4addb0d66f Merge pull request #421 from damienalexandre/profiler-curl
[Feature] Allow to display a run-able cURL query in the web profiler
2013-12-09 12:33:02 -08:00
Damien Alexandre 1ddd7c0e0c Store connection infos for all transports, display infos in debug 2013-12-09 14:46:06 +01:00
Damien Alexandre ca507a5e34 Add full_host in logger for HTTP(s) queries 2013-12-09 10:40:47 +01:00
Damien Alexandre c97a4abceb Add display cURL on the web debug queries shower 2013-12-09 10:09:36 +01:00
Lea Haensenberger 8f1b52328f Merge remote-tracking branch 'origin/master' into all-field-config
Conflicts:
	DependencyInjection/FOSElasticaExtension.php
2013-12-06 08:25:02 +01:00
Lea Haensenberger 08193ec2fd Add support to disable the _all field for a type 2013-12-05 16:35:30 +01:00
Pierre du Plessis 759950aff6 Add option to disable logger or specify different logger service 2013-12-04 22:09:27 +02:00
nurikabe 3a279f8edb Remove debug. 2013-12-04 10:46:05 +00:00
Richard Miller a227a3f076 Merge branch '2.1.x' 2013-12-04 08:03:04 +00:00
Richard Miller 2980ee818a Merge branch '2.0.x' into 2.1.x 2013-12-04 08:02:22 +00:00
Richard Miller 5a0d860786 Merge pull request #418 from blongden/2.0.x
Adds enabled mapping option (default true)
2013-12-04 00:00:47 -08:00
Ben Longden 8b6dffbc14 Adds enabled mapping option (default true) 2013-12-04 07:53:08 +00:00
nurikabe ed21e60869 Remove upgrade doc. Merk will add manually. 2013-12-03 23:40:00 +00:00
nurikabe 22a5d67d05 pre/postFlush configuration. Update documentation. 2013-12-03 20:41:26 +00:00
nurikabe af2827df01 Re-add renamed Listener. 2013-12-03 14:01:21 +00:00
Damien Alexandre 8a4848a16d Add UPGRADE-3.0.md file with descriptions of new features / changes 2013-12-02 22:35:50 +01:00
Damien Alexandre 25e59a311b Fix Persister constructor and undefined property 2013-12-02 22:26:30 +01:00
Damien Alexandre cf3e35e892 Remove extra line-break 2013-12-02 22:15:11 +01:00
nurikabe 1d700261ab Refactor to a single Listener class. Update tests. 2013-12-02 12:42:04 +00:00
nurikabe 5ec652063d Don't need postRemove. 2013-12-01 21:48:41 +00:00
nurikabe f258c9ddc0 Exploratory development for https://github.com/FriendsOfSymfony/FOSElasticaBundle/issues/410 2013-12-01 21:17:55 +00:00
Damien Alexandre 3027c687e2 Ref #341, fix the insertMany method to use Bulk indexing
To make it works, I inject the serializer defined for the Type
into the fos_elastica.object_serializer_persister service.

This is the SAME service injected in the setSerializer of Type.

We deport the handling of serialization outside Elastica,
this is not so good but we need to build our own Documents to
get the ID's correctly.
2013-11-29 15:35:59 +01:00
Damien Alexandre 2862259d8e Allow empty or null or no mappings: key under type configuration
refs #300. This commit allow to define types without having to
set any mapping as Elasticsearch build his own.

The minimal config become:

    indexes:
        toto:
            client: default
            types:
                Article:
                    mappings: ~
                    ...
2013-11-29 14:59:56 +01:00
Damien Alexandre b149ac235b Replace deprecated calls Document::add to Document::set 2013-11-29 13:53:25 +01:00
Damien Alexandre e180f1fd61 Merge remote-tracking branch 'peerj/ObjectWithoutProperties' into serializer-integration
Conflicts:
	Transformer/ModelToElasticaAutoTransformer.php
2013-11-29 13:51:58 +01:00
Damien Alexandre d546b4d3f3 Merge remote-tracking branch 'origin/serializer-transformer' into serializer-integration
Conflicts:
	DependencyInjection/FOSElasticaExtension.php
	Resources/config/config.xml
2013-11-29 10:07:13 +01:00
Luis Cordova cacb40286c clean ups 2013-11-20 08:11:15 -05:00
Luis Cordova c82006e8ac fix typos 2013-11-20 07:48:00 -05:00
Tim Nagel 40d3df9f92 Merge branch '2.1.x'
Conflicts:
	Finder/TransformedFinder.php
2013-11-19 08:29:02 +11:00
Tim Nagel 4fb0545a78 Merge branch '2.0.x' into 2.1.x 2013-11-19 08:27:41 +11:00
Tim Nagel a3077e1b53 Merge pull request #402 from XWB/mlt-fix
TransformedFinder::moreLikeThis: use \Elastica_Document instead of \Document
2013-11-16 23:44:07 -08:00
Karel Souffriau 97aadf4897 TransformedFinder::moreLikeThis: use \Elastica_Document instead of \Document 2013-11-15 17:51:26 +01:00
Tim Nagel 3c26f157aa Merge branch '2.1.x'
Conflicts:
	Tests/ResetterTest.php
2013-11-11 13:30:29 +11:00
Matyas Somfai 3f784b0a5b added new options to fos:elastica:populate command and options array parameter to ProviderInterface
removed assume-yes option as the no-interaction option has the same purpose
2013-11-11 13:23:28 +11:00
Tim Nagel 52d5d0d55f Remove incorrect copyright header 2013-11-11 13:21:36 +11:00
Tim Nagel 7464625566 Merge pull request #399 from merk/query-builder-transformers
Add query_builder_method option to the transformers
2013-11-10 18:19:22 -08:00
Tim Nagel 9b6b0b0148 Add query_builder_method option to the transformers 2013-11-11 13:14:02 +11:00
Tim Nagel 08697a4d84 Merge pull request #397 from igorRovenki/master
Update README.md
2013-11-06 13:03:10 -08:00
igorRovenki be4c99a0d3 Update README.md
Should be "listener: ~" on the line 595, otherwise listener does not working
2013-11-06 11:01:53 +02:00
Tim Nagel d5c606c64a Merge pull request #388 from XWB/dynamic_template_support
Add support for dynamic templates
2013-11-04 13:49:48 -08:00
Tim Nagel 8a14fbd73b Merge pull request #394 from pierredup/master
Add Symfony ExpressionLanguage support for indexable callback
2013-11-04 01:59:40 -08:00
Pierre du Plessis f972b4af59 Fixed CS 2013-11-04 08:50:41 +02:00
Pierre du Plessis 97c98a0243 Add Symfony ExpressionLanguage support for indexable callback 2013-11-04 00:09:21 +02:00
Tim Nagel 28641427d5 Merge tag 'v2.1.3-PL1' 2013-11-01 09:17:17 +11:00
Tim Nagel 7f8a8e95e6 Merge tag 'v2.0.3-PL1' into 2.1.x 2013-11-01 09:16:27 +11:00
Tim Nagel 21ce3cf6ff Fix definition decorators (closes #393) 2013-11-01 09:15:38 +11:00
Jeremy Mikola 467ccbf753 Tag client services in DI extension class
These tags were originally introduced in 16ecd7cca3. #339 removed the fos_elastica.client definition from config.xml, so this tag needs to be added via the DI extension class now.
2013-10-30 17:15:09 -04:00
Jeremy Mikola 68092eb4db Merge branch '2.1.x'
Conflicts:
	Resources/config/config.xml
2013-10-30 17:14:20 -04:00
Jeremy Mikola 11d0dd8f91 Merge branch '2.0.x' into 2.1.x 2013-10-30 17:10:04 -04:00
Jeremy Mikola 6e0f144ec2 Merge pull request #339 from FriendsOfSymfony/2.0.x-definition-decorators
2.0.x definition decorators
2013-10-30 14:09:43 -07:00
Jeremy Mikola 74d993b642 Do not clobber existing client definitions (closes #336 and #324)
While we could have used an abstract definition, its ID would likely conflict with the alias we set for the default client. Remove the abstract definition altogether and simply construct new definitions for each client. This resolves the previous issue where multiple clients would overwrite the constructor arguments of the previous definition.
2013-10-30 15:15:26 -04:00
Jeremy Mikola 604193396f Remove "prototype" from abstract definition IDs; note possible conflicts
Due to the naming of transformer, listener, and finder services, it's possible for index/type services to clobber the ID of another concrete or abstract service. This cannot be helped without breaking BC, but we should note it within the extension class.
2013-10-30 15:15:25 -04:00
Karel Souffriau c68bb411ac Add support for dynamic templates 2013-10-30 13:39:43 +01:00
Tim Nagel ca57b0d72e Merge pull request #379 from smatyas/populate-command-provider-options
New options to fos:elastica:populate command: offset, sleep, batch-size
2013-10-29 17:10:46 -07:00
Matyas Somfai 43e026500c added new options to fos:elastica:populate command and options array parameter to ProviderInterface
removed assume-yes option as the no-interaction option has the same purpose
2013-10-30 00:02:34 +01:00
Tim Nagel 85c4dc92f9 Merge tag 'v2.1.3'
Conflicts:
	DependencyInjection/Configuration.php
	README.md
2013-10-30 09:06:48 +11:00
Tim Nagel 8f49b246bc Merge tag 'v2.0.3' into 2.1.x 2013-10-30 09:01:05 +11:00
Tim Nagel f97dc21030 Merge pull request #355 from richardmiller/add-mlt
Add moreLikeThis query to finder
2013-10-29 14:55:00 -07:00
Tim Nagel cfaa85f1c5 Merge pull request #389 from XWB/add_format_field
Add date format field
2013-10-29 14:54:17 -07:00
Karel Souffriau 9d1201099d Add date format field 2013-10-29 12:20:32 +01:00
Tim Nagel c6b01a2c50 Merge pull request #382 from thierrymarianne/master
Fix type hinting in "Manual provider" example
2013-10-17 15:05:42 -07:00
Thierry Marianne 85a10613ba Fix type hinting in "Manual provider" example 2013-10-17 22:40:28 +02:00
Lukas Kahwe Smith 2cbf5f797b Merge pull request #367 from peterkokot/patch-2
LICENSE file removed in favor of Resources/meta/LICENSE file
2013-10-13 06:15:13 -07:00
Tim Nagel 7b1fe89627 Merge pull request #378 from dbu/patch-1
add a note how to use the parent mapping
2013-10-08 16:09:20 -07:00
David Buchmann ac56775791 add a note how to use the parent mapping 2013-09-26 10:02:48 +02:00
Peter Kokot 2b942a6edf LICENSE file removed in favor of Resources/meta/LICENSE file 2013-09-16 19:47:05 +02:00
Lukas Kahwe Smith 9fca3516b2 Merge pull request #365 from peterkokot/patch-1
Update LICENSE
2013-09-15 02:24:59 -07:00
Peter Kokot 6551028753 Update LICENSE
Updated license year range
2013-09-15 09:17:13 +02:00
leahaense 23382c895e Merge pull request #322 from ajgarlag/parentmapping
Fix _parent mapping.
2013-09-10 23:53:15 -07:00
Jeremy Mikola 2bfb637a00 Merge pull request #358 2013-08-19 12:02:28 -04:00
Robert Plant 41e132140e Added ability to access facets with paginated results 2013-08-19 12:01:32 -04:00
Jeremy Mikola b40149cbdc Code and documentation formatting in Propel transformer class 2013-08-19 12:00:56 -04:00
cedric lombardot 3c01ebb775 Fix ElasticaToModelTransformer the transform closure use Result instead of Document 2013-08-19 12:00:56 -04:00
Richard Fullmer e97b60fc7e Ignore failed deletions in ObjectPersister
This probably isn't the best way to solve my problem,
but the issue is this.

Step 1:  Create a new doctrine entity for which it's `is_indexable_callback`
returns false.  When doctrine flushes this entity to the database,
elastia will not index it with elastic search.  (Correct)

Step 2:  Update your doctrine entity and change some fields so
that `is_indexable_callback` _still_ returns false.  Persist and flush
to the database.

At this point, the postUpdate listener on ElastiaBundle is called
and since the `is_indexable_callback` returns false, it believes
it needs to remove it from the elastic search index and queues it
for deletion.  The deletion of course fails because it was never there
in the first place.

This solution simply ignores failures from deletions in the index.

Perhaps a better solution would be to have a smarter listener
that could determine if the entity was previously present in the
elastic search index or not, but that would require significant
refactoring.

Addresses issues discuseed in #284

Credit to @bbeaulant for simple solution.  Opening a PR to
discuss more generally.
2013-08-19 12:00:56 -04:00
Richard Miller 79501dc319 Add moreLikeThis query to finder 2013-08-12 11:04:54 +01:00
Jeremy Mikola 0b3c1ebbc2 Merge pull request #350 2013-08-09 13:57:16 -04:00
Jeremy Mikola c15caf3096 Code and documentation formatting in Propel transformer class 2013-08-09 13:56:51 -04:00
cedric lombardot e2b6177a33 Fix ElasticaToModelTransformer the transform closure use Result instead of Document 2013-08-09 13:42:12 -04:00
Jeremy Mikola b922315172 Merge pull request #312 from opensoft/issue-284
Ignore failed deletions in ObjectPersister
2013-08-07 13:57:23 -07:00
NicolasBadey 617b9d3f4b Recalculate pagination Query size if a limit is already set 2013-07-18 14:06:32 -04:00
Lea Haensenberger 37cfdb0df7 refactoring some code 2013-07-18 10:56:25 +02:00
Lea Haensenberger 77156b35aa some formatting and cleaning up 2013-07-18 10:54:11 +02:00
Lea Haensenberger 300d189a9d renaming services to avoid potential conflicts 2013-07-18 10:51:51 +02:00
Jeremy Mikola dcd3cbb944 Merge branch '2.1.x'
Conflicts:
	Tests/Transformer/ModelToElasticaAutoTransformerTest.php
2013-07-17 15:57:24 -04:00
Jeremy Mikola 4a889406e9 Merge branch '2.0.x' into 2.1.x
Conflicts:
	Tests/Transformer/ModelToElasticaAutoTransformerTest.php
2013-07-17 15:55:55 -04:00
Jeremy Mikola ab0c27c481 Fix expected exception class (related to #338)
This corrects a typo in a66a37aebd.
2013-07-17 15:54:06 -04:00
Jeremy Mikola 7ae4be0062 Merge branch '2.0.x' into 2.1.x
Conflicts:
	Tests/Transformer/ModelToElasticaAutoTransformerTest.php
2013-07-17 15:49:09 -04:00
Jeremy Mikola a66a37aebd Merge pull request #338 from FriendsOfSymfony/2.0.x-property-access
Fix missing getter for private field test for PropertyAccess 2.3+
2013-07-17 12:44:57 -07:00
Lea Haensenberger d10e8f56c8 Tests for new provider and new transformer 2013-07-17 10:10:07 +02:00
Lea Haensenberger 5b6a1f7bd6 Adding new persister and new transformer to make use of the serializer support of elastica when persisting doctrine objects 2013-07-17 08:58:15 +02:00
Jeremy Mikola 00f37835fc Rewrite filtered query example in README
Cleaning up the description paragraph and removing extra fields and pagination from the example, since we already have pagination examples elsewhere in the README.
2013-07-16 13:35:27 -04:00
RobertPlant cce1ffb06c Add filtered query example to README.md 2013-07-16 13:35:27 -04:00
Jeremy Mikola 9e2e8ab1c9 Fix missing getter for private field test for PropertyAccess 2.3+
See: df67239b02
2013-07-12 17:32:33 -04:00
Jeremy Mikola 1af85115df Merge pull request #323 from ajgarlag/orm-provider-order-by
An orderBy DQL  part is required to avoid feching the same row twice
2013-07-08 09:08:11 -07:00
Jeremy Mikola deb29233ba Merge pull request #330 from tgabi333/patch-1
Remove unused parameter from ModelToElasticaAutoTransformer.php
2013-07-04 13:11:03 -07:00
Gábor Tóth 9beb277745 Remove unused parameter from ModelToElasticaAutoTransformer.php 2013-07-04 18:47:58 +02:00
Antonio J. García Lagar 170864a30d Removes sort call 2013-07-04 08:07:00 +02:00
Jeremy Mikola 5bee33eec9 Merge pull request #321 from ajgarlag/fix-output-color
Fix output colors for single type commands
2013-07-02 13:48:40 -07:00
Lukas Kahwe Smith 8912e52980 Merge pull request #326 from Tobion/patch-1
Allow elastica 0.90. Elasticsearch made the jump from 0.20 to 0.90
2013-06-24 08:52:03 -07:00
Tobias Schultze 8b785c57c3 Allow elastica 0.90. Elasticsearch made the jump from 0.20 to 0.90 2013-06-24 18:44:46 +03:00
Antonio J. García Lagar 7f3cfa49fb Make the property param optional 2013-06-19 13:57:15 +02:00
Antonio J. García Lagar b11b4299ef An orderBy DQL part is required to avoid feching the same row twice 2013-06-19 12:36:59 +02:00
Antonio J. García Lagar 0bf6e0b09a Fix output colors 2013-06-18 09:52:44 +02:00
Antonio J. García Lagar a386ffefe3 Fix parent mapping 2013-06-17 21:19:11 +02:00
Lukas Kahwe Smith 9d5a0c2ed9 Merge pull request #318 from RobertPlant/patch-1
Update README.md
2013-06-13 03:15:46 -07:00
RobertPlant fd5ef8005e Update README.md 2013-06-13 11:28:49 +02:00
Jeremy Mikola 7824678e70 Merge pull request #316 2013-06-12 10:48:29 -04:00
RobertPlant c4cc199fbe Document object mapping implications for Doctrine ORM 2013-06-12 10:47:59 -04:00
Jeremy Mikola a9c44b491f Merge pull request #292 2013-06-10 10:37:11 -04:00
Jeremy Mikola b9da709f22 Add documentation for client tagging 2013-06-10 10:37:02 -04:00
Patrick McAndrew 16ecd7cca3 Tag client with fos_elastica.client 2013-06-10 10:30:31 -04:00
Jeremy Mikola 5a64420779 Merge branch '2.1.x'
Conflicts:
	composer.json
2013-06-06 11:21:15 -04:00
Jeremy Mikola 2dfbfffbd0 Update 2.1.x changelog 2013-06-06 11:19:59 -04:00
Jeremy Mikola 692d224b08 Merge branch '2.0.x' into 2.1.x
Conflicts:
	composer.json
2013-06-06 11:18:47 -04:00
Jeremy Mikola cd48a36687 Update 2.0.x changelog 2013-06-06 11:13:12 -04:00
Jeremy Mikola 00e9a49460 Allow Symfony dependencies until 3.0 2013-06-06 11:02:55 -04:00
Richard Fullmer 1fc94b2213 Ignore failed deletions in ObjectPersister
This probably isn't the best way to solve my problem,
but the issue is this.

Step 1:  Create a new doctrine entity for which it's `is_indexable_callback`
returns false.  When doctrine flushes this entity to the database,
elastia will not index it with elastic search.  (Correct)

Step 2:  Update your doctrine entity and change some fields so
that `is_indexable_callback` _still_ returns false.  Persist and flush
to the database.

At this point, the postUpdate listener on ElastiaBundle is called
and since the `is_indexable_callback` returns false, it believes
it needs to remove it from the elastic search index and queues it
for deletion.  The deletion of course fails because it was never there
in the first place.

This solution simply ignores failures from deletions in the index.

Perhaps a better solution would be to have a smarter listener
that could determine if the entity was previously present in the
elastic search index or not, but that would require significant
refactoring.

Addresses issues discuseed in #284

Credit to @bbeaulant for simple solution.  Opening a PR to
discuss more generally.
2013-06-04 11:45:45 -07:00
Jeremy Mikola 94ab3b1d3c Add PSR Log dependency (see: #304) 2013-05-31 13:16:49 -04:00
Jeremy Mikola 00fde6847a Merge pull request #304 from ceednee/master
Fixes Undefined property: FOS\ElasticaBundle\Client::$logger
2013-05-30 13:18:02 -07:00
ceednee 929c1bfc0d Fixes Undefined property: FOS\ElasticaBundle\Client:: 2013-05-30 21:27:31 +02:00
Lukas Kahwe Smith 860a1f8108 Merge pull request #303 from instaclick/logger-patch
update to PSR3 LoggerInterface per change in ruflin/elastica
2013-05-30 09:54:10 -07:00
Anthon Pang 55edceadcb remove redundant property/method 2013-05-30 16:43:10 +00:00
Anthon Pang f374dbbaa2 update to PSR3 LoggerInterface per change in ruflin/elastica 2013-05-30 16:26:16 +00:00
Patrick McAndrew fab42fa0ce Properities should not be required for object as elastica can automap 2013-05-24 12:27:37 +01:00
Lukas Kahwe Smith 43d1531cd4 cs fix 2013-05-23 00:25:38 +03:00
Lukas Kahwe Smith 16edbfa03b Merge pull request #285 from Appstrakt/master
Updated documentation
2013-05-22 12:56:17 -07:00
Lukas Kahwe Smith b7eff37f63 Merge pull request #290 from hacfi/readme_fix
Correct serializer configuration in README
2013-05-22 12:54:32 -07:00
Lukas Kahwe Smith be065735c1 master is 3.0.x 2013-05-22 21:52:48 +02:00
Lukas Kahwe Smith 79327d281c Merge pull request #293 from FriendsOfSymfony/add-path-support
added path support
2013-05-17 00:09:06 -07:00
Lukas Kahwe Smith 50730cca3d added path support, see http://www.elasticsearch.org/guide/reference/mapping/id-field/ 2013-05-17 00:22:46 +02:00
Jeremy Mikola 814460dbf2 Merge branch '2.1.x' 2013-05-15 10:58:47 -05:00
Jeremy Mikola 41c747907c Create 2.1.x changelog 2013-05-15 10:55:30 -05:00
Tim Nagel c05e0caa9c Added documentation for ignoring missing hits 2013-05-15 09:59:52 -05:00
Tim Nagel 00b67fd8a4 Ignore missing index hits 2013-05-15 09:59:43 -05:00
Philipp Wahala d6e8134189 Correct serializer configuration in README 2013-05-15 15:56:21 +02:00
Arne Stockmans 23dfd3f595 Renamed is_indexable_callback_class back to is_indexable_callback 2013-05-08 14:29:22 +02:00
Lukas Kahwe Smith b8a4a47b38 renamed PurgeCommand to ResetCommand 2013-05-08 09:10:40 +02:00
Lukas Kahwe Smith b5392df9fd Merge pull request #280 from FriendsOfSymfony/purge_command
added purge command
2013-05-07 04:54:08 -07:00
Lukas Kahwe Smith f48ae85cc8 added missing use statement 2013-05-06 10:32:50 +02:00
Tim Nagel 4ffc499c66 Saner version constraints 2013-05-03 11:20:44 +10:00
Jeremy Mikola ee6f3cb04d Expect a more specific PropertyAccess exception
RuntimeException is the nearest common ancestor of the PropertyAccessDeniedException (removed in 2.3) and NoSuchPropertyException.

See: symfony/symfony@2a666cb7c3
2013-05-02 11:24:27 -04:00
Jeremy Mikola 64d27c37fa Merge pull request #282 from tommygnr/symfony2.3
Allow symfony >= 2.3
2013-05-02 11:17:50 -04:00
Tom Corrigan b204f5bf5f Allow symfony >= 2.3
This required a small tweak to the tests as
Symfony\Component\PropertyAccess\Exception\PropertyAccessDeniedException
 has been removed in 2.3
2013-05-03 01:01:29 +10:00
Jeremy Mikola be3c2779ef Merge pull request #277 from FriendsOfSymfony/namespace_compat
Compatibility with Elastica 0.20.x (incl. Serializer support)
2013-04-26 16:12:30 -07:00
Lukas Kahwe Smith 813f57e3d0 added purge command 2013-04-26 19:46:15 +02:00
Lukas Kahwe Smith e898deb6df cleanups 2013-04-26 14:12:28 +02:00
Lukas Kahwe Smith c35cb1b25f fixed Elastica dependency 2013-04-26 14:10:06 +02:00
Lukas Kahwe Smith 0af8f6ce19 updated for Elastica master changes 2013-04-26 14:10:06 +02:00
Lukas Kahwe Smith 800e38f8aa tweaked the callback handling 2013-04-26 14:10:06 +02:00
Lukas Kahwe Smith 8a9a9686ba various tweaks 2013-04-26 14:10:05 +02:00
Lukas Kahwe Smith 965ee39c5a typo fix 2013-04-26 14:10:05 +02:00
Lukas Kahwe Smith aafb6e53fb made the bundle compatible with Elastica 0.20.x 2013-04-26 14:10:05 +02:00
Lukas Kahwe Smith d8f836d179 CS fixes and minor tweaks in the Callback class 2013-04-26 14:10:05 +02:00
Lea Haensenberger 1abe1f48dd Having a parameter name defining a class for the serializer callback, because directly putting service id or parameter doesn't work because these values are not available at bundle configuration time 2013-04-26 14:10:05 +02:00
Lea Haensenberger bcf564d09c Adapting readme 2013-04-26 14:09:42 +02:00
Lea Haensenberger a139d18b22 Adding default callback for serialization if serialization is turned on 2013-04-26 14:09:42 +02:00
Lea Haensenberger c99eee9c4b Adding some documentation 2013-04-26 14:06:50 +02:00
Lea Haensenberger 73fd4fe6b0 Creating a serializer callable for every type in an index and passing it to elastica 2013-04-26 14:06:49 +02:00
Lea Haensenberger c5ee26099b Adding support to pass a serializer to elastica 2013-04-26 14:06:48 +02:00
Jeremy Mikola a161b0657a Merge branch '2.0.x' 2013-04-17 11:23:58 -04:00
Thomas Tourlourat 4b4a56db1e Check for "indexes" key in Configuration::getNestings() 2013-04-17 11:23:30 -04:00
Jeremy Mikola 7e79fa6f35 Merge branch '2.0.x' 2013-04-16 13:27:46 -04:00
Jeremy Mikola 8ffd1a7c3d Update install version and add links to compatibility info 2013-04-16 13:26:14 -04:00
Jeremy Mikola b5037d1c77 Merge branch '2.0.x' 2013-04-16 13:19:50 -04:00
Jeremy Mikola 36e38cb576 Merge branch '1.0.x' into 2.0.x 2013-04-16 13:17:39 -04:00
Jeremy Mikola c24a647a43 Merge pull request #267 from XWB/collector-update
Collector: print query data as json instead of yaml
2013-04-10 12:39:04 -07:00
Jeremy Mikola ae4f676c25 Create 2.1.x-dev branch alias for master 2013-04-05 13:38:03 -04:00
Jeremy Mikola 8e03ed2663 Merge pull request #266 from XWB/property-access-update
Use the PropertyAccess component
2013-04-05 10:26:57 -07:00
Karel Souffriau 4f5be038ef Collector: print query data as json instead of yaml 2013-04-05 13:17:00 +02:00
Karel Souffriau 83e27ede93 Require PropertyAccess component 2013-04-04 21:51:03 +02:00
Jeremy Mikola e82b6e983f Create 2.0.x changelog 2013-04-04 11:46:06 -04:00
Jeremy Mikola 55920a3397 Merge branch '1.0.x' into 2.0.x 2013-03-28 16:36:46 -04:00
Jeremy Mikola 8c3863bb5f Merge branch 'pr/262' into 2.0.x 2013-03-28 13:53:16 -04:00
Jeremy Mikola c99f0458df Merge branch '1.0.x' into 2.0.x 2013-03-28 13:52:58 -04:00
Jeremy Mikola 89284df831 Revert "Provide branch alias for 2.0"
This reverts commit 920f16965f.
2013-03-28 13:52:48 -04:00
ShurtMaiden 1f26318875 Avoid using a feature not supported in PHP5.3 2013-03-28 12:15:02 +01:00
Tim Nagel 920f16965f Provide branch alias for 2.0 2013-03-28 11:24:11 +11:00
Jeremy Mikola 8146f8e9ab Merge pull request #255 from FriendsOfSymfony/property-access
Support Symfony 2.2 PropertyAccess with BC for 2.1 (closes #218)
2013-03-27 14:33:45 -07:00
Jeremy Mikola 2e7d2f2452 Support Symfony 2.2 PropertyAccess with BC for 2.1 (closes #218)
By abstracting the property access, we can easily support Symfony 2.1's Form component and 2.2's PropertyAccess component.

The PropertyAccessor service will be injected into transformers if it is available. Tests were modified to do the same, and expect the appropriate exception depending on which implementation is available.
2013-03-27 17:26:47 -04:00
Jeremy Mikola 91090ed37a Fix pagerfanta dependecy 2013-03-27 15:00:54 -04:00
Jeremy Mikola 440c36f537 Merge remote-tracking branch 'cevou/master' into pr/245
Conflicts:
	Command/PopulateCommand.php
	Command/SearchCommand.php
	DependencyInjection/Configuration.php
	Doctrine/AbstractElasticaToModelTransformer.php
	Doctrine/AbstractListener.php
	Doctrine/MongoDB/ElasticaToModelTransformer.php
	Doctrine/ORM/ElasticaToModelTransformer.php
	Doctrine/RepositoryManager.php
	Finder/TransformedFinder.php
	Paginator/PaginatorAdapterInterface.php
	Paginator/RawPaginatorAdapter.php
	Persister/ObjectPersister.php
	Propel/ElasticaToModelTransformer.php
	Subscriber/PaginateElasticaQuerySubscriber.php
	Tests/DataCollector/ElasticaDataCollectorTest.php
	Tests/Doctrine/AbstractProviderTest.php
	Tests/Doctrine/RepositoryManagerTest.php
	Tests/Manager/RepositoryManagerTest.php
	Tests/RepositoryTest.php
	Transformer/ElasticaToModelTransformerCollection.php
	composer.json
2013-03-27 14:58:34 -04:00
Jeremy Mikola cf4cc7f578 Require Symfony 2.1.x 2013-03-27 14:33:30 -04:00
Jeremy Mikola 744f05814a Merge branch '1.0.x' 2013-03-27 13:58:57 -04:00
Jeremy Mikola a7b37f3c41 Merge branch '1.0.x'
Conflicts:
	Command/PopulateCommand.php
	Command/SearchCommand.php
	DependencyInjection/Compiler/AddProviderPass.php
	DependencyInjection/FOQElasticaExtension.php
	Doctrine/AbstractListener.php
	Doctrine/AbstractProvider.php
	Doctrine/MongoDB/Listener.php
	Doctrine/MongoDB/Provider.php
	Doctrine/ORM/Listener.php
	Doctrine/ORM/Provider.php
	FOQElasticaBundle.php
	Finder/TransformedFinder.php
	IndexManager.php
	MappingRegistry.php
	Paginator/AbstractPaginatorAdapter.php
	Paginator/RawPaginatorAdapter.php
	Paginator/TransformedPaginatorAdapter.php
	Populator.php
	Propel/Provider.php
	Provider/ProviderInterface.php
	README.md
	Repository.php
	Reseter.php
	Resources/config/config.xml
	Resources/config/mongodb.xml
	Resources/config/orm.xml
	Resources/config/propel.xml
	Tests/Doctrine/MongoDB/ListenerTest.php
	Tests/Doctrine/ORM/ListenerTest.php
	Tests/IndexManagerTest.php
	Tests/MappingRegistryTest.php
	Tests/PopulatorTest.php
	Tests/ReseterTest.php
	Transformer/ElasticaToModelTransformerCollection.php
2013-03-27 13:57:39 -04:00
Jeremy Mikola 3fb9aaa56a Rename FOQ namespaces and services to FOS 2013-03-27 13:44:06 -04:00
Jeremy Mikola 4e11e20071 Merge branch '2.0'
Conflicts:
	.travis.yml
	composer.json
2013-03-15 15:24:43 -04:00
Stanislav Petrov 3f93f93a45 Changed configuration to implement ConfigurationInterface 2013-03-15 14:54:48 -04:00
skuro 904a664dfe Allow processing of null mappings in configuration 2013-03-15 14:35:01 -04:00
Jeremy Mikola b12b92845c Merge branch '2.0' 2013-03-07 17:54:21 -05:00
Jeremy Mikola 8f5f12315d Merge branch '2.0'
Conflicts:
	Transformer/ModelToElasticaAutoTransformer.php
2013-03-07 17:38:42 -05:00
Jeremy Mikola 7f3e3919e7 Merge pull request #248 from kostiklv/missing-field-options
Added missing string field attributes
2013-03-07 13:56:03 -08:00
Konstantin Tjuterev 5e835f5b2c Added missing string field attributes, according to http://www.elasticsearch.org/guide/reference/mapping/core-types.html 2013-03-05 15:06:11 +02:00
cevou b03ee7cc76 Removed property path changes again 2013-03-04 21:20:55 +01:00
Jeremy Mikola 8d11082a02 Skip config processing of indexes without types (fixes #246) 2013-03-04 14:59:04 -05:00
Jeremy Mikola eff52c2c9b Revert "fix search command"
This reverts commit f874e1d34f from PR #243.
2013-03-04 14:57:08 -05:00
cevou cbe6071969 Code cleanup
- updated deprecated calls
- cleaned up PHPDoc comments
2013-03-02 12:23:44 +01:00
Jeremy Mikola dea32f9b56 Merge pull request #243 from uehondor/fix-search-command
fix search command
2013-02-26 12:58:59 -08:00
Uyi Ehondor f874e1d34f fix search command
The bug:
The Search command throws an invalid argument exception when the index
alias and the index_name are different (see pull request 207 for a
background about the issue).

Fix:
The first argument of the index manager should be an array of index
objects having index names as keys, and should only fall back to using index aliases
if the index_name config param is not set.

See: pull request 207
(https://github.com/Exercise/FOQElasticaBundle/pull/207) for a background
on the issue.
2013-02-26 10:50:33 +00:00
Jeremy Mikola 423576638a Merge pull request #210 from liip-forks/recursive_field_config
Adding support for infinite nesting level in field configurations
2013-02-25 07:55:06 -08:00
Jeremy Mikola 3ea70afd7e Merge pull request #241 from nurikabe/patch-1
Fix odd grammar
2013-02-22 11:27:58 -08:00
Evan Owens 1992d6f0d6 Fix odd grammar 2013-02-22 14:03:40 -05:00
Lea Haensenberger 7e85f79f8e Merge remote-tracking branch 'origin/master' into recursive_field_config
Conflicts:
	DependencyInjection/Configuration.php
2013-02-22 10:46:43 +01:00
Jeremy Mikola 737b73b947 Merge pull request #240 from tyx/dev/query-time-debugbar
Query time in debugbar
2013-02-21 09:44:26 -08:00
tyx f66858ff3e Add test for the query time in datacollector 2013-02-21 10:52:49 +01:00
tyx 9c60a5ccac Add totalquery time in debugbar (like Doctrine does) 2013-02-21 10:37:04 +01:00
Jeremy Mikola 2171755e5a Merge pull request #231 from marcoleong/patch-1
The finder was not created in that section
2013-02-11 12:51:52 -08:00
Marco Leong 6995d75dc8 The finder was not created in that section
The finder was not created in that section, use repository instead, make more sense for user
2013-02-07 17:12:38 +08:00
Richard Miller 48d665e2ea Merge pull request #211 from liip-forks/fields_in_properties
Adding the fields configuration to the properties so multi_field fields ...
2013-02-03 11:49:51 -08:00
Richard Miller c82999fd8e Merge pull request #204 from micjohnson/patch-4
Add access to compression and disabling of _source from configuration
2013-02-03 11:45:37 -08:00
Richard Miller bfb0f823c1 Merge pull request #203 from micjohnson/patch-3
Adding _routing to type configuration
2013-02-03 11:44:51 -08:00
Richard Miller ef869be10b Update README.md
Adding details of the ```index_name``` config
2013-02-03 19:38:53 +00:00
Richard Miller 94d89159bd Merge pull request #207 from Exercise/index-aliasing
Adding configuring index name separately from service name
2013-02-03 11:32:37 -08:00
Richard Miller 76a3339e16 Merge pull request #216 from daFish/fix/issue-213
Fixes problem with potential null values coming from nested properties.
2013-02-03 11:23:44 -08:00
Richard Miller c73a151115 Merge pull request #219 from megazoll/dev-deps
Updated dev deps
2013-02-03 11:21:15 -08:00
Lea Haensenberger 71ccacc6b3 using getConfiguration and removing unnecessary end statements 2013-02-01 15:37:57 +01:00
Lea Haensenberger decd8a318d fixing CS problems 2013-02-01 14:55:59 +01:00
Jeremy Mikola 3cfa2c1ef6 Merge pull request #192 from kibao/fix-custom-finder
Fix register custom finder for entity
2013-01-30 13:44:27 -08:00
Przemysław Piechota 10ce9a6d0a CS 2013-01-30 22:24:19 +01:00
Lea Haensenberger 6e62d41d06 Merge remote-tracking branch 'origin/master' into recursive_field_config 2013-01-28 12:08:19 +01:00
Lea Haensenberger 02f3281a7a Fixing wrong default value 2013-01-28 11:55:54 +01:00
Lea Haensenberger 869b8b734e Using the config array to determine the needed nesting levels, building the config tree based on that 2013-01-28 11:53:50 +01:00
Vyacheslav Salakhutdinov e9be67d59b Updated dev deps 2013-01-25 14:59:24 +04:00
daFish 82ec81cb08 Fixes problem with potential null values coming from nested properties. 2013-01-24 16:43:10 +01:00
Richard Miller f7e697aacf Merge pull request #215 from daFish/fix/configuration
Added missing ~ to all configuration parameters.
2013-01-24 06:24:24 -08:00
daFish 6ff09f8cc1 Added missing ~ to all configuration parameters. 2013-01-24 14:53:28 +01:00
Lea Haensenberger 4055ff305f Adding the fields configuration to the properties so multi_field fields can also be defined in properties 2013-01-10 15:00:21 +01:00
Lea Haensenberger 2119a4b39f Adding support for infinite nesting level in field configurations 2013-01-10 12:25:34 +01:00
Richard Miller 93236752c4 Adding configuring index name separately from service name 2013-01-04 14:02:50 +00:00
micjohnson b2314f21c6 Update DependencyInjection/Configuration.php
add access to compression and disabling of _source
2012-12-12 07:49:37 -08:00
micjohnson d9367c7ed8 Update DependencyInjection/FOQElasticaExtension.php 2012-12-12 06:25:55 -08:00
micjohnson ea921c8abe Update DependencyInjection/Configuration.php
Adding _routing for types
2012-12-12 06:23:54 -08:00
Jeremy Mikola 973d67f0c1 Merge pull request #161 from NicolasBadey/patch-1
Update composer.json
2012-12-05 09:50:24 -08:00
NicolasBadey ab84d89eb7 rebase upstream 2012-12-05 17:28:34 +01:00
Richard Miller 04ddfcce43 Merge pull request #197 from craigmarvelley/allow-multi-field-type
Remove exception when multi_field type is used
2012-11-30 05:39:43 -08:00
craig 7717d4d580 Remove exception when multi_field type is used 2012-11-29 14:32:47 +00:00
Richard Miller 9b5c26d3e3 Merge pull request #196 from daFish/fix/undefinedindex
Fixes undefined index error when populating index
2012-11-29 01:32:22 -08:00
daFish e5fef260f2 Changed servers to numeric indexes instead of associative indexes 2012-11-29 10:00:51 +01:00
Richard Miller 1bcc518b31 Merge pull request #191 from odolbeau/feat-nodes
Allow multiple servers in configuration
2012-11-28 13:19:01 -08:00
Richard Miller 5ea8bb9688 Merge branch 'master' of github.com:Exercise/FOQElasticaBundle 2012-11-28 21:17:20 +00:00
Richard Miller 8fde6b235c Merge branch '2.0'
Conflicts:
	Transformer/ElasticaToModelTransformerCollection.php
2012-11-28 21:15:13 +00:00
Richard Miller 62b28a813e Merge remote-tracking branch 'cup-of-giraf/nested'
Conflicts:
	DependencyInjection/Configuration.php
2012-11-28 21:13:04 +00:00
Richard Miller 7d90c1fdc1 Merge pull request #190 from daFish/feature/symfony22
Added support for Symfony 2.2 to composer.json
2012-11-28 12:54:20 -08:00
Richard Miller 9b2dc40bc1 Merge pull request #172 from kostiklv/properties-mapping
Support for properties of objects/nested documents
2012-11-28 12:49:14 -08:00
Julien Muetton 79eb062cf7 add _parent in mapping during index reset 2012-11-28 12:07:09 +01:00
Julien Muetton 10eae2f254 fixes php5.3 defines ~ for default empty _parent property 2012-11-26 16:04:50 +01:00
Julien Muetton a36ec87f40 Add tests for _parent, nested and object types 2012-11-26 14:47:08 +01:00
Julien Muetton ea3191033f add documentation for nested, object and _parent 2012-11-26 13:55:48 +01:00
Julien Muetton 23f591bf01 allow _parent mapping 2012-11-26 13:50:14 +01:00
Julien Muetton a901304a59 remove trailing whitespace 2012-11-26 13:49:59 +01:00
Julien Muetton 5c8dd9b7a6 Transformer transforms nested documents 2012-11-22 14:35:01 +01:00
Julien Muetton 679480e496 add ability to configure nested mapping
``` yaml
foq_elastica:
    clients:
        default: { host: localhost, port: 9200 }
    indexes:
        website:
            client: default
            types:
                product:
                    mappings:
                        name: { type: string }
                        price: { type: float}
                        specifications:
                            type: object
                            properties:
                                name: {type: string}
                                value: {type: string, analyzer: keyword}
```
2012-11-22 14:33:49 +01:00
Przemysław Piechota e2cc4f965b Fix register custom finder for entity 2012-11-22 11:30:13 +01:00
daFish e6bfda8e80 Added support for Symfony 2.2 to composer.json 2012-11-18 20:30:51 +01:00
Olivier Dolbeau 58eaf6b03e Allow multiple servers in configuration 2012-11-05 11:00:27 +01:00
Jeremy Mikola 193ca3848b Merge pull request #176 from Fran6co/fix-index-property
adds to the config the index parameter
2012-11-04 22:24:28 -08:00
Francisco Facioni f4c0a4abda adds to the config the index parameter, needed for disabling the analyzer or the indexing 2012-10-15 17:18:04 -03:00
Jeremy Mikola 7bee84e2fa Merge branch '2.0' 2012-10-03 10:49:05 -04:00
Ad van der Veer d49c530c55 Updated the DoctrineMongoDB event subscriber tag 2012-10-01 15:46:02 -04:00
Konstantin Tjuterev e35134b780 Added configuration mapping for properties key, allows configuing mapping for objects/nested documents 2012-10-01 15:36:54 +03:00
Richard Miller afe5369e05 Merge pull request #164 from matteosister/command-color-output
colorized output for the foq:elastica:populate command
2012-09-24 15:36:57 -07:00
Richard Miller 46804a32c8 Merge pull request #158 from yoye/master
Update total hits count when paginate with filters
2012-09-24 15:25:05 -07:00
Richard Miller b376f2ca80 Merge pull request #150 from predakanga/add-index-boost
Added support for index-time document boosting
2012-09-24 15:23:02 -07:00
matteosister 23c96510d8 colorized output for the foq:elastica:populate command 2012-09-19 14:33:16 +02:00
Nicolas Badey 1f2fd479e3 Update composer.json
new version fix some issues ( _count with query filtered )
2012-08-30 12:41:32 +03:00
yoye 41b024925b Update Paginator/RawPaginatorAdapter.php 2012-08-24 12:23:10 +03:00
yoye dd5c5c321a Fix total hits count when adding filters 2012-08-24 12:17:07 +03:00
Jeremy Mikola 5d1f4f2d68 Merge pull request #155 from ChrisTickner/mongodb_service_ids
Updated the DoctrineMongoDBBundle service IDs
2012-08-17 10:56:24 -07:00
Chris Tickner fcb9e8f2f5 Updated the DoctrineMongoDBBundle service IDs
The service IDs for the DoctrineMongoDBBundle have changed for version 2.1.  This is an update to reflect that change.

https://github.com/doctrine/DoctrineMongoDBBundle/pull/134
2012-08-15 08:45:43 -03:00
Jeremy Mikola af468837a4 Merge branch '2.0' 2012-08-14 11:20:38 -04:00
Richard Miller ce5223f85d Updated test to reflect change in IndexManager constrcutor arguments 2012-08-14 10:04:20 +01:00
Richard Miller 2e3d67fdc7 Corrected spelling in README 2012-08-14 10:51:26 +02:00
Richard Miller 20a58c502c Merge pull request #151 from geecu/fix_search_command
fix search command when no index option is passed
2012-08-10 02:26:14 -07:00
Richard Miller 14fcc5faa1 Merge pull request #149 from predakanga/fix-search-command
Fixed SearchCommand's index option
2012-08-10 02:13:22 -07:00
Gunther Konig 3cdfcf1cea fix search command when no index option is passed 2012-08-10 11:40:01 +03:00
predakanga 70c629f857 Added configuration options to support index-time document boosting 2012-08-09 13:49:04 +10:00
predakanga 049e0da481 Fixed SearchCommand's index option 2012-08-09 12:06:50 +10:00
Richard Miller 67a11a59ce Merge branch '2.0'
Conflicts:
	Finder/FinderInterface.php
	Repository.php
2012-08-07 19:42:38 +01:00
Richard Miller b05af88931 Merge branch '2.0'
Conflicts:
	Doctrine/AbstractElasticaToModelTransformer.php
2012-08-07 19:14:16 +01:00
Richard Miller af8f5f1ecc Merge branch '2.0'
Conflicts:
	README.md
2012-08-06 23:32:09 +01:00
Richard Miller 0505cb55f2 Merge branch '2.0'
Conflicts:
	Finder/RawFinder.php
2012-08-06 23:13:43 +01:00
Richard Miller e269e14b10 Merge pull request #145 from Schyzophrenic/master
Fix resultSet size when using a Repository for master
2012-08-06 15:01:38 -07:00
Schyzophrenic 3b391919c9 Fix resultSet size when using a Repository
When using a Repository, the $limit parameter was lost along the way.
This is why the limit was always set to 10 in that case.
2012-08-05 02:43:52 +03:00
Richard Miller 123da22ebd Merge remote-tracking branch 'Fran6co/imp-lat_lon'
Conflicts:
	DependencyInjection/Configuration.php
2012-08-02 14:54:49 +01:00
Richard Miller 8ca25641f8 Merge pull request #139 from Fran6co/fix-paginator
fix for #138, query can be a string or a Elastica_Query
2012-08-02 06:12:45 -07:00
Richard Miller 3b4b91729f Merge pull request #141 from korstiaan/patch-1
Moved `identifier` to `persistence` in README
2012-08-02 06:11:41 -07:00
Richard Miller d7980bc419 Added installing mongo extension to travis config 2012-08-02 14:09:20 +01:00
Richard Miller f0c4cb23e3 Merge pull request #142 from korstiaan/include_in_all
Added `include_in_all` as mapping property
2012-08-02 05:56:18 -07:00
Korstiaan de Ridder dbf0e27386 Added include_in_all as mapping property 2012-08-01 13:52:08 +02:00
Korstiaan de Ridder 83cfd59902 Moved identifier to persistence in README
`identifier` config var is child of `persistence` root, and not `provider`
2012-07-31 17:36:32 +03:00
Francisco Facioni 0ede5ffc67 fix for #138, query can be a string or a Elastica_Query 2012-07-27 15:06:00 -03:00
Francisco Facioni f58cf6e63c adds support for lat_lon flag as specified in http://www.elasticsearch.org/guide/reference/mapping/geo-point-type.html 2012-07-25 18:29:35 -03:00
Richard Miller c7e0e88ece Merge branch '2.0'
Conflicts:
	composer.json
2012-07-10 22:50:04 +01:00
Richard Miller 16ab1481d2 Merge branch '2.0' 2012-07-10 21:38:42 +01:00
Richard Miller 2732296aed Merge branch '2.0'
Conflicts:
	Doctrine/AbstractElasticaToModelTransformer.php
	Doctrine/MongoDB/ElasticaToModelTransformer.php
	Doctrine/ORM/ElasticaToModelTransformer.php
	composer.json
2012-07-10 21:37:23 +01:00
Richard Miller affc50a2eb Added type hint to Repository constructor 2012-07-10 20:41:27 +01:00
Richard Miller 3d2252a688 Changed finder interface hierarchy 2012-07-10 20:38:08 +01:00
Richard Miller 76f583324e Converted indentation to spaces 2012-07-10 20:32:45 +01:00
Richard Miller 50ba50f848 Added findHybrid to the repository 2012-07-10 20:30:19 +01:00
Richard Miller 886ffbe279 Merge pull request #132 from Fran6co/imp-add-paginator-repository
adds createPaginatorAdapter to the repository
2012-07-10 12:18:06 -07:00
Francisco Facioni b7df8fb651 adds createPaginatorAdapter to the repository 2012-07-10 13:16:44 -03:00
Richard Miller 7a8664727c Merge remote-tracking branch 'origin/attachment_type_transformation'
Conflicts:
	Tests/Transformer/ModelToElasticaAutoTransformerTest.php
	Transformer/ModelToElasticaAutoTransformer.php
2012-07-08 15:38:09 +01:00
Richard Miller a787dcbe53 Merge pull request #119 from Fran6co/imp-knp-paginatior
Added knp paginator support
2012-07-08 06:59:54 -07:00
Richard Miller aa611605b6 Updated test to reflect changes in the way properties are accessed in the transformer 2012-07-08 14:31:19 +01:00
Richard Miller e37d22c220 Added minimum-stability to composer.json 2012-07-08 14:22:39 +01:00
Richard Miller c0cf0b921c Merge pull request #131 from Fran6co/fix-reset
Bugfix: missing 'parameters' is causing 'MapperParsingException' when resetting index
2012-07-08 05:35:21 -07:00
Francisco Facioni 4f26eb6e21 Updated Test to reflect actual configuration case (this bundle is using arrays instead of Elastica_Type_Mapping) 2012-07-02 10:00:40 -03:00
Francisco Facioni a6ca1bec7c Bugfix: missing 'parameters' was causing 'MapperParsingException' when resetting index 2012-06-29 13:05:18 -03:00
Jeremy Mikola 765d875d86 Merge pull request #113 from Fran6co/fix-propertypath
Using PropertyPath for resolving what getter to use
2012-06-14 07:43:45 -07:00
Richard Miller b721e86412 Merge pull request #126 from geoffrey-brier/master
Fixed missing argument concerning the foq:elastica:populate command
2012-06-14 04:55:10 -07:00
Geoffrey Brier 9dd4943af7 Fixed missing argument concerning the foq:elastica:populate command 2012-06-14 13:36:48 +02:00
Francisco Facioni 59bf8a1efd More CS 2012-06-13 15:40:27 -03:00
Francisco Facioni 2bf7344fbb CS 2012-06-13 15:28:16 -03:00
Francisco Facioni 33397ec467 Added to the documentation how to paginate with knp paginator 2012-06-13 13:40:41 -03:00
Richard Miller d0085057d5 Fixed modifier issue in Test 2012-06-13 17:22:13 +01:00
Richard Miller 835087eff1 Merge remote-tracking branch 'miguelibero/master' 2012-06-13 17:21:08 +01:00
Richard Miller 7455145511 Merge remote-tracking branch 'Fran6co/fix-missing-configuration' 2012-06-13 17:19:46 +01:00
Richard Miller 9f3b3daea2 Merge branch '2.0'
Conflicts:
	Command/PopulateCommand.php
2012-06-13 17:08:08 +01:00
Richard Miller c62822712c Merge branch 'master' of github.com:Exercise/FOQElasticaBundle 2012-06-13 16:53:13 +01:00
Richard Miller abe282550e Tidying up no-reset option for populate command 2012-06-13 16:52:34 +01:00
Richard Miller f63a71a492 Merge remote-tracking branch 'pdaether2/master' 2012-06-13 16:40:20 +01:00
Richard Miller c0ae2c870f Merge pull request #120 from lavoiesl/master
Changed ObjectPersiter::transformToElasticaDocument from protected to public to allow usage as a converter service
2012-06-13 08:34:48 -07:00
Sébastien Lavoie 408b7aeebe Changed ObjectPersiter::transformToElasticaDocument from protected to public to allow usage as a converter service 2012-05-29 14:28:20 -04:00
Miguel Ibero 0c02025e51 Merge branch 'master' of git://github.com/Exercise/FOQElasticaBundle 2012-05-24 20:14:01 +02:00
Miguel Ibero f69e969898 fixed for consistency 2012-05-24 20:13:58 +02:00
Francisco Facioni 0d9e0f1172 Added knp paginator support
Bug fix: no
Feature addition: yes
Backwards compatibility break: no

Encapsulated Pagerfanta dependency for pagination and added support for knp pagination component
2012-05-24 11:35:19 -03:00
Francisco Facioni 5bea4da409 added index_analyzer and search_analyzer for type fields 2012-05-23 14:42:28 -03:00
Francisco Facioni d5778bda4b Added composer dependency to symfony/form 2012-05-21 15:00:56 -03:00
Jeremy Mikola 2b858f0e42 Merge pull request #114 from willdurand/update-wdt-view
Updated collector view to fit the new WDT
2012-05-21 10:49:13 -07:00
William DURAND 303e48c8c6 Updated collector view to fit the new WDT 2012-05-21 10:09:58 +02:00
Francisco Facioni 08b4095687 Using PropertyPath for resolving what getter to use 2012-05-20 23:57:51 -03:00
Miguel Ibero ae80e3e4f3 added index_analyzer and search_analyzer type options 2012-05-17 13:00:53 +02:00
pdaether 486e78f3ee New Option no-reset for the populate command 2012-05-07 18:10:26 +02:00
William DURAND 836481aff7 [Propel] Added new method to return a query to use in
findByIdentifiers().

That way, it's easier to override the default ElasticaToModelTransformer
class.
2012-05-07 15:07:56 +02:00
Richard Miller 5a28372abf Merge branch '2.0' 2012-05-05 17:02:34 +01:00
Richard Miller bb57c84aff Merge pull request #98 from nurikabe/patch-1
Throw RuntimeException when all Elastica objects cannot be found via Doctrine
2012-05-05 08:56:04 -07:00
Richard Miller a741ea804b Merge pull request #106 from willdurand/public-persister-services
Made persister services public to use them
2012-05-05 08:54:53 -07:00
Richard Miller 99c1826d6d Merge pull request #103 from Fran6co/fix-transformer
Fixed bug when a transformer returns objects of different classes
2012-05-05 08:54:10 -07:00
William DURAND effd3583a4 Made persister services public to use them 2012-05-04 16:54:02 +02:00
fran6co cb20c4015e Minor improvement, using an intermediate variable to hold the transformed objects 2012-05-04 11:05:57 -03:00
Richard Miller 5834643d46 Merge branch '2.0'
Conflicts:
	composer.json
2012-05-04 12:23:06 +01:00
fran6co 1c1c33d327 Fixed bug when a transformer returns objects of different classes.\n The doctrine transformer can generate this kind of situations whene it returns proxy objects. 2012-05-02 23:06:41 -03:00
Richard Miller cbef5ac26d Merge remote-tracking branch 'origin/2.0' 2012-05-02 09:17:48 +01:00
Richard Miller 123816795a Update Elastica version required in composer.json 2012-05-02 10:08:48 +02:00
Richard Miller 77961ffcd9 Merge pull request #101 from leek/patch-1
Updating break from `v0.19.3.0`
2012-05-02 01:04:02 -07:00
Chris Jones a8fcfbbb1e Updating break from v0.19.3.0 2012-05-01 19:06:28 -03:00
Richard Miller 38d863e3ff Added tests attachment fixture 2012-05-01 20:09:04 +01:00
Richard Miller 146cf891cd Added transforming mapped attachments 2012-04-19 21:26:19 +01:00
Jeremy Mikola 38bdc44185 Support service ID's and class names in is_indexable_callback 2012-04-19 12:18:30 -04:00
Jeremy Mikola 3ec4a48484 Allow variable types for is_indexable_callback options
Actual checking (string, array callback or Closure) is done in the Listener class itself.
2012-04-19 11:43:35 -04:00
nurikabe 4b30686359 Somewhat clearer exception when Elastica results do not match Doctrine objects. Consistent behavior for both transform() and hybrdidTrasnform(). 2012-04-19 15:05:18 +01:00
nurikabe ccc920d46b Throw a more meaningful error when the number of items retrieved by Doctrine is less than the number of items from ElasticSearch. 2012-04-18 14:39:32 -03:00
Jeremy Mikola a39170060f Document arguments passed to is_indexable_callback 2012-04-17 13:43:18 -03:00
Jeremy Mikola 5f5ee8a15d Merge branch '2.0' 2012-04-17 12:21:11 -04:00
Jeremy Mikola 3b715f2fdd Merge pull request #93 from Exercise/listener-check-method
Listener check method
2012-04-17 08:00:54 -07:00
Jeremy Mikola a15dd2a411 [Listener] Revise is_indexable_callback documentation 2012-04-16 12:45:10 -04:00
Jeremy Mikola 86cdaa7c3c [Listener] Support additional indexable callback types
Support service/method tuples as indexable callbacks. Closures are also supported, although they cannot be injected by the service container.

The indexable callback is now injected via a setter and validated when set (instead of during event processing).
2012-04-16 12:30:30 -04:00
Jeremy Mikola 78a36c196d [Listener] Use common AbstractListenerTest for ORM and MongoDB ODM 2012-04-16 12:29:25 -04:00
Jeremy Mikola 9613392e8b Merge branch '2.0'
Conflicts:
	Command/PopulateCommand.php
2012-04-10 17:54:52 -04:00
r1pp3rj4ck 0f46f4b96d [Listener] Allow conditional indexing based on callback method
Added optional is_indexable_callback config param to persistence. If this is a method on the entity, the listener will only process it if the method returns true. Also updated documentation.
2012-04-10 14:36:25 -04:00
Jeremy Mikola 3863b2dba8 Merge pull request #92 from Exercise/suggested-deps
Add suggested Doctrine and Propel deps for test suite coverage
2012-04-10 11:35:41 -07:00
Jeremy Mikola 22789c1b01 Add suggested Doctrine and Propel deps for test suite coverage 2012-04-10 14:35:08 -04:00
Jeremy Mikola 24ca952d46 Update service tag for Doctrine MongoDB ODM listeners
See: doctrine/DoctrineMongoDBBundle#80
2012-03-23 15:02:00 -04:00
Jeremy Mikola 661c324e43 Merge pull request #80 from Exercise/repopulate-index
Allow single indexes and types to be repopulated
2012-03-13 10:48:07 -07:00
Jeremy Mikola 23cfb31651 Update documentation for custom provider services 2012-03-13 13:44:49 -04:00
Jeremy Mikola 15bcca4e7e Fix documentation for persistence "identifier" option 2012-03-13 13:42:27 -04:00
Jeremy Mikola f559700766 Fix typo in Doctrine/AbstractProviderTest 2012-03-12 14:13:54 -04:00
Jeremy Mikola 02f162fd79 Update Elastica dependency for Resetter changes
Resetter depends on Elastica_Type::delete(), which was a recent addition to Elastica. See: af6c92b92e5374f92323a65cb6ea957b74fcb1dd
2012-03-12 12:08:53 -04:00
Jeremy Mikola 4a80e27283 Enable PopulateCommand to target indexes and types
This makes the Populator service obsolete.
2012-03-12 12:07:51 -04:00
Jeremy Mikola 2046748516 [Provider] Lazy-loaded provider services must have public definitions
If provider definitions are not public, they will be removed by RemoveUnusedDefinitionsPass when compiling the container.
2012-03-12 12:07:51 -04:00
Jeremy Mikola 118900120b [Provider] ProviderRegistry should return indexed provider arrays
Since Provider instances do not know the index or type for which they are responsible, it's helpful for the ProviderRegistry to include that information when returning multiple providers.
2012-03-12 12:07:51 -04:00
Jeremy Mikola e09225eb09 [Provider] Change provider construction (possible BC break)
* Created AbstractProvider class (for all DB services), which handles the default batch_size option.
 * The logger Closure is now optional for populate().
 * Removed unused Elastica_Type argument from Provider constructors.
 * Added unit tests for Doctrine's AbstractProvider class.
 * The extra argument (ManagerRegistry) for Doctrine providers is now an appended constructor argument, so the extension no longer needs to use different replacement indexes for Propel/Doctrine providers.
2012-03-12 12:07:51 -04:00
Jeremy Mikola 89a368ae35 Allow Resetter to target specific indexes and types (BC break)
The original reset() method is now resetAllIndexes(). Additionally, new resetIndex() and resetIndexType() methods were introduced.
2012-03-12 12:07:51 -04:00
Jeremy Mikola 2d2e209373 Remove obsolete MappingRegistry class 2012-03-12 12:07:51 -04:00
Jeremy Mikola b360a36737 [Provider] Create ProviderRegistry service (BC break)
This introduces a registry service for persistence providers.

Previously, tagging one or more provider services would cause AddProviderPass to clobber the default providers created by the bundle's extension class. Now, the extension class tags its created providers and allows them to be registered via RegisterProvidersPass just like custom providers.

BC break: Custom providers tagged "foq_elastica.provider" must now specify a "type" attribute on their tag. An "index" attribute is optional (the default ES index will be used by default).
2012-03-12 12:07:51 -04:00
Jeremy Mikola 43eda480c5 Rename "reseter" to "Resetter" (BC break) 2012-03-12 12:07:51 -04:00
Jeremy Mikola d3a2335a55 Refactor IndexManager construction (preserves API)
Provide the default index name rather than the service itself. Additionally, inject references to each index by name instead of the definitions.
2012-03-12 12:07:51 -04:00
Jeremy Mikola 494b73a860 [Command] Refactor foq:elastica:search configuration 2012-03-12 12:07:51 -04:00
Richard Miller 9046d4d137 Merge branch '2.0' 2012-03-08 12:50:13 +00:00
Richard Miller 41f18a47af Merge branch '2.0'
Conflicts:
	composer.json
2012-03-07 10:20:24 +00:00
Jeremy Mikola b60256e8fd Merge branch '2.0' 2012-03-06 20:34:30 -05:00
Jeremy Mikola 3eb923cc84 Skip Doctrine tests if libraries are not available 2012-03-06 20:22:34 -05:00
Jeremy Mikola ebeff1aae4 Update composer.json to require Symfony 2.1 2012-03-03 22:48:22 -05:00
Jeremy Mikola b7d7017381 Merge branch '2.0' 2012-03-03 22:48:10 -05:00
Richard Miller 3e50cc95b5 Merge branch '2.0' 2012-02-27 20:13:39 +00:00
Jeremy Mikola 7a9255a9ed Merge remote-tracking branch 'origin/2.0' 2012-02-25 17:41:18 -05:00
Richard Miller 86e5afc469 Merge branch '2.0' 2012-02-24 09:51:51 +00:00
Richard Miller d67cd8f9ba Merge remote-tracking branch 'origin/2.0' 2012-02-03 12:40:42 +00:00
Richard Miller 9a6ce35fb6 Merge branch '2.0' 2012-01-25 14:16:10 +00:00
Richard Miller 38f31eca3c Merge branch '2.0'
Conflicts:
	DependencyInjection/FOQElasticaExtension.php
2012-01-25 13:51:16 +00:00
Richard Miller dce701b259 Merge branch '2.0'
Conflicts:
	DependencyInjection/FOQElasticaExtension.php
	Manager/RepositoryManager.php
	Resources/config/mongodb.xml
	Resources/config/orm.xml
	Resources/config/propel.xml
2012-01-25 12:09:06 +00:00
Richard Miller b4ebbc0a55 Merge branch '2.0' 2012-01-12 19:59:08 +00:00
Richard Miller 6eff104d6d Merge branch '2.0'
Conflicts:
	DependencyInjection/FOQElasticaExtension.php
	Manager/RepositoryManager.php
	README.md
	Resources/config/config.xml
	Resources/config/propel.xml
2012-01-12 16:34:19 +00:00
Jeremy Mikola 2193976c2c Merge pull request #62 from merk/patch-1
Fix index wide finder config check
2012-01-06 15:23:54 -08:00
Tim Nagel aa5bac2ccc Fix index wide finder config check
Fixes index wide finder configuration. Fixes #61
2012-01-07 09:19:24 +11:00
Richard Miller 96be3159bc Merge branch 'master' of github.com:Exercise/FOQElasticaBundle 2012-01-05 23:03:00 +00:00
Richard Miller 539bbebdd5 Added tests for Doctrine Listeners 2012-01-05 22:56:16 +00:00
Jeremy Mikola 094a505d12 Merge pull request #59 from merk/configerror
Removed missed merge conflict
2012-01-03 20:07:32 -08:00
Tim Nagel dfe72d8947 Fixed config.xml 2012-01-04 11:16:00 +11:00
Jeremy Mikola 0e0c12c7cf Merge pull request #58 from merk/index_transformer
Index wide finder
2012-01-03 14:16:56 -08:00
Tim Nagel 9c4ef3d8bd Added finder capability for an index 2012-01-04 09:12:51 +11:00
Jeremy Mikola fdc0d3c227 Merge pull request #55 from daFish/master
Changed path to custom provider example.
2011-12-29 08:57:22 -08:00
daFish 5aab521b42 Changed path to custom provider example. 2011-12-29 16:34:03 +01:00
Jeremy Mikola d0fdebb7d1 Ensure persistence.driver option exists before validating
The driver option is not required by the configuration, so we should check for it the validation functions.

If type_prototype is being used, there is a legitimate case where type definitions would not specify a driver. Likewise, the type_prototype may not specify the driver. If we wish to validate that a driver has been specified for a type, we'll have to do that in the extension class after loading the configuration and merging in prototypes.
2011-12-28 17:51:07 -05:00
Jeremy Mikola 62b3d94f8e Merge branch '2.0' 2011-12-28 17:09:50 -05:00
Jeremy Mikola 6036a8356e Merge branch '2.0' 2011-12-28 16:42:36 -05:00
Richard Miller 231e3a0b06 Moved annotation use back into RepositoryManager 2011-12-24 14:44:37 +00:00
Richard Miller 77a73b1db6 Refactored RepositoryManager 2011-12-23 16:38:22 +00:00
Richard Miller 510d411055 Made default manager configurable 2011-12-23 16:20:22 +00:00
Richard Miller ba976e3a41 Extracted the Doctine specific parts of the Repository Manager 2011-12-23 15:29:01 +00:00
Jeremy Mikola 8487ab1788 Merge pull request #51 from willdurand/propel-support
Propel support
2011-12-21 15:05:24 -08:00
William DURAND 00aa83df80 Fixed comments
see https://github.com/Exercise/FOQElasticaBundle/pull/51
2011-12-20 20:14:49 +01:00
William DURAND 19ae10ae27 Fixed unit test (phpunit doesn\'t allow to expect the base Exception class) 2011-12-20 17:46:36 +01:00
William DURAND 55187d23bf Added Propel support
Refactored the configuration => BC break
2011-12-20 17:44:39 +01:00
Richard Miller 0386f8ebbd Updated autoload instructions as per GH-48 2011-12-19 12:39:20 +00:00
Richard Miller ade3cfaef1 Merge pull request #46 from nurikabe/master
Allow variable "fields" configuration node for attachment mapping.
2011-12-16 07:38:45 -08:00
Richard Miller 048b1ff625 Added configuring repository by annotation 2011-12-13 19:26:03 +00:00
Richard Miller 564f1c843b Added using deps and vendors script to docs 2011-12-13 10:49:00 +00:00
Richard Miller 4bd1aa7c90 Updated README.md with info on 2.0 branch 2011-12-13 10:30:45 +00:00
Richard Miller 0e3fedf3fb Switched to manager registry for doctrine integration 2011-12-13 10:22:24 +00:00
nurikabe d4d05c2fc9 Allow variable "fields" configuration node for attachment mapping. 2011-12-12 17:12:48 +00:00
Richard Miller b9599052f9 Fixed typo 2011-12-11 23:19:10 +00:00
Richard Miller 7832fbc61a Removed unused local variable 2011-12-11 23:17:54 +00:00
Richard Miller 1a921ec2a3 Added Doctrine shortcut names for getting repositories 2011-12-11 23:09:13 +00:00
Richard Miller 69afe16558 Initialised RepositoryManager properties 2011-12-11 20:30:44 +00:00
182 changed files with 11426 additions and 2674 deletions

5
.scrutinizer.yml Normal file
View file

@ -0,0 +1,5 @@
imports:
- php
tools:
external_code_coverage: true

View file

@ -1,9 +1,36 @@
language: php
cache:
directories:
- $HOME/.composer/cache
php:
- 5.3
- 5.4
- 5.5
- 5.6
matrix:
include:
- php: 5.5
env: SYMFONY_VERSION='2.3.*'
- php: 5.5
env: SYMFONY_VERSION='2.5.*'
before_script:
- echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- composer install --dev
- /usr/share/elasticsearch/bin/elasticsearch -v
- sudo /usr/share/elasticsearch/bin/plugin -install elasticsearch/elasticsearch-mapper-attachments/2.0.0
- sudo service elasticsearch restart
- sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then echo "extension = mongo.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi;'
- sh -c 'if [ "$SYMFONY_VERSION" != "" ]; then composer require --dev --no-update symfony/symfony=$SYMFONY_VERSION; fi;'
- composer install --dev --prefer-source
script:
- vendor/bin/phpunit --coverage-clover=coverage.clover
services:
- elasticsearch
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover

16
Annotation/Search.php Normal file
View file

@ -0,0 +1,16 @@
<?php
namespace FOS\ElasticaBundle\Annotation;
/**
* Annotation class for setting search repository.
*
* @author Richard Miller <info@limethinking.co.uk>
* @Annotation
* @Target("CLASS")
*/
class Search
{
/** @var string */
public $repositoryClass;
}

25
CHANGELOG-2.0.md Normal file
View file

@ -0,0 +1,25 @@
CHANGELOG for 2.0.x
===================
This changelog references the relevant changes (bug and security fixes) done
in 2.0 minor versions.
To get the diff for a specific change, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/commit/XXX where XXX is
the commit hash. To get the diff between two versions, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v2.0.0...v2.0.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v2.0.0...2.0.x`
* 2.0.2 (2013-06-06)
* 00e9a49: Allow Symfony dependencies until 3.0
* 4b4a56d: Check for "indexes" key in Configuration::getNestings()
* 8ffd1a7: Update install version and add links to compatibility info
* 58e983f: Document installation via composer in README (closes #271)
* 2.0.1 (2013-04-04)
* f0d3a4d: Ensure mongo extension is available in Travis CI
* 1f26318: Avoid using a feature not supported in PHP5.3

22
CHANGELOG-2.1.md Normal file
View file

@ -0,0 +1,22 @@
CHANGELOG for 2.1.x
===================
This changelog references the relevant changes (bug and security fixes) done
in 2.1 minor versions.
To get the diff for a specific change, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/commit/XXX where XXX is
the commit hash. To get the diff between two versions, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v2.1.0...v2.1.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v2.1.0...2.1.x`
* 2.1.2 (2013-06-06)
* 00e9a49: Allow Symfony dependencies until 3.0
* 2.1.1 (2013-05-15)
* c05e0ca: Added documentation for ignoring missing hits
* 00b67fd: Ignore missing index hits

76
CHANGELOG-3.0.md Normal file
View file

@ -0,0 +1,76 @@
CHANGELOG for 3.0.x
===================
This changelog references the relevant changes (bug and security fixes) done
in 3.0 minor versions.
To get the diff for a specific change, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/commit/XXX where XXX is
the commit hash. To get the diff between two versions, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.0...v3.0.1
To generate a changelog summary since the last version, run
`git log --no-merges --oneline v3.0.0...3.0.x`
* 3.0.9 (2015-03-12)
* Fix a bug in the BC layer of the type configuration for empty configs
* Fix the service definition for the Doctrine listener when the logger is not enabled
* 3.0.8 (2014-01-31)
* Fixed handling of empty indexes #760
* Added support for `connectionStrategy` Elastica configuration #732
* Allow Elastica 1.4
* 3.0.7 (2015-01-21)
* Fixed the indexing of parent/child relations, broken since 3.0 #774
* Fixed multi_field properties not being normalised #769
* 3.0.6 (2015-01-04)
* Removed unused public image asset for the web development toolbar #742
* Fixed is_indexable_callback BC code to support array notation #761
* Fixed debug_logger for type providers #724
* Clean the OM if we filter away the entire batch #737
* 3.0.0-ALPHA6
* Moved `is_indexable_callback` from the listener properties to a type property called
`indexable_callback` which is run when both populating and listening for object
changes.
* AbstractProvider constructor change: Second argument is now an `IndexableInterface`
instance.
* Annotation @Search moved to FOS\ElasticaBundle\Annotation\Search with FOS\ElasticaBundle\Configuration\Search deprecated
* Deprecated FOS\ElasticaBundle\Client in favour of FOS\ElasticaBundle\Elastica\Client
* Deprecated FOS\ElasticaBundle\DynamicIndex in favour of FOS\ElasticaBundle\Elastica\Index
* Deprecated FOS\ElasticaBundle\IndexManager in favour of FOS\ElasticaBundle\Index\IndexManager
* Deprecated FOS\ElasticaBundle\Resetter in favour of FOS\ElasticaBundle\Index\Resetter
* 3.0.0-ALPHA5 (2014-05-23)
* Doctrine Provider speed up by disabling persistence logging while populating documents
* 3.0.0-ALPHA4 (2014-04-10)
* Indexes are now capable of logging errors with Elastica
* Fixed deferred indexing of deleted documents
* Resetting an index will now create it even if it doesn't exist
* Bulk upserting of documents is now supported when populating
* 3.0.0-ALPHA3 (2014-04-01)
* a9c4c93: Logger is now only enabled in debug mode by default
* #463: allowing hot swappable reindexing
* #415: BC BREAK: document indexing occurs in postFlush rather than the pre* events previously.
* 7d13823: Dropped (broken) support for Symfony <2.3
* #496: Added support for HTTP headers
* #528: FOSElasticaBundle will disable Doctrine logging when populating for a large increase in speed
* 3.0.0-ALPHA2 (2014-03-17)
* 41bf07e: Renamed the `no-stop-on-error` option in PopulateCommand to `ignore-errors`
* 418b9d7: Fixed validation of url configuration
* 726892c: Ignore TypeMissingException when resetting a single type. This allows to create new types without having to recreate the whole index.
* 7f53bad Add support for include_in_{parent,root} for nested and objects

61
CHANGELOG-3.1.md Normal file
View file

@ -0,0 +1,61 @@
CHANGELOG for 3.1.x
===================
This changelog references the relevant changes (bug and security fixes) done
in 3.1 versions.
To get the diff for a specific change, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/commit/XXX where XXX is
the commit hash. To get the diff between two versions, go to
https://github.com/FriendsOfSymfony/FOSElasticaBundle/compare/v3.0.4...v3.1.0
* 3.1.3 (2015-04-02)
* Fix Symfony 2.3 compatibility
* 3.1.2 (2015-03-27)
* Fix the previous release
* 3.1.1 (2015-03-27)
* Fix PopulateCommand trying to set formats for ProgressBar in Symfony < 2.5
* Fix Provider implementations that depend on a batch size from going into
infinite loops
* 3.1.0 (2015-03-18)
* BC BREAK: `Doctrine\Listener#scheduleForDeletion` access changed to private.
* BC BREAK: `ObjectPersisterInterface` gains the method `handlesObject` that
returns a boolean value if it will handle a given object or not.
* BC BREAK: Removed `Doctrine\Listener#getSubscribedEvents`. The container
configuration now configures tags with the methods to call to avoid loading
this class on every request where doctrine is active. #729
* BC BREAK: Added methods for retrieving aggregations when paginating results.
The `PaginationAdapterInterface` has a new method, `getAggregations`. #726
* Added ability to configure `date_detection`, `numeric_detection` and
`dynamic_date_formats` for types. #753
* New event `POST_TRANSFORM` which allows developers to add custom properties to
Elastica Documents for indexing.
* When available, the `fos:elastica:populate` command will now use the
ProgressBar helper instead of outputting strings. You can use verbosity
controls on the command to output additional information like memory
usage, runtime and estimated time.
* Added new option `property_path` to a type property definition to allow
customisation of the property path used to retrieve data from objects.
Setting `property_path` to `false` will configure the Transformer to ignore
that property while transforming. Combined with the above POST_TRANSFORM event
developers can now create calculated dynamic properties on Elastica documents
for indexing. #794
* Fixed a case where ProgressCommand would always ignore errors regardless of
--ignore-errors being passed or not.
* Added a `SliceFetcher` abstraction for Doctrine providers that get more
information about the previous slice allowing for optimising queries during
population. #725
* New events `PRE_INDEX_POPULATE`, `POST_INDEX_POPULATE`, `PRE_TYPE_POPULATE` and
`POST_TYPE_POPULATE` allow for monitoring when an index is about to be or has
just been populated. #744
* New events `PRE_INDEX_RESET`, `POST_INDEX_RESET`, `PRE_TYPE_RESET` and
`POST_TYPE_RESET` are run before and after operations that will reset an
index. #744
* Added indexable callback support for the __invoke method of a service. #823

View file

@ -2,31 +2,11 @@
namespace FOS\ElasticaBundle;
use Elastica_Client;
use FOS\ElasticaBundle\Logger\ElasticaLogger;
use FOS\ElasticaBundle\Elastica\Client as BaseClient;
/**
* @author Gordon Franke <info@nevalon.de>
* @deprecated Use \FOS\ElasticaBundle\Elastica\LoggingClient
*/
class Client extends Elastica_Client
class Client extends BaseClient
{
protected $logger;
public function setLogger(ElasticaLogger $logger)
{
$this->logger = $logger;
}
public function request($path, $method, $data = array(), array $query = array())
{
$start = microtime(true);
$response = parent::request($path, $method, $data, $query);
if (null !== $this->logger) {
$time = microtime(true) - $start;
$this->logger->logQuery($path, $method, $data, $time);
}
return $response;
}
}

187
Command/PopulateCommand.php Executable file → Normal file
View file

@ -2,49 +2,200 @@
namespace FOS\ElasticaBundle\Command;
use FOS\ElasticaBundle\Event\IndexPopulateEvent;
use FOS\ElasticaBundle\Event\TypePopulateEvent;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Helper\DialogHelper;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\Output;
use FOS\ElasticaBundle\IndexManager;
use FOS\ElasticaBundle\Provider\ProviderRegistry;
use FOS\ElasticaBundle\Resetter;
use Symfony\Component\Console\Helper\ProgressBar;
/**
* Populate the search index
* Populate the search index.
*/
class PopulateCommand extends ContainerAwareCommand
{
/**
* @see Command
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
*/
private $dispatcher;
/**
* @var IndexManager
*/
private $indexManager;
/**
* @var ProgressClosureBuilder
*/
private $progressClosureBuilder;
/**
* @var ProviderRegistry
*/
private $providerRegistry;
/**
* @var Resetter
*/
private $resetter;
/**
* @see Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this
->setName('fos:elastica:populate')
->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to repopulate')
->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to repopulate')
->addOption('no-reset', null, InputOption::VALUE_NONE, 'Do not reset index before populating')
->addOption('offset', null, InputOption::VALUE_REQUIRED, 'Start indexing at offset', 0)
->addOption('sleep', null, InputOption::VALUE_REQUIRED, 'Sleep time between persisting iterations (microseconds)', 0)
->addOption('batch-size', null, InputOption::VALUE_REQUIRED, 'Index packet size (overrides provider config option)')
->addOption('ignore-errors', null, InputOption::VALUE_NONE, 'Do not stop on errors')
->addOption('no-overwrite-format', null, InputOption::VALUE_NONE, 'Prevent this command from overwriting ProgressBar\'s formats')
->setDescription('Populates search indexes from providers')
->addOption('no-reset', null, InputOption::VALUE_NONE, 'Do not reset the indexes before they are populated.');
;
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->dispatcher = $this->getContainer()->get('event_dispatcher');
$this->indexManager = $this->getContainer()->get('fos_elastica.index_manager');
$this->providerRegistry = $this->getContainer()->get('fos_elastica.provider_registry');
$this->resetter = $this->getContainer()->get('fos_elastica.resetter');
$this->progressClosureBuilder = new ProgressClosureBuilder();
if (!$input->getOption('no-overwrite-format') && class_exists('Symfony\\Component\\Console\\Helper\\ProgressBar')) {
ProgressBar::setFormatDefinition('normal', " %current%/%max% [%bar%] %percent:3s%%\n%message%");
ProgressBar::setFormatDefinition('verbose', " %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%\n%message%");
ProgressBar::setFormatDefinition('very_verbose', " %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%\n%message%");
ProgressBar::setFormatDefinition('debug', " %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%\n%message%");
}
}
/**
* {@inheritDoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$input->getOption('no-reset')) {
$output->writeln('Resetting indexes');
$this->getContainer()->get('fos_elastica.reseter')->reset();
$index = $input->getOption('index');
$type = $input->getOption('type');
$reset = !$input->getOption('no-reset');
$options = array(
'ignore_errors' => $input->getOption('ignore-errors'),
'offset' => $input->getOption('offset'),
'sleep' => $input->getOption('sleep')
);
if ($input->getOption('batch-size')) {
$options['batch_size'] = (int) $input->getOption('batch-size');
}
$output->writeln('Populating indexes');
$this->getContainer()->get('fos_elastica.populator')->populate(function($text) use ($output) {
$output->writeLn($text);
});
if ($input->isInteractive() && $reset && $input->getOption('offset')) {
/** @var DialogHelper $dialog */
$dialog = $this->getHelperSet()->get('dialog');
if (!$dialog->askConfirmation($output, '<question>You chose to reset the index and start indexing with an offset. Do you really want to do that?</question>', true)) {
return;
}
}
$output->writeln('Refreshing indexes');
array_map(function($index) {
$index->refresh();
}, $this->getContainer()->get('fos_elastica.index_manager')->getAllIndexes());
if (null === $index && null !== $type) {
throw new \InvalidArgumentException('Cannot specify type option without an index.');
}
$output->writeln('Done');
if (null !== $index) {
if (null !== $type) {
$this->populateIndexType($output, $index, $type, $reset, $options);
} else {
$this->populateIndex($output, $index, $reset, $options);
}
} else {
$indexes = array_keys($this->indexManager->getAllIndexes());
foreach ($indexes as $index) {
$this->populateIndex($output, $index, $reset, $options);
}
}
}
/**
* Recreates an index, populates its types, and refreshes the index.
*
* @param OutputInterface $output
* @param string $index
* @param boolean $reset
* @param array $options
*/
private function populateIndex(OutputInterface $output, $index, $reset, $options)
{
$event = new IndexPopulateEvent($index, $reset, $options);
$this->dispatcher->dispatch(IndexPopulateEvent::PRE_INDEX_POPULATE, $event);
if ($event->isReset()) {
$output->writeln(sprintf('<info>Resetting</info> <comment>%s</comment>', $index));
$this->resetter->resetIndex($index, true);
}
$types = array_keys($this->providerRegistry->getIndexProviders($index));
foreach ($types as $type) {
$this->populateIndexType($output, $index, $type, false, $event->getOptions());
}
$this->dispatcher->dispatch(IndexPopulateEvent::POST_INDEX_POPULATE, $event);
$this->refreshIndex($output, $index);
}
/**
* Deletes/remaps an index type, populates it, and refreshes the index.
*
* @param OutputInterface $output
* @param string $index
* @param string $type
* @param boolean $reset
* @param array $options
*/
private function populateIndexType(OutputInterface $output, $index, $type, $reset, $options)
{
$event = new TypePopulateEvent($index, $type, $reset, $options);
$this->dispatcher->dispatch(TypePopulateEvent::PRE_TYPE_POPULATE, $event);
if ($event->isReset()) {
$output->writeln(sprintf('<info>Resetting</info> <comment>%s/%s</comment>', $index, $type));
$this->resetter->resetIndexType($index, $type);
}
$provider = $this->providerRegistry->getProvider($index, $type);
$loggerClosure = $this->progressClosureBuilder->build($output, 'Populating', $index, $type);
$provider->populate($loggerClosure, $event->getOptions());
$this->dispatcher->dispatch(TypePopulateEvent::POST_TYPE_POPULATE, $event);
$this->refreshIndex($output, $index, false);
}
/**
* Refreshes an index.
*
* @param OutputInterface $output
* @param string $index
* @param bool $postPopulate
*/
private function refreshIndex(OutputInterface $output, $index, $postPopulate = true)
{
if ($postPopulate) {
$this->resetter->postPopulate($index);
}
$output->writeln(sprintf('<info>Refreshing</info> <comment>%s</comment>', $index));
$this->indexManager->getIndex($index)->refresh();
}
}

View file

@ -0,0 +1,103 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\OutputInterface;
class ProgressClosureBuilder
{
/**
* Builds a loggerClosure to be called from inside the Provider to update the command
* line.
*
* @param OutputInterface $output
* @param string $action
* @param string $index
* @param string $type
*
* @return callable
*/
public function build(OutputInterface $output, $action, $index, $type)
{
if (!class_exists('Symfony\Component\Console\Helper\ProgressBar') ||
!is_callable(array('Symfony\Component\Console\Helper\ProgressBar', 'getProgress'))) {
return $this->buildLegacy($output, $action, $index, $type);
}
$progress = null;
return function ($increment, $totalObjects, $message = null) use (&$progress, $output, $action, $index, $type) {
if (null === $progress) {
$progress = new ProgressBar($output, $totalObjects);
$progress->start();
}
if (null !== $message) {
$progress->clear();
$output->writeln(sprintf('<info>%s</info> <error>%s</error>', $action, $message));
$progress->display();
}
$progress->setMessage(sprintf('<info>%s</info> <comment>%s/%s</comment>', $action, $index, $type));
$progress->advance($increment);
};
}
/**
* Builds a legacy closure that outputs lines for each step. Used in cases
* where the ProgressBar component doesnt exist or does not have the correct
* methods to support what we need.
*
* @param OutputInterface $output
* @param string $action
* @param string $index
* @param string $type
*
* @return callable
*/
private function buildLegacy(OutputInterface $output, $action, $index, $type)
{
$lastStep = null;
$current = 0;
return function ($increment, $totalObjects, $message = null) use ($output, $action, $index, $type, &$lastStep, &$current) {
if ($current + $increment > $totalObjects) {
$increment = $totalObjects - $current;
}
if (null !== $message) {
$output->writeln(sprintf('<info>%s</info> <error>%s</error>', $action, $message));
}
$currentTime = microtime(true);
$timeDifference = $currentTime - $lastStep;
$objectsPerSecond = $lastStep ? ($increment / $timeDifference) : $increment;
$lastStep = $currentTime;
$current += $increment;
$percent = 100 * $current / $totalObjects;
$output->writeln(sprintf(
'<info>%s</info> <comment>%s/%s</comment> %0.1f%% (%d/%d), %d objects/s (RAM: current=%uMo peak=%uMo)',
$action,
$index,
$type,
$percent,
$current,
$totalObjects,
$objectsPerSecond,
round(memory_get_usage() / (1024 * 1024)),
round(memory_get_peak_usage() / (1024 * 1024))
));
};
}
}

78
Command/ResetCommand.php Executable file
View file

@ -0,0 +1,78 @@
<?php
namespace FOS\ElasticaBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use FOS\ElasticaBundle\IndexManager;
use FOS\ElasticaBundle\Resetter;
/**
* Reset search indexes.
*/
class ResetCommand extends ContainerAwareCommand
{
/**
* @var IndexManager
*/
private $indexManager;
/**
* @var Resetter
*/
private $resetter;
/**
* @see Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this
->setName('fos:elastica:reset')
->addOption('index', null, InputOption::VALUE_OPTIONAL, 'The index to reset')
->addOption('type', null, InputOption::VALUE_OPTIONAL, 'The type to reset')
->addOption('force', null, InputOption::VALUE_NONE, 'Force index deletion if same name as alias')
->setDescription('Reset search indexes')
;
}
/**
* @see Symfony\Component\Console\Command\Command::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->indexManager = $this->getContainer()->get('fos_elastica.index_manager');
$this->resetter = $this->getContainer()->get('fos_elastica.resetter');
}
/**
* @see Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$index = $input->getOption('index');
$type = $input->getOption('type');
$force = (bool) $input->getOption('force');
if (null === $index && null !== $type) {
throw new \InvalidArgumentException('Cannot specify type option without an index.');
}
if (null !== $type) {
$output->writeln(sprintf('<info>Resetting</info> <comment>%s/%s</comment>', $index, $type));
$this->resetter->resetIndexType($index, $type);
} else {
$indexes = null === $index
? array_keys($this->indexManager->getAllIndexes())
: array($index)
;
foreach ($indexes as $index) {
$output->writeln(sprintf('<info>Resetting</info> <comment>%s</comment>', $index));
$this->resetter->resetIndex($index, false, $force);
}
}
}
}

View file

@ -7,12 +7,11 @@ use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\Output;
use Elastica_Query;
use Elastica_Result;
use Elastica\Query;
use Elastica\Result;
/**
* Searches a type
* Searches a type.
*/
class SearchCommand extends ContainerAwareCommand
{
@ -22,18 +21,17 @@ class SearchCommand extends ContainerAwareCommand
protected function configure()
{
$this
->setDefinition(array(
new InputArgument('type', InputArgument::REQUIRED, 'The type to search in'),
new InputArgument('query', InputArgument::REQUIRED, 'The text to search'),
))
->addOption('index', null, InputOption::VALUE_NONE, 'The index to search in')
->setName('fos:elastica:search')
->addArgument('type', InputArgument::REQUIRED, 'The type to search in')
->addArgument('query', InputArgument::REQUIRED, 'The text to search')
->addOption('index', null, InputOption::VALUE_REQUIRED, 'The index to search in')
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'The maximum number of documents to return', 20)
->addOption('show-field', null, InputOption::VALUE_REQUIRED, 'Field to show, null uses the first field')
->addOption('show-source', null, InputOption::VALUE_NONE, 'Show the documents sources')
->addOption('show-id', null, InputOption::VALUE_NONE, 'Show the documents ids')
->addOption('explain', null, InputOption::VALUE_NONE, 'Enables explanation for each hit on how its score was computed.')
->setName('fos:elastica:search')
->setDescription('Searches documents in a given type and index');
->setDescription('Searches documents in a given type and index')
;
}
/**
@ -41,10 +39,12 @@ class SearchCommand extends ContainerAwareCommand
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$index = $this->getContainer()->get('fos_elastica.index_manager')->getIndex($input->getOption('index'));
$indexName = $input->getOption('index');
/** @var $index \Elastica\Index */
$index = $this->getContainer()->get('fos_elastica.index_manager')->getIndex($indexName ? $indexName : null);
$type = $index->getType($input->getArgument('type'));
$query = Elastica_Query::create($input->getArgument('query'));
$query->setLimit($input->getOption('limit'));
$query = Query::create($input->getArgument('query'));
$query->setSize($input->getOption('limit'));
if ($input->getOption('explain')) {
$query->setExplain(true);
}
@ -57,7 +57,7 @@ class SearchCommand extends ContainerAwareCommand
}
}
protected function formatResult(Elastica_Result $result, $showField, $showSource, $showId, $explain)
protected function formatResult(Result $result, $showField, $showSource, $showId, $explain)
{
$source = $result->getSource();
if ($showField) {

View file

@ -0,0 +1,64 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Configuration;
/**
* Central manager for index and type configuration.
*/
class ConfigManager implements ManagerInterface
{
/**
* @var IndexConfig[]
*/
private $indexes = array();
/**
* @param Source\SourceInterface[] $sources
*/
public function __construct(array $sources)
{
foreach ($sources as $source) {
$this->indexes = array_merge($source->getConfiguration(), $this->indexes);
}
}
public function getIndexConfiguration($indexName)
{
if (!$this->hasIndexConfiguration($indexName)) {
throw new \InvalidArgumentException(sprintf('Index with name "%s" is not configured.', $indexName));
}
return $this->indexes[$indexName];
}
public function getIndexNames()
{
return array_keys($this->indexes);
}
public function getTypeConfiguration($indexName, $typeName)
{
$index = $this->getIndexConfiguration($indexName);
$type = $index->getType($typeName);
if (!$type) {
throw new \InvalidArgumentException(sprintf('Type with name "%s" on index "%s" is not configured', $typeName, $indexName));
}
return $type;
}
public function hasIndexConfiguration($indexName)
{
return isset($this->indexes[$indexName]);
}
}

View file

@ -0,0 +1,124 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Configuration;
class IndexConfig
{
/**
* The name of the index for ElasticSearch.
*
* @var string
*/
private $elasticSearchName;
/**
* The internal name of the index. May not be the same as the name used in ElasticSearch,
* especially if aliases are enabled.
*
* @var string
*/
private $name;
/**
* An array of settings sent to ElasticSearch when creating the index.
*
* @var array
*/
private $settings;
/**
* All types that belong to this index.
*
* @var TypeConfig[]
*/
private $types;
/**
* Indicates if the index should use an alias, allowing an index repopulation to occur
* without overwriting the current index.
*
* @var bool
*/
private $useAlias = false;
/**
* Constructor expects an array as generated by the Container Configuration builder.
*
* @param string $name
* @param TypeConfig[] $types
* @param array $config
*/
public function __construct($name, array $types, array $config)
{
$this->elasticSearchName = isset($config['elasticSearchName']) ? $config['elasticSearchName'] : $name;
$this->name = $name;
$this->settings = isset($config['settings']) ? $config['settings'] : array();
$this->types = $types;
$this->useAlias = isset($config['useAlias']) ? $config['useAlias'] : false;
}
/**
* @return string
*/
public function getElasticSearchName()
{
return $this->elasticSearchName;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return array
*/
public function getSettings()
{
return $this->settings;
}
/**
* @param string $typeName
*
* @return TypeConfig
*
* @throws \InvalidArgumentException
*/
public function getType($typeName)
{
if (!array_key_exists($typeName, $this->types)) {
throw new \InvalidArgumentException(sprintf('Type "%s" does not exist on index "%s"', $typeName, $this->name));
}
return $this->types[$typeName];
}
/**
* @return \FOS\ElasticaBundle\Configuration\TypeConfig[]
*/
public function getTypes()
{
return $this->types;
}
/**
* @return boolean
*/
public function isUseAlias()
{
return $this->useAlias;
}
}

View file

@ -0,0 +1,44 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Configuration;
/**
* Central manager for index and type configuration.
*/
interface ManagerInterface
{
/**
* Returns configuration for an index.
*
* @param $index
*
* @return IndexConfig
*/
public function getIndexConfiguration($index);
/**
* Returns an array of known index names.
*
* @return array
*/
public function getIndexNames();
/**
* Returns a type configuration.
*
* @param string $index
* @param string $type
*
* @return TypeConfig
*/
public function getTypeConfiguration($index, $type);
}

View file

@ -1,18 +1,26 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Configuration;
use FOS\ElasticaBundle\Annotation\Search as BaseSearch;
/**
* Annotation class for setting search repository.
*
* @author Richard Miller <info@limethinking.co.uk>
* @Annotation
*
* @deprecated Use FOS\ElasticaBundle\Annotation\Search instead
* @Target("CLASS")
*/
class Search
class Search extends BaseSearch
{
/** @var string */
public $repositoryClass;
}

View file

@ -0,0 +1,80 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Configuration\Source;
use FOS\ElasticaBundle\Configuration\IndexConfig;
use FOS\ElasticaBundle\Configuration\TypeConfig;
/**
* Returns index and type configuration from the container.
*/
class ContainerSource implements SourceInterface
{
/**
* The internal container representation of information.
*
* @var array
*/
private $configArray;
public function __construct(array $configArray)
{
$this->configArray = $configArray;
}
/**
* Should return all configuration available from the data source.
*
* @return IndexConfig[]
*/
public function getConfiguration()
{
$indexes = array();
foreach ($this->configArray as $config) {
$types = $this->getTypes($config);
$index = new IndexConfig($config['name'], $types, array(
'elasticSearchName' => $config['elasticsearch_name'],
'settings' => $config['settings'],
'useAlias' => $config['use_alias'],
));
$indexes[$config['name']] = $index;
}
return $indexes;
}
/**
* Builds TypeConfig objects for each type.
*
* @param array $config
*
* @return array
*/
protected function getTypes($config)
{
$types = array();
if (isset($config['types'])) {
foreach ($config['types'] as $typeConfig) {
$types[$typeConfig['name']] = new TypeConfig(
$typeConfig['name'],
$typeConfig['mapping'],
$typeConfig['config']
);
// TODO: handle prototypes..
}
}
return $types;
}
}

View file

@ -0,0 +1,26 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Configuration\Source;
/**
* Represents a source of index and type information (ie, the Container configuration or
* annotations).
*/
interface SourceInterface
{
/**
* Should return all configuration available from the data source.
*
* @return \FOS\ElasticaBundle\Configuration\IndexConfig[]
*/
public function getConfiguration();
}

View file

@ -0,0 +1,113 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Configuration;
class TypeConfig
{
/**
* @var array
*/
private $config;
/**
* @var array
*/
private $mapping;
/**
* @var string
*/
private $name;
public function __construct($name, array $mapping, array $config = array())
{
$this->config = $config;
$this->mapping = $mapping;
$this->name = $name;
}
/**
* @return bool|null
*/
public function getDateDetection()
{
return $this->getConfig('date_detection');
}
/**
* @return array
*/
public function getDynamicDateFormats()
{
return $this->getConfig('dynamic_date_formats');
}
/**
* @return string|null
*/
public function getIndexAnalyzer()
{
return $this->getConfig('index_analyzer');
}
/**
* @return array
*/
public function getMapping()
{
return $this->mapping;
}
/**
* @return string|null
*/
public function getModel()
{
return isset($this->config['persistence']['model']) ?
$this->config['persistence']['model'] :
null;
}
/**
* @return bool|null
*/
public function getNumericDetection()
{
return $this->getConfig('numeric_detection');
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string|null
*/
public function getSearchAnalyzer()
{
return $this->getConfig('search_analyzer');
}
/**
* @param string $key
*/
private function getConfig($key)
{
return isset($this->config[$key]) ?
$this->config[$key] :
null;
}
}

View file

@ -40,6 +40,16 @@ class ElasticaDataCollector extends DataCollector
return $this->data['queries'];
}
public function getTime()
{
$time = 0;
foreach ($this->data['queries'] as $query) {
$time += $query['executionMS'];
}
return $time;
}
/**
* {@inheritdoc}
*/

View file

@ -1,27 +0,0 @@
<?php
namespace FOS\ElasticaBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
class AddProviderPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('fos_elastica.populator')) {
return;
}
$providers = array();
foreach ($container->findTaggedServiceIds('fos_elastica.provider') as $id => $attributes) {
$providers[$id] = new Reference($id);
}
$container->getDefinition('fos_elastica.populator')->replaceArgument(0, $providers);
}
}

View file

@ -0,0 +1,36 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class ConfigSourcePass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('fos_elastica.config_manager')) {
return;
}
$sources = array();
foreach (array_keys($container->findTaggedServiceIds('fos_elastica.config_source')) as $id) {
$sources[] = new Reference($id);
}
$container->getDefinition('fos_elastica.config_manager')->replaceArgument(0, $sources);
}
}

View file

@ -0,0 +1,38 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class IndexPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('fos_elastica.index_manager')) {
return;
}
$indexes = array();
foreach ($container->findTaggedServiceIds('fos_elastica.index') as $id => $tags) {
foreach ($tags as $tag) {
$indexes[$tag['name']] = new Reference($id);
}
}
$container->getDefinition('fos_elastica.index_manager')->replaceArgument(0, $indexes);
}
}

View file

@ -0,0 +1,70 @@
<?php
namespace FOS\ElasticaBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class RegisterProvidersPass implements CompilerPassInterface
{
/**
* Mapping of class names to booleans indicating whether the class
* implements ProviderInterface.
*
* @var array
*/
private $implementations = array();
/**
* @see Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface::process()
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('fos_elastica.provider_registry')) {
return;
}
// Infer the default index name from the service alias
$defaultIndex = substr($container->getAlias('fos_elastica.index'), 19);
$registry = $container->getDefinition('fos_elastica.provider_registry');
$providers = $container->findTaggedServiceIds('fos_elastica.provider');
foreach ($providers as $providerId => $tags) {
$index = $type = null;
$class = $container->getDefinition($providerId)->getClass();
if (!$class || !$this->isProviderImplementation($class)) {
throw new \InvalidArgumentException(sprintf('Elastica provider "%s" with class "%s" must implement ProviderInterface.', $providerId, $class));
}
foreach ($tags as $tag) {
if (!isset($tag['type'])) {
throw new \InvalidArgumentException(sprintf('Elastica provider "%s" must specify the "type" attribute.', $providerId));
}
$index = isset($tag['index']) ? $tag['index'] : $defaultIndex;
$type = $tag['type'];
}
$registry->addMethodCall('addProvider', array($index, $type, $providerId));
}
}
/**
* Returns whether the class implements ProviderInterface.
*
* @param string $class
*
* @return boolean
*/
private function isProviderImplementation($class)
{
if (!isset($this->implementations[$class])) {
$refl = new \ReflectionClass($class);
$this->implementations[$class] = $refl->implementsInterface('FOS\ElasticaBundle\Provider\ProviderInterface');
}
return $this->implementations[$class];
}
}

View file

@ -4,7 +4,6 @@ namespace FOS\ElasticaBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;
use InvalidArgumentException;
@ -20,7 +19,7 @@ class TransformerPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('fos_elastica.elastica_to_model_transformer.collection.prototype')) {
if (!$container->hasDefinition('fos_elastica.elastica_to_model_transformer.collection')) {
return;
}
@ -32,7 +31,7 @@ class TransformerPass implements CompilerPassInterface
throw new InvalidArgumentException('The Transformer must have both a type and an index defined.');
}
$transformers[$tag['index']][$tag['type']]= new Reference($id);
$transformers[$tag['index']][$tag['type']] = new Reference($id);
}
}
@ -45,4 +44,4 @@ class TransformerPass implements CompilerPassInterface
$index->replaceArgument(0, $indexTransformers);
}
}
}
}

View file

@ -4,17 +4,35 @@ namespace FOS\ElasticaBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration
class Configuration implements ConfigurationInterface
{
/**
* Stores supported database drivers.
*
* @var array
*/
private $supportedDrivers = array('orm', 'mongodb', 'propel');
/**
* If the kernel is running in debug mode.
*
* @var bool
*/
private $debug;
public function __construct($debug)
{
$this->debug = $debug;
}
/**
* Generates the configuration tree.
*
* @return \Symfony\Component\DependencyInjection\Configuration\NodeInterface
* @return TreeBuilder
*/
public function getConfigTree()
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('fos_elastica', 'array');
@ -24,17 +42,28 @@ class Configuration
$rootNode
->children()
->scalarNode('default_client')->end()
->scalarNode('default_index')->end()
->scalarNode('default_client')
->info('Defaults to the first client defined')
->end()
->scalarNode('default_index')
->info('Defaults to the first index defined')
->end()
->scalarNode('default_manager')->defaultValue('orm')->end()
->arrayNode('serializer')
->treatNullLike(array())
->children()
->scalarNode('callback_class')->defaultValue('FOS\ElasticaBundle\Serializer\Callback')->end()
->scalarNode('serializer')->defaultValue('serializer')->end()
->end()
->end()
->end()
;
return $treeBuilder->buildTree();
return $treeBuilder;
}
/**
* Adds the configuration for the "clients" key
* Adds the configuration for the "clients" key.
*/
private function addClientsSection(ArrayNodeDefinition $rootNode)
{
@ -45,12 +74,67 @@ class Configuration
->useAttributeAsKey('id')
->prototype('array')
->performNoDeepMerging()
// BC - Renaming 'servers' node to 'connections'
->beforeNormalization()
->ifTrue(function ($v) { return isset($v['servers']); })
->then(function ($v) {
$v['connections'] = $v['servers'];
unset($v['servers']);
return $v;
})
->end()
// Elastica names its properties with camel case, support both
->beforeNormalization()
->ifTrue(function ($v) { return isset($v['connection_strategy']); })
->then(function ($v) {
$v['connectionStrategy'] = $v['connection_strategy'];
unset($v['connection_strategy']);
return $v;
})
->end()
// If there is no connections array key defined, assume a single connection.
->beforeNormalization()
->ifTrue(function ($v) { return is_array($v) && !array_key_exists('connections', $v); })
->then(function ($v) {
return array(
'connections' => array($v),
);
})
->end()
->children()
->scalarNode('url')->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
->arrayNode('connections')
->requiresAtLeastOneElement()
->prototype('array')
->fixXmlConfig('header')
->children()
->scalarNode('url')
->validate()
->ifTrue(function ($url) { return $url && substr($url, -1) !== '/'; })
->then(function ($url) { return $url.'/'; })
->end()
->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
->scalarNode('proxy')->end()
->scalarNode('logger')
->defaultValue($this->debug ? 'fos_elastica.logger' : false)
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
->arrayNode('headers')
->useAttributeAsKey('name')
->prototype('scalar')->end()
->end()
->scalarNode('transport')->end()
->scalarNode('timeout')->end()
->end()
->end()
->end()
->scalarNode('timeout')->end()
->scalarNode('headers')->end()
->scalarNode('connectionStrategy')->defaultValue('Simple')->end()
->end()
->end()
->end()
@ -59,7 +143,7 @@ class Configuration
}
/**
* Adds the configuration for the "indexes" key
* Adds the configuration for the "indexes" key.
*/
private function addIndexesSection(ArrayNodeDefinition $rootNode)
{
@ -69,8 +153,11 @@ class Configuration
->arrayNode('indexes')
->useAttributeAsKey('name')
->prototype('array')
->performNoDeepMerging()
->children()
->scalarNode('index_name')
->info('Defaults to the name of the index, but can be modified if the index name is different in ElasticSearch')
->end()
->booleanNode('use_alias')->defaultValue(false)->end()
->scalarNode('client')->end()
->scalarNode('finder')
->treatNullLike(true)
@ -78,57 +165,10 @@ class Configuration
->end()
->arrayNode('type_prototype')
->children()
->arrayNode('persistence')
->validate()
->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
->thenInvalid('Propel doesn\'t support listeners')
->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
->thenInvalid('Propel doesn\'t support the "repository" parameter')
->end()
->children()
->scalarNode('driver')
->validate()
->ifNotInArray($this->supportedDrivers)
->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
->end()
->end()
->scalarNode('identifier')->defaultValue('id')->end()
->arrayNode('provider')
->children()
->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
->scalarNode('batch_size')->defaultValue(100)->end()
->scalarNode('clear_object_manager')->defaultTrue()->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('listener')
->children()
->scalarNode('insert')->defaultTrue()->end()
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('finder')
->children()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('elastica_to_model_transformer')
->addDefaultsIfNotSet()
->children()
->scalarNode('hydrate')->defaultTrue()->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('model_to_elastica_transformer')
->addDefaultsIfNotSet()
->children()
->scalarNode('service')->end()
->end()
->end()
->end()
->end()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
->append($this->getPersistenceNode())
->append($this->getSerializerNode())
->end()
->end()
->variableNode('settings')->defaultValue(array())->end()
@ -152,63 +192,83 @@ class Configuration
->useAttributeAsKey('name')
->prototype('array')
->treatNullLike(array())
->children()
->arrayNode('persistence')
->validate()
->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
->thenInvalid('Propel doesn\'t support listeners')
->ifTrue(function($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
->thenInvalid('Propel doesn\'t support the "repository" parameter')
->end()
->children()
->scalarNode('driver')
->validate()
->ifNotInArray($this->supportedDrivers)
->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
->end()
->end()
->scalarNode('model')->end()
->scalarNode('repository')->end()
->scalarNode('identifier')->defaultValue('id')->end()
->arrayNode('provider')
->children()
->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
->scalarNode('batch_size')->defaultValue(100)->end()
->scalarNode('clear_object_manager')->defaultTrue()->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('listener')
->children()
->scalarNode('insert')->defaultTrue()->end()
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('finder')
->children()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('elastica_to_model_transformer')
->addDefaultsIfNotSet()
->children()
->scalarNode('hydrate')->defaultTrue()->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('model_to_elastica_transformer')
->addDefaultsIfNotSet()
->children()
->scalarNode('service')->end()
->end()
->end()
->end()
->end()
->beforeNormalization()
->ifNull()
->thenEmptyArray()
->end()
->append($this->getMappingsNode())
// BC - Renaming 'mappings' node to 'properties'
->beforeNormalization()
->ifTrue(function ($v) { return array_key_exists('mappings', $v); })
->then(function ($v) {
$v['properties'] = $v['mappings'];
unset($v['mappings']);
return $v;
})
->end()
// BC - Support the old is_indexable_callback property
->beforeNormalization()
->ifTrue(function ($v) {
return isset($v['persistence']) &&
isset($v['persistence']['listener']) &&
isset($v['persistence']['listener']['is_indexable_callback']);
})
->then(function ($v) {
$callback = $v['persistence']['listener']['is_indexable_callback'];
if (is_array($callback)) {
list($class) = $callback + array(null);
if ($class[0] !== '@' && is_string($class) && !class_exists($class)) {
$callback[0] = '@'.$class;
}
}
$v['indexable_callback'] = $callback;
unset($v['persistence']['listener']['is_indexable_callback']);
return $v;
})
->end()
// Support multiple dynamic_template formats to match the old bundle style
// and the way ElasticSearch expects them
->beforeNormalization()
->ifTrue(function ($v) { return isset($v['dynamic_templates']); })
->then(function ($v) {
$dt = array();
foreach ($v['dynamic_templates'] as $key => $type) {
if (is_int($key)) {
$dt[] = $type;
} else {
$dt[][$key] = $type;
}
}
$v['dynamic_templates'] = $dt;
return $v;
})
->end()
->children()
->booleanNode('date_detection')->end()
->arrayNode('dynamic_date_formats')->prototype('scalar')->end()->end()
->scalarNode('index_analyzer')->end()
->booleanNode('numeric_detection')->end()
->scalarNode('search_analyzer')->end()
->variableNode('indexable_callback')->end()
->append($this->getPersistenceNode())
->append($this->getSerializerNode())
->end()
->append($this->getIdNode())
->append($this->getPropertiesNode())
->append($this->getDynamicTemplateNode())
->append($this->getSourceNode())
->append($this->getBoostNode())
->append($this->getRoutingNode())
->append($this->getParentNode())
->append($this->getAllNode())
->append($this->getTimestampNode())
->append($this->getTtlNode())
->end()
;
@ -216,39 +276,42 @@ class Configuration
}
/**
* Returns the array node used for "mappings".
* Returns the array node used for "properties".
*/
protected function getMappingsNode()
protected function getPropertiesNode()
{
$builder = new TreeBuilder();
$node = $builder->root('mappings');
$node = $builder->root('properties');
$node
->useAttributeAsKey('name')
->prototype('variable')
->treatNullLike(array());
return $node;
}
/**
* Returns the array node used for "dynamic_templates".
*/
public function getDynamicTemplateNode()
{
$builder = new TreeBuilder();
$node = $builder->root('dynamic_templates');
$node
->prototype('array')
->treatNullLike(array())
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue('string')->end()
->scalarNode('boost')->end()
->scalarNode('store')->end()
->scalarNode('index')->end()
->scalarNode('analyzer')->end()
->scalarNode('term_vector')->end()
->scalarNode('null_value')->end()
->arrayNode('fields')
->useAttributeAsKey('name')
->prototype('array')
->treatNullLike(array())
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue('string')->end()
->scalarNode('boost')->end()
->scalarNode('store')->end()
->scalarNode('index')->end()
->scalarNode('analyzer')->end()
->scalarNode('term_vector')->end()
->scalarNode('null_value')->end()
->prototype('array')
->children()
->scalarNode('match')->end()
->scalarNode('unmatch')->end()
->scalarNode('match_mapping_type')->end()
->scalarNode('path_match')->end()
->scalarNode('path_unmatch')->end()
->scalarNode('match_pattern')->end()
->arrayNode('mapping')
->prototype('variable')
->treatNullLike(array())
->end()
->end()
->end()
@ -259,6 +322,23 @@ class Configuration
return $node;
}
/**
* Returns the array node used for "_id".
*/
protected function getIdNode()
{
$builder = new TreeBuilder();
$node = $builder->root('_id');
$node
->children()
->scalarNode('path')->end()
->end()
;
return $node;
}
/**
* Returns the array node used for "_source".
*/
@ -277,9 +357,225 @@ class Configuration
->useAttributeAsKey('name')
->prototype('scalar')->end()
->end()
->scalarNode('compress')->end()
->scalarNode('compress_threshold')->end()
->scalarNode('enabled')->defaultTrue()->end()
->end()
;
return $node;
}
/**
* Returns the array node used for "_boost".
*/
protected function getBoostNode()
{
$builder = new TreeBuilder();
$node = $builder->root('_boost');
$node
->children()
->scalarNode('name')->end()
->scalarNode('null_value')->end()
->end()
;
return $node;
}
/**
* Returns the array node used for "_routing".
*/
protected function getRoutingNode()
{
$builder = new TreeBuilder();
$node = $builder->root('_routing');
$node
->children()
->scalarNode('required')->end()
->scalarNode('path')->end()
->end()
;
return $node;
}
/**
* Returns the array node used for "_parent".
*/
protected function getParentNode()
{
$builder = new TreeBuilder();
$node = $builder->root('_parent');
$node
->children()
->scalarNode('type')->end()
->scalarNode('property')->defaultValue(null)->end()
->scalarNode('identifier')->defaultValue('id')->end()
->end()
;
return $node;
}
/**
* Returns the array node used for "_all".
*/
protected function getAllNode()
{
$builder = new TreeBuilder();
$node = $builder->root('_all');
$node
->children()
->scalarNode('enabled')->defaultValue(true)->end()
->scalarNode('index_analyzer')->end()
->scalarNode('search_analyzer')->end()
->end()
;
return $node;
}
/**
* Returns the array node used for "_timestamp".
*/
protected function getTimestampNode()
{
$builder = new TreeBuilder();
$node = $builder->root('_timestamp');
$node
->children()
->scalarNode('enabled')->defaultValue(true)->end()
->scalarNode('path')->end()
->scalarNode('format')->end()
->scalarNode('store')->end()
->scalarNode('index')->end()
->end()
;
return $node;
}
/**
* Returns the array node used for "_ttl".
*/
protected function getTtlNode()
{
$builder = new TreeBuilder();
$node = $builder->root('_ttl');
$node
->children()
->scalarNode('enabled')->defaultValue(true)->end()
->scalarNode('default')->end()
->scalarNode('store')->end()
->scalarNode('index')->end()
->end()
;
return $node;
}
/**
* @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
*/
protected function getPersistenceNode()
{
$builder = new TreeBuilder();
$node = $builder->root('persistence');
$node
->validate()
->ifTrue(function ($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['listener']); })
->thenInvalid('Propel doesn\'t support listeners')
->ifTrue(function ($v) { return isset($v['driver']) && 'propel' === $v['driver'] && isset($v['repository']); })
->thenInvalid('Propel doesn\'t support the "repository" parameter')
->end()
->children()
->scalarNode('driver')
->validate()
->ifNotInArray($this->supportedDrivers)
->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($this->supportedDrivers))
->end()
->end()
->scalarNode('model')->end()
->scalarNode('repository')->end()
->scalarNode('identifier')->defaultValue('id')->end()
->arrayNode('provider')
->children()
->scalarNode('batch_size')->defaultValue(100)->end()
->scalarNode('clear_object_manager')->defaultTrue()->end()
->scalarNode('debug_logging')
->defaultValue($this->debug)
->treatNullLike(true)
->end()
->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('listener')
->children()
->scalarNode('insert')->defaultTrue()->end()
->scalarNode('update')->defaultTrue()->end()
->scalarNode('delete')->defaultTrue()->end()
->scalarNode('flush')->defaultTrue()->end()
->booleanNode('immediate')->defaultFalse()->end()
->scalarNode('logger')
->defaultFalse()
->treatNullLike('fos_elastica.logger')
->treatTrueLike('fos_elastica.logger')
->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('finder')
->children()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('elastica_to_model_transformer')
->addDefaultsIfNotSet()
->children()
->scalarNode('hydrate')->defaultTrue()->end()
->scalarNode('ignore_missing')->defaultFalse()->end()
->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
->scalarNode('service')->end()
->end()
->end()
->arrayNode('model_to_elastica_transformer')
->addDefaultsIfNotSet()
->children()
->scalarNode('service')->end()
->end()
->end()
->end();
return $node;
}
/**
* @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
*/
protected function getSerializerNode()
{
$builder = new TreeBuilder();
$node = $builder->root('serializer');
$node
->addDefaultsIfNotSet()
->children()
->arrayNode('groups')
->treatNullLike(array())
->prototype('scalar')->end()
->end()
->scalarNode('version')->end()
->end();
return $node;
}
}

View file

@ -2,11 +2,9 @@
namespace FOS\ElasticaBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Config\FileLocator;
@ -14,21 +12,42 @@ use InvalidArgumentException;
class FOSElasticaExtension extends Extension
{
protected $indexConfigs = array();
protected $typeFields = array();
protected $loadedDrivers = array();
/**
* Definition of elastica clients as configured by this extension.
*
* @var array
*/
private $clients = array();
/**
* An array of indexes as configured by the extension.
*
* @var array
*/
private $indexConfigs = array();
/**
* If we've encountered a type mapped to a specific persistence driver, it will be loaded
* here.
*
* @var array
*/
private $loadedDrivers = array();
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$processor = new Processor();
$config = $processor->process($configuration->getConfigTree(), $configs);
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('config.xml');
if (empty($config['clients']) || empty($config['indexes'])) {
throw new InvalidArgumentException('You must define at least one client and one index');
// No Clients or indexes are defined
return;
}
foreach (array('config', 'index', 'persister', 'provider', 'source', 'transformer') as $basename) {
$loader->load(sprintf('%s.xml', $basename));
}
if (empty($config['default_client'])) {
@ -41,197 +60,277 @@ class FOSElasticaExtension extends Extension
$config['default_index'] = reset($keys);
}
$clientIdsByName = $this->loadClients($config['clients'], $container);
$indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client']);
$indexDefsByName = array_map(function($id) use ($container) {
return $container->getDefinition($id);
}, $indexIdsByName);
if (isset($config['serializer'])) {
$loader->load('serializer.xml');
$this->loadIndexManager($indexDefsByName, $container->getDefinition($indexIdsByName[$config['default_index']]), $container);
$this->loadReseter($this->indexConfigs, $container);
$this->loadSerializer($config['serializer'], $container);
}
$this->loadClients($config['clients'], $container);
$container->setAlias('fos_elastica.client', sprintf('fos_elastica.client.%s', $config['default_client']));
$this->loadIndexes($config['indexes'], $container);
$container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index']));
$container->getDefinition('fos_elastica.config_source.container')->replaceArgument(0, $this->indexConfigs);
$this->loadIndexManager($container);
$this->createDefaultManagerAlias($config['default_manager'], $container);
}
/**
* @param array $config
* @param ContainerBuilder $container
*
* @return Configuration
*/
public function getConfiguration(array $config, ContainerBuilder $container)
{
return new Configuration($container->getParameter('kernel.debug'));
}
/**
* Loads the configured clients.
*
* @param array $config An array of clients configurations
* @param array $clients An array of clients configurations
* @param ContainerBuilder $container A ContainerBuilder instance
*
* @return array
*/
protected function loadClients(array $clients, ContainerBuilder $container)
private function loadClients(array $clients, ContainerBuilder $container)
{
$clientIds = array();
foreach ($clients as $name => $clientConfig) {
$clientDef = $container->getDefinition('fos_elastica.client');
$clientId = sprintf('fos_elastica.client.%s', $name);
$clientDef = new DefinitionDecorator('fos_elastica.client_prototype');
$clientDef->replaceArgument(0, $clientConfig);
$clientId = sprintf('fos_elastica.client.%s', $name);
$logger = $clientConfig['connections'][0]['logger'];
if (false !== $logger) {
$clientDef->addMethodCall('setLogger', array(new Reference($logger)));
}
$clientDef->addTag('fos_elastica.client');
$container->setDefinition($clientId, $clientDef);
$clientIds[$name] = $clientId;
$this->clients[$name] = array(
'id' => $clientId,
'reference' => new Reference($clientId),
);
}
return $clientIds;
}
/**
* Loads the configured indexes.
*
* @param array $config An array of indexes configurations
* @param array $indexes An array of indexes configurations
* @param ContainerBuilder $container A ContainerBuilder instance
*
* @throws \InvalidArgumentException
*
* @return array
*/
protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName)
private function loadIndexes(array $indexes, ContainerBuilder $container)
{
$indexIds = array();
$indexableCallbacks = array();
foreach ($indexes as $name => $index) {
$indexId = sprintf('fos_elastica.index.%s', $name);
$indexName = isset($index['index_name']) ? $index['index_name'] : $name;
$indexDef = new DefinitionDecorator('fos_elastica.index_prototype');
$indexDef->replaceArgument(0, $indexName);
$indexDef->addTag('fos_elastica.index', array(
'name' => $name,
));
if (isset($index['client'])) {
$clientName = $index['client'];
if (!isset($clientIdsByName[$clientName])) {
throw new InvalidArgumentException(sprintf('The elastica client with name "%s" is not defined', $clientName));
}
} else {
$clientName = $defaultClientName;
$client = $this->getClient($index['client']);
$indexDef->setFactoryService($client);
}
$clientId = $clientIdsByName[$clientName];
$indexId = sprintf('fos_elastica.index.%s', $name);
$indexDefArgs = array($name);
$indexDef = new Definition('%fos_elastica.index.class%', $indexDefArgs);
$indexDef->setFactoryService($clientId);
$indexDef->setFactoryMethod('getIndex');
$container->setDefinition($indexId, $indexDef);
$typePrototypeConfig = isset($index['type_prototype']) ? $index['type_prototype'] : array();
$indexIds[$name] = $indexId;
$reference = new Reference($indexId);
$this->indexConfigs[$name] = array(
'index' => new Reference($indexId),
'config' => array(
'mappings' => array()
)
'elasticsearch_name' => $indexName,
'reference' => $reference,
'name' => $name,
'settings' => $index['settings'],
'type_prototype' => isset($index['type_prototype']) ? $index['type_prototype'] : array(),
'use_alias' => $index['use_alias'],
);
if ($index['finder']) {
$this->loadIndexFinder($container, $name, $indexId);
$this->loadIndexFinder($container, $name, $reference);
}
if (!empty($index['settings'])) {
$this->indexConfigs[$name]['config']['settings'] = $index['settings'];
}
$this->loadTypes(isset($index['types']) ? $index['types'] : array(), $container, $name, $indexId, $typePrototypeConfig);
$this->loadTypes((array) $index['types'], $container, $this->indexConfigs[$name], $indexableCallbacks);
}
return $indexIds;
$indexable = $container->getDefinition('fos_elastica.indexable');
$indexable->replaceArgument(0, $indexableCallbacks);
}
/**
* Loads the configured index finders.
*
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
* @param string $name The index name
* @param string $indexId The index service identifier
* @param string $name The index name
* @param Reference $index Reference to the related index
*
* @return string
*/
protected function loadIndexFinder(ContainerBuilder $container, $name, $indexId)
private function loadIndexFinder(ContainerBuilder $container, $name, Reference $index)
{
$abstractTransformerId = 'fos_elastica.elastica_to_model_transformer.collection.prototype';
/* Note: transformer services may conflict with "collection.index", if
* an index and type names were "collection" and an index, respectively.
*/
$transformerId = sprintf('fos_elastica.elastica_to_model_transformer.collection.%s', $name);
$transformerDef = new DefinitionDecorator($abstractTransformerId);
$transformerDef = new DefinitionDecorator('fos_elastica.elastica_to_model_transformer.collection');
$container->setDefinition($transformerId, $transformerDef);
$abstractFinderId = 'fos_elastica.finder.prototype';
$finderId = sprintf('fos_elastica.finder.%s', $name);
$finderDef = new DefinitionDecorator($abstractFinderId);
$finderDef->replaceArgument(0, new Reference($indexId));
$finderDef = new DefinitionDecorator('fos_elastica.finder');
$finderDef->replaceArgument(0, $index);
$finderDef->replaceArgument(1, new Reference($transformerId));
$container->setDefinition($finderId, $finderDef);
return $finderId;
}
/**
* Loads the configured types.
*
* @param array $config An array of types configurations
* @param ContainerBuilder $container A ContainerBuilder instance
* @param array $types
* @param ContainerBuilder $container
* @param array $indexConfig
* @param array $indexableCallbacks
*/
protected function loadTypes(array $types, ContainerBuilder $container, $indexName, $indexId, array $typePrototypeConfig)
private function loadTypes(array $types, ContainerBuilder $container, array $indexConfig, array &$indexableCallbacks)
{
foreach ($types as $name => $type) {
$type = self::deepArrayUnion($typePrototypeConfig, $type);
$typeId = sprintf('%s.%s', $indexId, $name);
$typeDefArgs = array($name);
$typeDef = new Definition('%fos_elastica.type.class%', $typeDefArgs);
$typeDef->setFactoryService($indexId);
$typeDef->setFactoryMethod('getType');
$indexName = $indexConfig['name'];
$typeId = sprintf('%s.%s', $indexConfig['reference'], $name);
$typeDef = new DefinitionDecorator('fos_elastica.type_prototype');
$typeDef->replaceArgument(0, $name);
$typeDef->setFactoryService($indexConfig['reference']);
$container->setDefinition($typeId, $typeDef);
if (isset($type['_source'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['_source'] = $type['_source'];
$typeConfig = array(
'name' => $name,
'mapping' => array(), // An array containing anything that gets sent directly to ElasticSearch
'config' => array(),
);
foreach (array(
'dynamic_templates',
'properties',
'_all',
'_boost',
'_id',
'_parent',
'_routing',
'_source',
'_timestamp',
'_ttl',
) as $field) {
if (isset($type[$field])) {
$typeConfig['mapping'][$field] = $type[$field];
}
}
if (isset($type['mappings'])) {
$this->indexConfigs[$indexName]['config']['mappings'][$name]['properties'] = $type['mappings'];
$typeName = sprintf('%s/%s', $indexName, $name);
$this->typeFields[$typeName] = array_keys($type['mappings']);
foreach (array(
'persistence',
'serializer',
'index_analyzer',
'search_analyzer',
'date_detection',
'dynamic_date_formats',
'numeric_detection',
) as $field) {
$typeConfig['config'][$field] = array_key_exists($field, $type) ?
$type[$field] :
null;
}
$this->indexConfigs[$indexName]['types'][$name] = $typeConfig;
if (isset($type['persistence'])) {
$this->loadTypePersistenceIntegration($type['persistence'], $container, $typeDef, $indexName, $name);
$this->loadTypePersistenceIntegration($type['persistence'], $container, new Reference($typeId), $indexName, $name);
$typeConfig['persistence'] = $type['persistence'];
}
if (isset($type['indexable_callback'])) {
$indexableCallbacks[sprintf('%s/%s', $indexName, $name)] = $type['indexable_callback'];
}
if ($container->hasDefinition('fos_elastica.serializer_callback_prototype')) {
$typeSerializerId = sprintf('%s.serializer.callback', $typeId);
$typeSerializerDef = new DefinitionDecorator('fos_elastica.serializer_callback_prototype');
if (isset($type['serializer']['groups'])) {
$typeSerializerDef->addMethodCall('setGroups', array($type['serializer']['groups']));
}
if (isset($type['serializer']['version'])) {
$typeSerializerDef->addMethodCall('setVersion', array($type['serializer']['version']));
}
$typeDef->addMethodCall('setSerializer', array(array(new Reference($typeSerializerId), 'serialize')));
$container->setDefinition($typeSerializerId, $typeSerializerDef);
}
}
}
/**
* Merges two arrays without reindexing numeric keys.
* Loads the optional provider and finder for a type.
*
* @param array $array1 An array to merge
* @param array $array2 An array to merge
*
* @return array The merged array
* @param array $typeConfig
* @param ContainerBuilder $container
* @param Reference $typeRef
* @param string $indexName
* @param string $typeName
*/
static protected function deepArrayUnion($array1, $array2)
{
foreach ($array2 as $key => $value) {
if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])) {
$array1[$key] = self::deepArrayUnion($array1[$key], $value);
} else {
$array1[$key] = $value;
}
}
return $array1;
}
/**
* Loads the optional provider and finder for a type
*
* @return null
**/
protected function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Definition $typeDef, $indexName, $typeName)
private function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Reference $typeRef, $indexName, $typeName)
{
$this->loadDriver($container, $typeConfig['driver']);
$elasticaToModelTransformerId = $this->loadElasticaToModelTransformer($typeConfig, $container, $indexName, $typeName);
$modelToElasticaTransformerId = $this->loadModelToElasticaTransformer($typeConfig, $container, $indexName, $typeName);
$objectPersisterId = $this->loadObjectPersister($typeConfig, $typeDef, $container, $indexName, $typeName, $modelToElasticaTransformerId);
$objectPersisterId = $this->loadObjectPersister($typeConfig, $typeRef, $container, $indexName, $typeName, $modelToElasticaTransformerId);
if (isset($typeConfig['provider'])) {
$providerId = $this->loadTypeProvider($typeConfig, $container, $objectPersisterId, $typeDef, $indexName, $typeName);
$container->getDefinition('fos_elastica.populator')->addMethodCall('addProvider', array($providerId, new Reference($providerId)));
$this->loadTypeProvider($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
}
if (isset($typeConfig['finder'])) {
$this->loadTypeFinder($typeConfig, $container, $elasticaToModelTransformerId, $typeDef, $indexName, $typeName);
$this->loadTypeFinder($typeConfig, $container, $elasticaToModelTransformerId, $typeRef, $indexName, $typeName);
}
if (isset($typeConfig['listener'])) {
$this->loadTypeListener($typeConfig, $container, $objectPersisterId, $typeDef, $indexName, $typeName);
$this->loadTypeListener($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
}
}
protected function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
/**
* Creates and loads an ElasticaToModelTransformer.
*
* @param array $typeConfig
* @param ContainerBuilder $container
* @param string $indexName
* @param string $typeName
*
* @return string
*/
private function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
{
if (isset($typeConfig['elastica_to_model_transformer']['service'])) {
return $typeConfig['elastica_to_model_transformer']['service'];
}
/* Note: transformer services may conflict with "prototype.driver", if
* the index and type names were "prototype" and a driver, respectively.
*/
$abstractId = sprintf('fos_elastica.elastica_to_model_transformer.prototype.%s', $typeConfig['driver']);
$serviceId = sprintf('fos_elastica.elastica_to_model_transformer.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
@ -241,102 +340,201 @@ class FOSElasticaExtension extends Extension
$argPos = ('propel' === $typeConfig['driver']) ? 0 : 1;
$serviceDef->replaceArgument($argPos, $typeConfig['model']);
$serviceDef->replaceArgument($argPos + 1, array(
'identifier' => $typeConfig['identifier'],
'hydrate' => $typeConfig['elastica_to_model_transformer']['hydrate']
));
$serviceDef->replaceArgument($argPos + 1, array_merge($typeConfig['elastica_to_model_transformer'], array(
'identifier' => $typeConfig['identifier'],
)));
$container->setDefinition($serviceId, $serviceDef);
return $serviceId;
}
protected function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
/**
* Creates and loads a ModelToElasticaTransformer for an index/type.
*
* @param array $typeConfig
* @param ContainerBuilder $container
* @param string $indexName
* @param string $typeName
*
* @return string
*/
private function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
{
if (isset($typeConfig['model_to_elastica_transformer']['service'])) {
return $typeConfig['model_to_elastica_transformer']['service'];
}
$abstractId = sprintf('fos_elastica.model_to_elastica_transformer.prototype.auto');
$abstractId = $container->hasDefinition('fos_elastica.serializer_callback_prototype') ?
'fos_elastica.model_to_elastica_identifier_transformer' :
'fos_elastica.model_to_elastica_transformer';
$serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
$serviceDef->replaceArgument(0, array(
'identifier' => $typeConfig['identifier']
'identifier' => $typeConfig['identifier'],
));
$container->setDefinition($serviceId, $serviceDef);
return $serviceId;
}
protected function loadObjectPersister(array $typeConfig, Definition $typeDef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
/**
* Creates and loads an object persister for a type.
*
* @param array $typeConfig
* @param Reference $typeRef
* @param ContainerBuilder $container
* @param string $indexName
* @param string $typeName
* @param string $transformerId
*
* @return string
*/
private function loadObjectPersister(array $typeConfig, Reference $typeRef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
{
$abstractId = sprintf('fos_elastica.object_persister.prototype');
$arguments = array(
$typeRef,
new Reference($transformerId),
$typeConfig['model'],
);
if ($container->hasDefinition('fos_elastica.serializer_callback_prototype')) {
$abstractId = 'fos_elastica.object_serializer_persister';
$callbackId = sprintf('%s.%s.serializer.callback', $this->indexConfigs[$indexName]['reference'], $typeName);
$arguments[] = array(new Reference($callbackId), 'serialize');
} else {
$abstractId = 'fos_elastica.object_persister';
$mapping = $this->indexConfigs[$indexName]['types'][$typeName]['mapping'];
$argument = $mapping['properties'];
if (isset($mapping['_parent'])) {
$argument['_parent'] = $mapping['_parent'];
}
$arguments[] = $argument;
}
$serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
$serviceDef = new DefinitionDecorator($abstractId);
$serviceDef->replaceArgument(0, $typeDef);
$serviceDef->replaceArgument(1, new Reference($transformerId));
$serviceDef->replaceArgument(2, $typeConfig['model']);
$serviceDef->replaceArgument(3, $this->typeFields[sprintf('%s/%s', $indexName, $typeName)]);
foreach ($arguments as $i => $argument) {
$serviceDef->replaceArgument($i, $argument);
}
$container->setDefinition($serviceId, $serviceDef);
return $serviceId;
}
protected function loadTypeProvider(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $typeDef, $indexName, $typeName)
/**
* Loads a provider for a type.
*
* @param array $typeConfig
* @param ContainerBuilder $container
* @param string $objectPersisterId
* @param string $indexName
* @param string $typeName
*
* @return string
*/
private function loadTypeProvider(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
{
if (isset($typeConfig['provider']['service'])) {
return $typeConfig['provider']['service'];
}
$abstractProviderId = sprintf('fos_elastica.provider.prototype.%s', $typeConfig['driver']);
/* Note: provider services may conflict with "prototype.driver", if the
* index and type names were "prototype" and a driver, respectively.
*/
$providerId = sprintf('fos_elastica.provider.%s.%s', $indexName, $typeName);
$providerDef = new DefinitionDecorator($abstractProviderId);
$providerDef->replaceArgument(0, $typeDef);
// Doctrine has a mandatory service as second argument
$argPos = ('propel' === $typeConfig['driver']) ? 1 : 2;
$providerDef->replaceArgument($argPos, new Reference($objectPersisterId));
$providerDef->replaceArgument($argPos + 1, $typeConfig['model']);
$options = array('batch_size' => $typeConfig['provider']['batch_size']);
if ('propel' !== $typeConfig['driver']) {
$options['query_builder_method'] = $typeConfig['provider']['query_builder_method'];
$options['clear_object_manager'] = $typeConfig['provider']['clear_object_manager'];
}
$providerDef->replaceArgument($argPos + 2, $options);
$providerDef = new DefinitionDecorator('fos_elastica.provider.prototype.'.$typeConfig['driver']);
$providerDef->addTag('fos_elastica.provider', array('index' => $indexName, 'type' => $typeName));
$providerDef->replaceArgument(0, new Reference($objectPersisterId));
$providerDef->replaceArgument(2, $typeConfig['model']);
// Propel provider can simply ignore Doctrine-specific options
$providerDef->replaceArgument(3, array_merge(array_diff_key($typeConfig['provider'], array('service' => 1)), array(
'indexName' => $indexName,
'typeName' => $typeName,
)));
$container->setDefinition($providerId, $providerDef);
return $providerId;
}
protected function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $typeDef, $indexName, $typeName)
/**
* Loads doctrine listeners to handle indexing of new or updated objects.
*
* @param array $typeConfig
* @param ContainerBuilder $container
* @param string $objectPersisterId
* @param string $indexName
* @param string $typeName
*
* @return string
*/
private function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
{
if (isset($typeConfig['listener']['service'])) {
return $typeConfig['listener']['service'];
}
/* Note: listener services may conflict with "prototype.driver", if the
* index and type names were "prototype" and a driver, respectively.
*/
$abstractListenerId = sprintf('fos_elastica.listener.prototype.%s', $typeConfig['driver']);
$listenerId = sprintf('fos_elastica.listener.%s.%s', $indexName, $typeName);
$listenerDef = new DefinitionDecorator($abstractListenerId);
$listenerDef->replaceArgument(0, new Reference($objectPersisterId));
$listenerDef->replaceArgument(1, $typeConfig['model']);
$listenerDef->replaceArgument(3, $typeConfig['identifier']);
$listenerDef->replaceArgument(2, $this->getDoctrineEvents($typeConfig));
$listenerDef->replaceArgument(2, array(
'identifier' => $typeConfig['identifier'],
'indexName' => $indexName,
'typeName' => $typeName,
));
$listenerDef->replaceArgument(3, $typeConfig['listener']['logger'] ?
new Reference($typeConfig['listener']['logger']) :
null
);
$tagName = null;
switch ($typeConfig['driver']) {
case 'orm': $listenerDef->addTag('doctrine.event_subscriber'); break;
case 'mongodb': $listenerDef->addTag('doctrine.common.event_subscriber'); break;
case 'orm':
$tagName = 'doctrine.event_listener';
break;
case 'mongodb':
$tagName = 'doctrine_mongodb.odm.event_listener';
break;
}
if (null !== $tagName) {
foreach ($this->getDoctrineEvents($typeConfig) as $event) {
$listenerDef->addTag($tagName, array('event' => $event));
}
}
$container->setDefinition($listenerId, $listenerDef);
return $listenerId;
}
/**
* Map Elastica to Doctrine events for the current driver.
*/
private function getDoctrineEvents(array $typeConfig)
{
switch ($typeConfig['driver']) {
case 'orm':
$eventsClass = '\Doctrine\ORM\Events';
break;
case 'mongodb':
$eventsClass = '\Doctrine\ODM\MongoDB\Events';
break;
default:
throw new InvalidArgumentException(sprintf('Cannot determine events for driver "%s"', $typeConfig['driver']));
}
$events = array();
$eventMapping = array(
'insert' => array('postPersist'),
'update' => array('postUpdate'),
'delete' => array('postRemove', 'preRemove')
'insert' => array(constant($eventsClass.'::postPersist')),
'update' => array(constant($eventsClass.'::postUpdate')),
'delete' => array(constant($eventsClass.'::preRemove')),
'flush' => array($typeConfig['listener']['immediate'] ? constant($eventsClass.'::preFlush') : constant($eventsClass.'::postFlush')),
);
foreach ($eventMapping as $event => $doctrineEvents) {
@ -348,64 +546,99 @@ class FOSElasticaExtension extends Extension
return $events;
}
protected function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, $typeDef, $indexName, $typeName)
/**
* Loads a Type specific Finder.
*
* @param array $typeConfig
* @param ContainerBuilder $container
* @param string $elasticaToModelId
* @param Reference $typeRef
* @param string $indexName
* @param string $typeName
*
* @return string
*/
private function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, Reference $typeRef, $indexName, $typeName)
{
if (isset($typeConfig['finder']['service'])) {
return $typeConfig['finder']['service'];
$finderId = $typeConfig['finder']['service'];
} else {
$finderId = sprintf('fos_elastica.finder.%s.%s', $indexName, $typeName);
$finderDef = new DefinitionDecorator('fos_elastica.finder');
$finderDef->replaceArgument(0, $typeRef);
$finderDef->replaceArgument(1, new Reference($elasticaToModelId));
$container->setDefinition($finderId, $finderDef);
}
$abstractFinderId = 'fos_elastica.finder.prototype';
$finderId = sprintf('fos_elastica.finder.%s.%s', $indexName, $typeName);
$finderDef = new DefinitionDecorator($abstractFinderId);
$finderDef->replaceArgument(0, $typeDef);
$finderDef->replaceArgument(1, new Reference($elasticaToModelId));
$container->setDefinition($finderId, $finderDef);
$managerId = sprintf('fos_elastica.manager.%s', $typeConfig['driver']);
$managerId = sprintf('fos_elastica.manager.%s', $typeConfig['driver']);
$managerDef = $container->getDefinition($managerId);
$arguments = array( $typeConfig['model'], new Reference($finderId));
if (isset($typeConfig['repository'])) {
$arguments[] = $typeConfig['repository'];
}
$managerDef->addMethodCall('addEntity', $arguments);
return $finderId;
}
/**
* Loads the index manager
* Loads the index manager.
*
* @return null
* @param ContainerBuilder $container
**/
protected function loadIndexManager(array $indexDefs, $defaultIndexId, ContainerBuilder $container)
private function loadIndexManager(ContainerBuilder $container)
{
$indexRefs = array_map(function ($index) {
return $index['reference'];
}, $this->indexConfigs);
$managerDef = $container->getDefinition('fos_elastica.index_manager');
$managerDef->replaceArgument(0, $indexDefs);
$managerDef->replaceArgument(1, new Reference('fos_elastica.index'));
$managerDef->replaceArgument(0, $indexRefs);
}
/**
* Loads the reseter
* Makes sure a specific driver has been loaded.
*
* @return null
**/
protected function loadReseter(array $indexConfigs, ContainerBuilder $container)
{
$reseterDef = $container->getDefinition('fos_elastica.reseter');
$reseterDef->replaceArgument(0, $indexConfigs);
}
protected function loadDriver(ContainerBuilder $container, $driver)
* @param ContainerBuilder $container
* @param string $driver
*/
private function loadDriver(ContainerBuilder $container, $driver)
{
if (in_array($driver, $this->loadedDrivers)) {
return;
}
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load($driver.'.xml');
$this->loadedDrivers[] = $driver;
}
protected function createDefaultManagerAlias($defaultManager, ContainerBuilder $container)
/**
* Loads and configures the serializer prototype.
*
* @param array $config
* @param ContainerBuilder $container
*/
private function loadSerializer($config, ContainerBuilder $container)
{
$container->setAlias('fos_elastica.serializer', $config['serializer']);
$serializer = $container->getDefinition('fos_elastica.serializer_callback_prototype');
$serializer->setClass($config['callback_class']);
$callbackClassImplementedInterfaces = class_implements($config['callback_class']);
if (isset($callbackClassImplementedInterfaces['Symfony\Component\DependencyInjection\ContainerAwareInterface'])) {
$serializer->addMethodCall('setContainer', array(new Reference('service_container')));
}
}
/**
* Creates a default manager alias for defined default manager or the first loaded driver.
*
* @param string $defaultManager
* @param ContainerBuilder $container
*/
private function createDefaultManagerAlias($defaultManager, ContainerBuilder $container)
{
if (0 == count($this->loadedDrivers)) {
return;
@ -422,4 +655,21 @@ class FOSElasticaExtension extends Extension
$container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService));
}
/**
* Returns a reference to a client given its configured name.
*
* @param string $clientName
*
* @return Reference
*
* @throws \InvalidArgumentException
*/
private function getClient($clientName)
{
if (!array_key_exists($clientName, $this->clients)) {
throw new InvalidArgumentException(sprintf('The elastica client with name "%s" is not defined', $clientName));
}
return $this->clients[$clientName]['reference'];
}
}

View file

@ -2,52 +2,56 @@
namespace FOS\ElasticaBundle\Doctrine;
use Doctrine\Common\Persistence\ManagerRegistry;
use FOS\ElasticaBundle\HybridResult;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use FOS\ElasticaBundle\Transformer\AbstractElasticaToModelTransformer as BaseTransformer;
use FOS\ElasticaBundle\Transformer\HighlightableModelInterface;
use Elastica_Document;
/**
* Maps Elastica documents with Doctrine objects
* This mapper assumes an exact match between
* elastica documents ids and doctrine object ids
* elastica documents ids and doctrine object ids.
*/
abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTransformerInterface
abstract class AbstractElasticaToModelTransformer extends BaseTransformer
{
/**
* Repository to fetch the objects from
* Manager registry.
*
* @var ManagerRegistry
*/
protected $objectManager = null;
protected $registry = null;
/**
* Class of the model to map to the elastica documents
* Class of the model to map to the elastica documents.
*
* @var string
*/
protected $objectClass = null;
/**
* Optional parameters
* Optional parameters.
*
* @var array
*/
protected $options = array(
'hydrate' => true,
'identifier' => 'id'
'hydrate' => true,
'identifier' => 'id',
'ignore_missing' => false,
'query_builder_method' => 'createQueryBuilder',
);
/**
* Instantiates a new Mapper
* Instantiates a new Mapper.
*
* @param object $objectManager
* @param ManagerRegistry $registry
* @param string $objectClass
* @param array $options
* @param array $options
*/
public function __construct($objectManager, $objectClass, array $options = array())
public function __construct(ManagerRegistry $registry, $objectClass, array $options = array())
{
$this->objectManager = $objectManager;
$this->objectClass = $objectClass;
$this->options = array_merge($this->options, $options);
$this->registry = $registry;
$this->objectClass = $objectClass;
$this->options = array_merge($this->options, $options);
}
/**
@ -62,9 +66,12 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
/**
* Transforms an array of elastica objects into an array of
* model objects fetched from the doctrine repository
* model objects fetched from the doctrine repository.
*
* @param array $elasticaObjects of elastica objects
*
* @throws \RuntimeException
*
* @param array of elastica objects
* @return array
**/
public function transform(array $elasticaObjects)
@ -76,7 +83,7 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
}
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
if (count($objects) < count($elasticaObjects)) {
if (!$this->options['ignore_missing'] && count($objects) < count($elasticaObjects)) {
throw new \RuntimeException('Cannot find corresponding Doctrine objects for all Elastica results.');
};
@ -86,32 +93,34 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
}
}
$identifierGetter = 'get'.ucfirst($this->options['identifier']);
// sort objects in the order of ids
$idPos = array_flip($ids);
usort($objects, function($a, $b) use ($idPos, $identifierGetter)
{
return $idPos[$a->$identifierGetter()] > $idPos[$b->$identifierGetter()];
});
$identifier = $this->options['identifier'];
usort($objects, $this->getSortingClosure($idPos, $identifier));
return $objects;
}
public function hybridTransform(array $elasticaObjects)
{
$indexedElasticaResults = array();
foreach ($elasticaObjects as $elasticaObject) {
$indexedElasticaResults[$elasticaObject->getId()] = $elasticaObject;
}
$objects = $this->transform($elasticaObjects);
$result = array();
for ($i = 0; $i < count($elasticaObjects); $i++) {
$result[] = new HybridResult($elasticaObjects[$i], $objects[$i]);
foreach ($objects as $object) {
$id = $this->propertyAccessor->getValue($object, $this->options['identifier']);
$result[] = new HybridResult($indexedElasticaResults[$id], $object);
}
return $result;
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function getIdentifierField()
{
@ -119,11 +128,12 @@ abstract class AbstractElasticaToModelTransformer implements ElasticaToModelTran
}
/**
* Fetches objects by theses identifier values
* Fetches objects by theses identifier values.
*
* @param array $identifierValues ids values
* @param Boolean $hydrate whether or not to hydrate the objects, false returns arrays
*
* @param array $identifierValues ids values
* @param Boolean $hydrate whether or not to hydrate the objects, false returns arrays
* @return array of objects or arrays
*/
protected abstract function findByIdentifiers(array $identifierValues, $hydrate);
abstract protected function findByIdentifiers(array $identifierValues, $hydrate);
}

View file

@ -1,69 +0,0 @@
<?php
namespace FOS\ElasticaBundle\Doctrine;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
abstract class AbstractListener
{
/**
* Object persister
*
* @var ObjectPersister
*/
protected $objectPersister;
/**
* Class of the domain model
*
* @var string
*/
protected $objectClass;
/**
* List of subscribed events
*
* @var array
*/
protected $events;
protected $esIdentifierField;
protected $scheduledForRemoval;
/**
* Constructor
**/
public function __construct(ObjectPersisterInterface $objectPersister, $objectClass, array $events, $esIdentifierField = 'id')
{
$this->objectPersister = $objectPersister;
$this->objectClass = $objectClass;
$this->events = $events;
$this->esIdentifierField = $esIdentifierField;
$this->scheduledForRemoval = array();
}
/**
* @return array
*/
public function getSubscribedEvents()
{
return $this->events;
}
protected function scheduleForRemoval($object, $objectManager)
{
$metadata = $objectManager->getClassMetadata($this->objectClass);
$esId = $metadata->getFieldValue($object, $this->esIdentifierField);
$this->scheduledForRemoval[spl_object_hash($object)] = $esId;
}
protected function removeIfScheduled($object)
{
$objectHash = spl_object_hash($object);
if (isset($this->scheduledForRemoval[$objectHash])) {
$this->objectPersister->deleteById($this->scheduledForRemoval[$objectHash]);
unset($this->scheduledForRemoval[$objectHash]);
}
}
}

View file

@ -2,106 +2,169 @@
namespace FOS\ElasticaBundle\Doctrine;
use FOS\ElasticaBundle\Provider\ProviderInterface;
use Doctrine\Common\Persistence\ManagerRegistry;
use Elastica\Exception\Bulk\ResponseException as BulkResponseException;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use Elastica_Type;
use Elastica_Document;
use Closure;
use InvalidArgumentException;
use FOS\ElasticaBundle\Provider\AbstractProvider as BaseAbstractProvider;
use FOS\ElasticaBundle\Provider\IndexableInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
abstract class AbstractProvider implements ProviderInterface
abstract class AbstractProvider extends BaseAbstractProvider
{
/**
* Elastica type
*
* @var Elastica_Type
* @var SliceFetcherInterface
*/
protected $type;
private $sliceFetcher;
/**
* Domain model object manager
*
* @var object
* @var ManagerRegistry
*/
protected $objectManager;
protected $managerRegistry;
/**
* Object persister
* Constructor.
*
* @var ObjectPersisterInterface
* @param ObjectPersisterInterface $objectPersister
* @param IndexableInterface $indexable
* @param string $objectClass
* @param array $baseOptions
* @param ManagerRegistry $managerRegistry
* @param SliceFetcherInterface $sliceFetcher
*/
protected $objectPersister;
public function __construct(
ObjectPersisterInterface $objectPersister,
IndexableInterface $indexable,
$objectClass,
array $baseOptions,
ManagerRegistry $managerRegistry,
SliceFetcherInterface $sliceFetcher = null
) {
parent::__construct($objectPersister, $indexable, $objectClass, $baseOptions);
/**
* Provider options
*
* @var array
*/
protected $options = array(
'batch_size' => 100,
'clear_object_manager' => true,
'query_builder_method' => 'createQueryBuilder'
);
public function __construct(Elastica_Type $type, $objectManager, ObjectPersisterInterface $objectPersister, $objectClass, array $options = array())
{
$this->type = $type;
$this->objectManager = $objectManager;
$this->objectClass = $objectClass;
$this->objectPersister = $objectPersister;
$this->options = array_merge($this->options, $options);
$this->managerRegistry = $managerRegistry;
$this->sliceFetcher = $sliceFetcher;
}
/**
* Insert the repository objects in the type index
* Counts objects that would be indexed using the query builder.
*
* @param Closure $loggerClosure
* @param object $queryBuilder
*
* @return integer
*/
public function populate(Closure $loggerClosure)
abstract protected function countObjects($queryBuilder);
/**
* Creates the query builder, which will be used to fetch objects to index.
*
* @param string $method
*
* @return object
*/
abstract protected function createQueryBuilder($method);
/**
* Fetches a slice of objects using the query builder.
*
* @param object $queryBuilder
* @param integer $limit
* @param integer $offset
*
* @return array
*/
abstract protected function fetchSlice($queryBuilder, $limit, $offset);
/**
* {@inheritDoc}
*/
protected function doPopulate($options, \Closure $loggerClosure = null)
{
$queryBuilder = $this->createQueryBuilder();
$nbObjects = $this->countObjects($queryBuilder);
$manager = $this->managerRegistry->getManagerForClass($this->objectClass);
for ($offset = 0; $offset < $nbObjects; $offset += $this->options['batch_size']) {
$queryBuilder = $this->createQueryBuilder($options['query_builder_method']);
$nbObjects = $this->countObjects($queryBuilder);
$offset = $options['offset'];
$stepStartTime = microtime(true);
$objects = $this->fetchSlice($queryBuilder, $this->options['batch_size'], $offset);
$objects = array();
for (; $offset < $nbObjects; $offset += $options['batch_size']) {
try {
$objects = $this->getSlice($queryBuilder, $options['batch_size'], $offset, $objects);
$objects = $this->filterObjects($options, $objects);
$this->objectPersister->insertMany($objects);
if (!empty($objects)) {
$this->objectPersister->insertMany($objects);
}
} catch (BulkResponseException $e) {
if (!$options['ignore_errors']) {
throw $e;
}
if ($this->options['clear_object_manager']) {
$this->objectManager->clear();
if (null !== $loggerClosure) {
$loggerClosure(
$options['batch_size'],
$nbObjects,
sprintf('<error>%s</error>', $e->getMessage())
);
}
}
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects+$offset;
$objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
$loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s', 100*$stepCount/$nbObjects, $stepCount, $nbObjects, $objectsPerSecond));
if ($options['clear_object_manager']) {
$manager->clear();
}
usleep($options['sleep']);
if (null !== $loggerClosure) {
$loggerClosure($options['batch_size'], $nbObjects);
}
}
}
/**
* Counts the objects of a query builder
*
* @param queryBuilder
* @return int
**/
protected abstract function countObjects($queryBuilder);
* {@inheritDoc}
*/
protected function configureOptions()
{
parent::configureOptions();
$this->resolver->setDefaults(array(
'clear_object_manager' => true,
'debug_logging' => false,
'ignore_errors' => false,
'offset' => 0,
'query_builder_method' => 'createQueryBuilder',
'sleep' => 0
));
}
/**
* Fetches a slice of objects
* If this Provider has a SliceFetcher defined, we use it instead of falling back to
* the fetchSlice methods defined in the ORM/MongoDB subclasses.
*
* @param queryBuilder
* @param int limit
* @param int offset
* @return array of objects
**/
protected abstract function fetchSlice($queryBuilder, $limit, $offset);
* @param $queryBuilder
* @param int $limit
* @param int $offset
* @param array $lastSlice
*
* @return array
*/
private function getSlice($queryBuilder, $limit, $offset, $lastSlice)
{
if (!$this->sliceFetcher) {
return $this->fetchSlice($queryBuilder, $limit, $offset);
}
/**
* Creates the query builder used to fetch the documents to index
*
* @return query builder
**/
protected abstract function createQueryBuilder();
$manager = $this->managerRegistry->getManagerForClass($this->objectClass);
$identifierFieldNames = $manager
->getClassMetadata($this->objectClass)
->getIdentifierFieldNames();
return $this->sliceFetcher->fetch(
$queryBuilder,
$limit,
$offset,
$lastSlice,
$identifierFieldNames
);
}
}

212
Doctrine/Listener.php Normal file
View file

@ -0,0 +1,212 @@
<?php
namespace FOS\ElasticaBundle\Doctrine;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use FOS\ElasticaBundle\Persister\ObjectPersister;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use FOS\ElasticaBundle\Provider\IndexableInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* Automatically update ElasticSearch based on changes to the Doctrine source
* data. One listener is generated for each Doctrine entity / ElasticSearch type.
*/
class Listener
{
/**
* Object persister.
*
* @var ObjectPersisterInterface
*/
protected $objectPersister;
/**
* Configuration for the listener.
*
* @var array
*/
private $config;
/**
* Objects scheduled for insertion.
*
* @var array
*/
public $scheduledForInsertion = array();
/**
* Objects scheduled to be updated or removed.
*
* @var array
*/
public $scheduledForUpdate = array();
/**
* IDs of objects scheduled for removal.
*
* @var array
*/
public $scheduledForDeletion = array();
/**
* PropertyAccessor instance.
*
* @var PropertyAccessorInterface
*/
protected $propertyAccessor;
/**
* @var IndexableInterface
*/
private $indexable;
/**
* Constructor.
*
* @param ObjectPersisterInterface $objectPersister
* @param IndexableInterface $indexable
* @param array $config
* @param LoggerInterface $logger
*/
public function __construct(
ObjectPersisterInterface $objectPersister,
IndexableInterface $indexable,
array $config = array(),
LoggerInterface $logger = null
) {
$this->config = array_merge(array(
'identifier' => 'id',
), $config);
$this->indexable = $indexable;
$this->objectPersister = $objectPersister;
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
if ($logger && $this->objectPersister instanceof ObjectPersister) {
$this->objectPersister->setLogger($logger);
}
}
/**
* Looks for new objects that should be indexed.
*
* @param LifecycleEventArgs $eventArgs
*/
public function postPersist(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getObject();
if ($this->objectPersister->handlesObject($entity) && $this->isObjectIndexable($entity)) {
$this->scheduledForInsertion[] = $entity;
}
}
/**
* Looks for objects being updated that should be indexed or removed from the index.
*
* @param LifecycleEventArgs $eventArgs
*/
public function postUpdate(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getObject();
if ($this->objectPersister->handlesObject($entity)) {
if ($this->isObjectIndexable($entity)) {
$this->scheduledForUpdate[] = $entity;
} else {
// Delete if no longer indexable
$this->scheduleForDeletion($entity);
}
}
}
/**
* Delete objects preRemove instead of postRemove so that we have access to the id. Because this is called
* preRemove, first check that the entity is managed by Doctrine.
*
* @param LifecycleEventArgs $eventArgs
*/
public function preRemove(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getObject();
if ($this->objectPersister->handlesObject($entity)) {
$this->scheduleForDeletion($entity);
}
}
/**
* Persist scheduled objects to ElasticSearch
* After persisting, clear the scheduled queue to prevent multiple data updates when using multiple flush calls.
*/
private function persistScheduled()
{
if (count($this->scheduledForInsertion)) {
$this->objectPersister->insertMany($this->scheduledForInsertion);
$this->scheduledForInsertion = array();
}
if (count($this->scheduledForUpdate)) {
$this->objectPersister->replaceMany($this->scheduledForUpdate);
$this->scheduledForUpdate = array();
}
if (count($this->scheduledForDeletion)) {
$this->objectPersister->deleteManyByIdentifiers($this->scheduledForDeletion);
$this->scheduledForDeletion = array();
}
}
/**
* Iterate through scheduled actions before flushing to emulate 2.x behavior.
* Note that the ElasticSearch index will fall out of sync with the source
* data in the event of a crash during flush.
*
* This method is only called in legacy configurations of the listener.
*
* @deprecated This method should only be called in applications that depend
* on the behaviour that entities are indexed regardless of if a
* flush is successful.
*/
public function preFlush()
{
$this->persistScheduled();
}
/**
* Iterating through scheduled actions *after* flushing ensures that the
* ElasticSearch index will be affected only if the query is successful.
*/
public function postFlush()
{
$this->persistScheduled();
}
/**
* Record the specified identifier to delete. Do not need to entire object.
*
* @param object $object
*/
private function scheduleForDeletion($object)
{
if ($identifierValue = $this->propertyAccessor->getValue($object, $this->config['identifier'])) {
$this->scheduledForDeletion[] = $identifierValue;
}
}
/**
* Checks if the object is indexable or not.
*
* @param object $object
*
* @return bool
*/
private function isObjectIndexable($object)
{
return $this->indexable->isObjectIndexable(
$this->config['indexName'],
$this->config['typeName'],
$object
);
}
}

View file

@ -3,28 +3,28 @@
namespace FOS\ElasticaBundle\Doctrine\MongoDB;
use FOS\ElasticaBundle\Doctrine\AbstractElasticaToModelTransformer;
use Elastica_Document;
/**
* Maps Elastica documents with Doctrine objects
* This mapper assumes an exact match between
* elastica documents ids and doctrine object ids
* elastica documents ids and doctrine object ids.
*/
class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
{
/**
* Fetch objects for theses identifier values
* Fetch objects for theses identifier values.
*
* @param array $identifierValues ids values
* @param Boolean $hydrate whether or not to hydrate the objects, false returns arrays
*
* @param string $class the model class
* @param string $identifierField like 'id'
* @param array $identifierValues ids values
* @param Boolean $hydrate whether or not to hydrate the objects, false returns arrays
* @return array of objects or arrays
*/
protected function findByIdentifiers(array $identifierValues, $hydrate)
{
return $this->objectManager
->createQueryBuilder($this->objectClass)
return $this->registry
->getManagerForClass($this->objectClass)
->getRepository($this->objectClass)
->{$this->options['query_builder_method']}($this->objectClass)
->field($this->options['identifier'])->in($identifierValues)
->hydrate($hydrate)
->getQuery()

View file

@ -1,46 +0,0 @@
<?php
namespace FOS\ElasticaBundle\Doctrine\MongoDB;
use FOS\ElasticaBundle\Doctrine\AbstractListener;
use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
use Doctrine\Common\EventSubscriber;
class Listener extends AbstractListener implements EventSubscriber
{
public function postPersist(LifecycleEventArgs $eventArgs)
{
$document = $eventArgs->getDocument();
if ($document instanceof $this->objectClass) {
$this->objectPersister->insertOne($document);
}
}
public function postUpdate(LifecycleEventArgs $eventArgs)
{
$document = $eventArgs->getDocument();
if ($document instanceof $this->objectClass) {
$this->objectPersister->replaceOne($document);
}
}
public function preRemove(LifecycleEventArgs $eventArgs)
{
$document = $eventArgs->getDocument();
if ($document instanceof $this->objectClass) {
$this->scheduleForRemoval($document, $eventArgs->getDocumentManager());
}
}
public function postRemove(LifecycleEventArgs $eventArgs)
{
$document = $eventArgs->getDocument();
if ($document instanceof $this->objectClass) {
$this->removeIfScheduled($document);
}
}
}

View file

@ -2,41 +2,86 @@
namespace FOS\ElasticaBundle\Doctrine\MongoDB;
use Doctrine\ODM\MongoDB\Query\Builder;
use FOS\ElasticaBundle\Doctrine\AbstractProvider;
use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
class Provider extends AbstractProvider
{
/**
* Counts the objects of a query builder
* Disables logging and returns the logger that was previously set.
*
* @param queryBuilder
* @return int
**/
* @return mixed
*/
protected function disableLogging()
{
$configuration = $this->managerRegistry
->getManagerForClass($this->objectClass)
->getConnection()
->getConfiguration();
$logger = $configuration->getLoggerCallable();
$configuration->setLoggerCallable(null);
return $logger;
}
/**
* Reenables the logger with the previously returned logger from disableLogging();.
*
* @param mixed $logger
*
* @return mixed
*/
protected function enableLogging($logger)
{
$configuration = $this->managerRegistry
->getManagerForClass($this->objectClass)
->getConnection()
->getConfiguration();
$configuration->setLoggerCallable($logger);
}
/**
* {@inheritDoc}
*/
protected function countObjects($queryBuilder)
{
return $queryBuilder->getQuery()->count();
if (!$queryBuilder instanceof Builder) {
throw new InvalidArgumentTypeException($queryBuilder, 'Doctrine\ODM\MongoDB\Query\Builder');
}
return $queryBuilder
->getQuery()
->count();
}
/**
* Fetches a slice of objects
*
* @param queryBuilder
* @param int limit
* @param int offset
* @return array of objects
**/
* {@inheritDoc}
*/
protected function fetchSlice($queryBuilder, $limit, $offset)
{
return $queryBuilder->limit($limit)->skip($offset)->getQuery()->execute()->toArray();
if (!$queryBuilder instanceof Builder) {
throw new InvalidArgumentTypeException($queryBuilder, 'Doctrine\ODM\MongoDB\Query\Builder');
}
return $queryBuilder
->skip($offset)
->limit($limit)
->getQuery()
->execute()
->toArray();
}
/**
* Creates the query builder used to fetch the documents to index
*
* @return query builder
**/
protected function createQueryBuilder()
* {@inheritDoc}
*/
protected function createQueryBuilder($method)
{
return $this->objectManager->getRepository($this->objectClass)->{$this->options['query_builder_method']}();
return $this->managerRegistry
->getManagerForClass($this->objectClass)
->getRepository($this->objectClass)
->{$method}();
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace FOS\ElasticaBundle\Doctrine\MongoDB;
use Doctrine\ODM\MongoDB\Query\Builder;
use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
use FOS\ElasticaBundle\Doctrine\SliceFetcherInterface;
/**
* Fetches a slice of objects.
*
* @author Thomas Prelot <tprelot@gmail.com>
*/
class SliceFetcher implements SliceFetcherInterface
{
/**
* {@inheritdoc}
*/
public function fetch($queryBuilder, $limit, $offset, array $previousSlice, array $identifierFieldNames)
{
if (!$queryBuilder instanceof Builder) {
throw new InvalidArgumentTypeException($queryBuilder, 'Doctrine\ODM\MongoDB\Query\Builder');
}
$lastObject = array_pop($previousSlice);
if ($lastObject) {
$queryBuilder
->field('_id')->gt($lastObject->getId())
->skip(0)
;
} else {
$queryBuilder->skip($offset);
}
return $queryBuilder
->limit($limit)
->sort(array('_id' => 'asc'))
->getQuery()
->execute()
->toArray()
;
}
}

View file

@ -3,23 +3,23 @@
namespace FOS\ElasticaBundle\Doctrine\ORM;
use FOS\ElasticaBundle\Doctrine\AbstractElasticaToModelTransformer;
use Elastica_Document;
use Doctrine\ORM\Query;
/**
* Maps Elastica documents with Doctrine objects
* This mapper assumes an exact match between
* elastica documents ids and doctrine object ids
* elastica documents ids and doctrine object ids.
*/
class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
{
const ENTITY_ALIAS = 'o';
/**
* Fetch objects for theses identifier values
* Fetch objects for theses identifier values.
*
* @param array $identifierValues ids values
* @param Boolean $hydrate whether or not to hydrate the objects, false returns arrays
*
* @param string $class the model class
* @param string $identifierField like 'id'
* @param array $identifierValues ids values
* @param Boolean $hydrate whether or not to hydrate the objects, false returns arrays
* @return array of objects or arrays
*/
protected function findByIdentifiers(array $identifierValues, $hydrate)
@ -28,13 +28,25 @@ class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
return array();
}
$hydrationMode = $hydrate ? Query::HYDRATE_OBJECT : Query::HYDRATE_ARRAY;
$qb = $this->objectManager
->getRepository($this->objectClass)
->createQueryBuilder('o');
/* @var $qb \Doctrine\ORM\QueryBuilder */
$qb->where($qb->expr()->in('o.'.$this->options['identifier'], ':values'))
$qb = $this->getEntityQueryBuilder();
$qb->andWhere($qb->expr()->in(static::ENTITY_ALIAS.'.'.$this->options['identifier'], ':values'))
->setParameter('values', $identifierValues);
return $qb->getQuery()->setHydrationMode($hydrationMode)->execute();
}
/**
* Retrieves a query builder to be used for querying by identifiers.
*
* @return \Doctrine\ORM\QueryBuilder
*/
protected function getEntityQueryBuilder()
{
$repository = $this->registry
->getManagerForClass($this->objectClass)
->getRepository($this->objectClass);
return $repository->{$this->options['query_builder_method']}(static::ENTITY_ALIAS);
}
}

View file

@ -1,46 +0,0 @@
<?php
namespace FOS\ElasticaBundle\Doctrine\ORM;
use FOS\ElasticaBundle\Doctrine\AbstractListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\Common\EventSubscriber;
class Listener extends AbstractListener implements EventSubscriber
{
public function postPersist(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
$this->objectPersister->insertOne($entity);
}
}
public function postUpdate(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
$this->objectPersister->replaceOne($entity);
}
}
public function preRemove(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
$this->scheduleForRemoval($entity, $eventArgs->getEntityManager());
}
}
public function postRemove(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof $this->objectClass) {
$this->removeIfScheduled($entity);
}
}
}

View file

@ -2,48 +2,117 @@
namespace FOS\ElasticaBundle\Doctrine\ORM;
use Doctrine\ORM\QueryBuilder;
use FOS\ElasticaBundle\Doctrine\AbstractProvider;
use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
class Provider extends AbstractProvider
{
const ENTITY_ALIAS = 'a';
/**
* Counts the objects of a query builder
* Disables logging and returns the logger that was previously set.
*
* @param queryBuilder
* @return int
**/
* @return mixed
*/
protected function disableLogging()
{
$configuration = $this->managerRegistry
->getManagerForClass($this->objectClass)
->getConnection()
->getConfiguration();
$logger = $configuration->getSQLLogger();
$configuration->setSQLLogger(null);
return $logger;
}
/**
* Reenables the logger with the previously returned logger from disableLogging();.
*
* @param mixed $logger
*
* @return mixed
*/
protected function enableLogging($logger)
{
$configuration = $this->managerRegistry
->getManagerForClass($this->objectClass)
->getConnection()
->getConfiguration();
$configuration->setSQLLogger($logger);
}
/**
* {@inheritDoc}
*/
protected function countObjects($queryBuilder)
{
$qb = clone $queryBuilder;
$qb->select($qb->expr()->count($queryBuilder->getRootAlias()))
->resetDQLPart('orderBy'); // no need to order the query. It does not change the count and make the query less efficient.
if (!$queryBuilder instanceof QueryBuilder) {
throw new InvalidArgumentTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
}
return $qb->getQuery()->getSingleScalarResult();
/* Clone the query builder before altering its field selection and DQL,
* lest we leave the query builder in a bad state for fetchSlice().
*/
$qb = clone $queryBuilder;
$rootAliases = $queryBuilder->getRootAliases();
return $qb
->select($qb->expr()->count($rootAliases[0]))
// Remove ordering for efficiency; it doesn't affect the count
->resetDQLPart('orderBy')
->getQuery()
->getSingleScalarResult();
}
/**
* Fetches a slice of objects
* This method should remain in sync with SliceFetcher::fetch until it is deprecated and removed.
*
* @param queryBuilder
* @param int limit
* @param int offset
* @return array of objects
**/
* {@inheritDoc}
*/
protected function fetchSlice($queryBuilder, $limit, $offset)
{
$queryBuilder->setFirstResult($offset);
$queryBuilder->setMaxResults($limit);
if (!$queryBuilder instanceof QueryBuilder) {
throw new InvalidArgumentTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
}
return $queryBuilder->getQuery()->getResult();
/*
* An orderBy DQL part is required to avoid fetching the same row twice.
* @see http://stackoverflow.com/questions/6314879/does-limit-offset-length-require-order-by-for-pagination
* @see http://www.postgresql.org/docs/current/static/queries-limit.html
* @see http://www.sqlite.org/lang_select.html#orderby
*/
$orderBy = $queryBuilder->getDQLPart('orderBy');
if (empty($orderBy)) {
$rootAliases = $queryBuilder->getRootAliases();
$identifierFieldNames = $this->managerRegistry
->getManagerForClass($this->objectClass)
->getClassMetadata($this->objectClass)
->getIdentifierFieldNames();
foreach ($identifierFieldNames as $fieldName) {
$queryBuilder->addOrderBy($rootAliases[0].'.'.$fieldName);
}
}
return $queryBuilder
->setFirstResult($offset)
->setMaxResults($limit)
->getQuery()
->getResult();
}
/**
* Creates the query builder used to fetch the documents to index
*
* @return query builder
**/
protected function createQueryBuilder()
* {@inheritDoc}
*/
protected function createQueryBuilder($method)
{
return $this->objectManager->getRepository($this->objectClass)->{$this->options['query_builder_method']}('a');
return $this->managerRegistry
->getManagerForClass($this->objectClass)
->getRepository($this->objectClass)
// ORM query builders require an alias argument
->{$method}(static::ENTITY_ALIAS);
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace FOS\ElasticaBundle\Doctrine\ORM;
use Doctrine\ORM\QueryBuilder;
use FOS\ElasticaBundle\Exception\InvalidArgumentTypeException;
use FOS\ElasticaBundle\Doctrine\SliceFetcherInterface;
/**
* Fetches a slice of objects.
*
* @author Thomas Prelot <tprelot@gmail.com>
*/
class SliceFetcher implements SliceFetcherInterface
{
/**
* This method should remain in sync with Provider::fetchSlice until that method is deprecated and
* removed.
*
* {@inheritdoc}
*/
public function fetch($queryBuilder, $limit, $offset, array $previousSlice, array $identifierFieldNames)
{
if (!$queryBuilder instanceof QueryBuilder) {
throw new InvalidArgumentTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
}
/*
* An orderBy DQL part is required to avoid feching the same row twice.
* @see http://stackoverflow.com/questions/6314879/does-limit-offset-length-require-order-by-for-pagination
* @see http://www.postgresql.org/docs/current/static/queries-limit.html
* @see http://www.sqlite.org/lang_select.html#orderby
*/
$orderBy = $queryBuilder->getDQLPart('orderBy');
if (empty($orderBy)) {
$rootAliases = $queryBuilder->getRootAliases();
foreach ($identifierFieldNames as $fieldName) {
$queryBuilder->addOrderBy($rootAliases[0].'.'.$fieldName);
}
}
return $queryBuilder
->setFirstResult($offset)
->setMaxResults($limit)
->getQuery()
->getResult()
;
}
}

View file

@ -0,0 +1,43 @@
<?php
namespace FOS\ElasticaBundle\Doctrine;
use Doctrine\Common\Annotations\Reader;
use Doctrine\Common\Persistence\ManagerRegistry;
use FOS\ElasticaBundle\Manager\RepositoryManager as BaseManager;
/**
* @author Richard Miller <info@limethinking.co.uk>
*
* Allows retrieval of basic or custom repository for mapped Doctrine
* entities/documents.
*/
class RepositoryManager extends BaseManager
{
protected $entities = array();
protected $repositories = array();
protected $managerRegistry;
public function __construct(ManagerRegistry $managerRegistry, Reader $reader)
{
$this->managerRegistry = $managerRegistry;
parent::__construct($reader);
}
/**
* Return repository for entity.
*
* Returns custom repository if one specified otherwise
* returns a basic repository.
*/
public function getRepository($entityName)
{
$realEntityName = $entityName;
if (strpos($entityName, ':') !== false) {
list($namespaceAlias, $simpleClassName) = explode(':', $entityName);
$realEntityName = $this->managerRegistry->getAliasNamespace($namespaceAlias).'\\'.$simpleClassName;
}
return parent::getRepository($realEntityName);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace FOS\ElasticaBundle\Doctrine;
/**
* Fetches a slice of objects.
*
* @author Thomas Prelot <tprelot@gmail.com>
*/
interface SliceFetcherInterface
{
/**
* Fetches a slice of objects using the query builder.
*
* @param object $queryBuilder
* @param integer $limit
* @param integer $offset
* @param array $previousSlice
* @param array $identifierFieldNames
*
* @return array
*/
public function fetch($queryBuilder, $limit, $offset, array $previousSlice, array $identifierFieldNames);
}

12
DynamicIndex.php Normal file
View file

@ -0,0 +1,12 @@
<?php
namespace FOS\ElasticaBundle;
use FOS\ElasticaBundle\Elastica\Index;
/**
* @deprecated Use \FOS\ElasticaBundle\Elastica\TransformingIndex
*/
class DynamicIndex extends Index
{
}

104
Elastica/Client.php Normal file
View file

@ -0,0 +1,104 @@
<?php
namespace FOS\ElasticaBundle\Elastica;
use Elastica\Client as BaseClient;
use Elastica\Request;
use FOS\ElasticaBundle\Logger\ElasticaLogger;
use Symfony\Component\Stopwatch\Stopwatch;
/**
* Extends the default Elastica client to provide logging for errors that occur
* during communication with ElasticSearch.
*
* @author Gordon Franke <info@nevalon.de>
*/
class Client extends BaseClient
{
/**
* Stores created indexes to avoid recreation.
*
* @var array
*/
private $indexCache = array();
/**
* Symfony's debugging Stopwatch.
*
* @var Stopwatch|null
*/
private $stopwatch;
/**
* @param string $path
* @param string $method
* @param array $data
* @param array $query
*
* @return \Elastica\Response
*/
public function request($path, $method = Request::GET, $data = array(), array $query = array())
{
if ($this->stopwatch) {
$this->stopwatch->start('es_request', 'fos_elastica');
}
$start = microtime(true);
$response = parent::request($path, $method, $data, $query);
$this->logQuery($path, $method, $data, $query, $start);
if ($this->stopwatch) {
$this->stopwatch->stop('es_request');
}
return $response;
}
public function getIndex($name)
{
if (isset($this->indexCache[$name])) {
return $this->indexCache[$name];
}
return $this->indexCache[$name] = new Index($this, $name);
}
/**
* Sets a stopwatch instance for debugging purposes.
*
* @param Stopwatch $stopwatch
*/
public function setStopwatch(Stopwatch $stopwatch = null)
{
$this->stopwatch = $stopwatch;
}
/**
* Log the query if we have an instance of ElasticaLogger.
*
* @param string $path
* @param string $method
* @param array $data
* @param array $query
* @param int $start
*/
private function logQuery($path, $method, $data, array $query, $start)
{
if (!$this->_logger or !$this->_logger instanceof ElasticaLogger) {
return;
}
$time = microtime(true) - $start;
$connection = $this->getLastRequest()->getConnection();
$connection_array = array(
'host' => $connection->getHost(),
'port' => $connection->getPort(),
'transport' => $connection->getTransport(),
'headers' => $connection->hasConfig('headers') ? $connection->getConfig('headers') : array(),
);
$this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query);
}
}

59
Elastica/Index.php Normal file
View file

@ -0,0 +1,59 @@
<?php
namespace FOS\ElasticaBundle\Elastica;
use Elastica\Index as BaseIndex;
/**
* Overridden Elastica Index class that provides dynamic index name changes.
*
* @author Konstantin Tjuterev <kostik.lv@gmail.com>
*/
class Index extends BaseIndex
{
private $originalName;
/**
* Stores created types to avoid recreation.
*
* @var array
*/
private $typeCache = array();
/**
* Returns the original name of the index if the index has been renamed for reindexing
* or realiasing purposes.
*
* @return string
*/
public function getOriginalName()
{
return $this->originalName ?: $this->_name;
}
/**
* @param string $type
*/
public function getType($type)
{
if (isset($this->typeCache[$type])) {
return $this->typeCache[$type];
}
return $this->typeCache[$type] = parent::getType($type);
}
/**
* Reassign index name.
*
* While it's technically a regular setter for name property, it's specifically named overrideName, but not setName
* since it's used for a very specific case and normally should not be used
*
* @param string $name Index name
*/
public function overrideName($name)
{
$this->originalName = $this->_name;
$this->_name = $name;
}
}

38
Event/IndexEvent.php Normal file
View file

@ -0,0 +1,38 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Tim Nagel <tim@nagel.com.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Event;
use Symfony\Component\EventDispatcher\Event;
class IndexEvent extends Event
{
/**
* @var string
*/
private $index;
/**
* @param string $index
*/
public function __construct($index)
{
$this->index = $index;
}
/**
* @return string
*/
public function getIndex()
{
return $this->index;
}
}

View file

@ -0,0 +1,70 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) FriendsOfSymfony <https://github.com/FriendsOfSymfony/FOSElasticaBundle/graphs/contributors>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Event;
/**
* Index Populate Event.
*
* @author Oleg Andreyev <oleg.andreyev@intexsys.lv>
*/
class IndexPopulateEvent extends IndexEvent
{
const PRE_INDEX_POPULATE = 'elastica.index.index_pre_populate';
const POST_INDEX_POPULATE = 'elastica.index.index_post_populate';
/**
* @var bool
*/
private $reset;
/**
* @var array
*/
private $options;
/**
* @param string $index
* @param boolean $reset
* @param array $options
*/
public function __construct($index, $reset, $options)
{
parent::__construct($index);
$this->reset = $reset;
$this->options = $options;
}
/**
* @return boolean
*/
public function isReset()
{
return $this->reset;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @param boolean $reset
*/
public function setReset($reset)
{
$this->reset = $reset;
}
}

70
Event/IndexResetEvent.php Normal file
View file

@ -0,0 +1,70 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Infinite Networks Pty Ltd <http://www.infinite.net.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Event;
/**
* Index ResetEvent.
*
* @author Oleg Andreyev <oleg.andreyev@intexsys.lv>
*/
class IndexResetEvent extends IndexEvent
{
const PRE_INDEX_RESET = 'elastica.index.pre_reset';
const POST_INDEX_RESET = 'elastica.index.post_reset';
/**
* @var bool
*/
private $force;
/**
* @var bool
*/
private $populating;
/**
* @param string $index
* @param bool $populating
* @param bool $force
*/
public function __construct($index, $populating, $force)
{
parent::__construct($index);
$this->force = $force;
$this->populating = $populating;
}
/**
* @return boolean
*/
public function isForce()
{
return $this->force;
}
/**
* @return boolean
*/
public function isPopulating()
{
return $this->populating;
}
/**
* @param boolean $force
*/
public function setForce($force)
{
$this->force = $force;
}
}

78
Event/TransformEvent.php Normal file
View file

@ -0,0 +1,78 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Infinite Networks Pty Ltd <http://www.infinite.net.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Event;
use Symfony\Component\EventDispatcher\Event;
class TransformEvent extends Event
{
const POST_TRANSFORM = 'fos_elastica.post_transform';
/**
* @var mixed
*/
private $document;
/**
* @var array
*/
private $fields;
/**
* @var mixed
*/
private $object;
/**
* @param mixed $document
* @param array $fields
* @param mixed $object
*/
public function __construct($document, array $fields, $object)
{
$this->document = $document;
$this->fields = $fields;
$this->object = $object;
}
/**
* @return mixed
*/
public function getDocument()
{
return $this->document;
}
/**
* @return array
*/
public function getFields()
{
return $this->fields;
}
/**
* @return mixed
*/
public function getObject()
{
return $this->object;
}
/**
* @param mixed $document
*/
public function setDocument($document)
{
$this->document = $document;
}
}

View file

@ -0,0 +1,51 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) FriendsOfSymfony <https://github.com/FriendsOfSymfony/FOSElasticaBundle/graphs/contributors>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Event;
use Symfony\Component\EventDispatcher\Event;
/**
* Type Populate Event.
*
* @author Oleg Andreyev <oleg.andreyev@intexsys.lv>
*/
class TypePopulateEvent extends IndexPopulateEvent
{
const PRE_TYPE_POPULATE = 'elastica.index.type_pre_populate';
const POST_TYPE_POPULATE = 'elastica.index.type_post_populate';
/**
* @var string
*/
private $type;
/**
* @param string $index
* @param string $type
* @param bool $reset
* @param array $options
*/
public function __construct($index, $type, $reset, $options)
{
parent::__construct($index, $reset, $options);
$this->type = $type;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
}

49
Event/TypeResetEvent.php Normal file
View file

@ -0,0 +1,49 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Infinite Networks Pty Ltd <http://www.infinite.net.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Event;
use Symfony\Component\EventDispatcher\Event;
/**
* Type ResetEvent.
*
* @author Oleg Andreyev <oleg.andreyev@intexsys.lv>
*/
class TypeResetEvent extends IndexEvent
{
const PRE_TYPE_RESET = 'elastica.index.type_pre_reset';
const POST_TYPE_RESET = 'elastica.index.type_post_reset';
/**
* @var string
*/
private $type;
/**
* @param string $index
* @param string $type
*/
public function __construct($index, $type)
{
parent::__construct($index);
$this->type = $type;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
}

View file

@ -0,0 +1,11 @@
<?php
namespace FOS\ElasticaBundle\Exception;
class AliasIsIndexException extends \Exception
{
public function __construct($indexName)
{
parent::__construct(sprintf('Expected %s to be an alias but it is an index.', $indexName));
}
}

View file

@ -0,0 +1,11 @@
<?php
namespace FOS\ElasticaBundle\Exception;
class InvalidArgumentTypeException extends \InvalidArgumentException
{
public function __construct($value, $expectedType)
{
parent::__construct(sprintf('Expected argument of type "%s", "%s" given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
}
}

View file

@ -2,18 +2,29 @@
namespace FOS\ElasticaBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use FOS\ElasticaBundle\DependencyInjection\Compiler\AddProviderPass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\ConfigSourcePass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\IndexPass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\RegisterProvidersPass;
use FOS\ElasticaBundle\DependencyInjection\Compiler\TransformerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* Bundle.
*/
class FOSElasticaBundle extends Bundle
{
/**
* {@inheritdoc}
*/
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new AddProviderPass());
$container->addCompilerPass(new ConfigSourcePass());
$container->addCompilerPass(new IndexPass());
$container->addCompilerPass(new RegisterProvidersPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new TransformerPass());
}
}

View file

@ -4,12 +4,14 @@ namespace FOS\ElasticaBundle\Finder;
interface FinderInterface
{
/**
* Searches for query results within a given limit
*
* @param mixed $query Can be a string, an array or an Elastica_Query object
* @param int $limit How many results to get
* @return array results
*/
function find($query, $limit = null);
/**
* Searches for query results within a given limit.
*
* @param mixed $query Can be a string, an array or an \Elastica\Query object
* @param int $limit How many results to get
* @param array $options
*
* @return array results
*/
public function find($query, $limit = null, $options = array());
}

View file

@ -2,15 +2,29 @@
namespace FOS\ElasticaBundle\Finder;
use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
use Pagerfanta\Pagerfanta;
use Elastica\Query;
interface PaginatedFinderInterface
interface PaginatedFinderInterface extends FinderInterface
{
/**
* Searches for query results and returns them wrapped in a paginator
*
* @param mixed $query Can be a string, an array or an Elastica_Query object
* @return Pagerfanta paginated results
*/
function findPaginated($query);
/**
* Searches for query results and returns them wrapped in a paginator.
*
* @param mixed $query Can be a string, an array or an \Elastica\Query object
* @param array $options
*
* @return Pagerfanta paginated results
*/
public function findPaginated($query, $options = array());
/**
* Creates a paginator adapter for this query.
*
* @param mixed $query
* @param array $options
*
* @return PaginatorAdapterInterface
*/
public function createPaginatorAdapter($query, $options = array());
}

View file

@ -2,82 +2,109 @@
namespace FOS\ElasticaBundle\Finder;
use FOS\ElasticaBundle\Finder\FinderInterface;
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
use Elastica\Document;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use FOS\ElasticaBundle\Paginator\TransformedPaginatorAdapter;
use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter;
use Pagerfanta\Pagerfanta;
use Elastica_Searchable;
use Elastica_Query;
use Elastica\SearchableInterface;
use Elastica\Query;
/**
* Finds elastica documents and map them to persisted objects
* Finds elastica documents and map them to persisted objects.
*/
class TransformedFinder implements FinderInterface, PaginatedFinderInterface
class TransformedFinder implements PaginatedFinderInterface
{
protected $searchable;
protected $transformer;
public function __construct(Elastica_Searchable $searchable, ElasticaToModelTransformerInterface $transformer)
public function __construct(SearchableInterface $searchable, ElasticaToModelTransformerInterface $transformer)
{
$this->searchable = $searchable;
$this->transformer = $transformer;
}
/**
* Search for a query string
* Search for a query string.
*
* @param string $query
* @param string $query
* @param integer $limit
* @param array $options
*
* @return array of model objects
**/
public function find($query, $limit = null)
public function find($query, $limit = null, $options = array())
{
$results = $this->search($query, $limit);
$results = $this->search($query, $limit, $options);
return $this->transformer->transform($results);
}
public function findHybrid($query, $limit = null)
public function findHybrid($query, $limit = null, $options = array())
{
$results = $this->search($query, $limit);
$results = $this->search($query, $limit, $options);
return $this->transformer->hybridTransform($results);
}
protected function search($query, $limit = null)
/**
* Find documents similar to one with passed id.
*
* @param integer $id
* @param array $params
* @param array $query
*
* @return array of model objects
**/
public function moreLikeThis($id, $params = array(), $query = array())
{
$queryObject = Elastica_Query::create($query);
$doc = new Document($id);
$results = $this->searchable->moreLikeThis($doc, $params, $query)->getResults();
return $this->transformer->transform($results);
}
/**
* @param $query
* @param null|int $limit
* @param array $options
*
* @return array
*/
protected function search($query, $limit = null, $options = array())
{
$queryObject = Query::create($query);
if (null !== $limit) {
$queryObject->setLimit($limit);
$queryObject->setSize($limit);
}
$results = $this->searchable->search($queryObject)->getResults();
$results = $this->searchable->search($queryObject, $options)->getResults();
return $results;
}
/**
* Gets a paginator wrapping the result of a search
* Gets a paginator wrapping the result of a search.
*
* @param string $query
* @param array $options
*
* @return Pagerfanta
**/
public function findPaginated($query)
*/
public function findPaginated($query, $options = array())
{
$queryObject = Elastica_Query::create($query);
$paginatorAdapter = $this->createPaginatorAdapter($queryObject);
$queryObject = Query::create($query);
$paginatorAdapter = $this->createPaginatorAdapter($queryObject, $options);
return new Pagerfanta($paginatorAdapter);
return new Pagerfanta(new FantaPaginatorAdapter($paginatorAdapter));
}
/**
* Creates a paginator adapter for this query
*
* @param Elastica_Query $query
* @return TransformedPaginatorAdapter
* {@inheritdoc}
*/
protected function createPaginatorAdapter(Elastica_Query $query)
public function createPaginatorAdapter($query, $options = array())
{
return new TransformedPaginatorAdapter($this->searchable, $query, $this->transformer);
$query = Query::create($query);
return new TransformedPaginatorAdapter($this->searchable, $query, $options, $this->transformer);
}
}

View file

@ -2,14 +2,14 @@
namespace FOS\ElasticaBundle;
use Elastica_Result;
use Elastica\Result;
class HybridResult
{
protected $result;
protected $transformed;
public function __construct(Elastica_Result $result, $transformed = null)
public function __construct(Result $result, $transformed = null)
{
$this->result = $result;
$this->transformed = $transformed;
@ -24,4 +24,4 @@ class HybridResult
{
return $this->result;
}
}
}

197
Index/AliasProcessor.php Normal file
View file

@ -0,0 +1,197 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Infinite Networks Pty Ltd <http://www.infinite.net.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Index;
use Elastica\Client;
use Elastica\Exception\ExceptionInterface;
use Elastica\Request;
use FOS\ElasticaBundle\Configuration\IndexConfig;
use FOS\ElasticaBundle\Elastica\Index;
use FOS\ElasticaBundle\Exception\AliasIsIndexException;
class AliasProcessor
{
/**
* Sets the randomised root name for an index.
*
* @param IndexConfig $indexConfig
* @param Index $index
*/
public function setRootName(IndexConfig $indexConfig, Index $index)
{
$index->overrideName(
sprintf('%s_%s',
$indexConfig->getElasticSearchName(),
date('Y-m-d-His')
)
);
}
/**
* Switches an index to become the new target for an alias. Only applies for
* indexes that are set to use aliases.
*
* $force will delete an index encountered where an alias is expected.
*
* @param IndexConfig $indexConfig
* @param Index $index
* @param bool $force
*
* @throws AliasIsIndexException
* @throws \RuntimeException
*/
public function switchIndexAlias(IndexConfig $indexConfig, Index $index, $force = false)
{
$client = $index->getClient();
$aliasName = $indexConfig->getElasticSearchName();
$oldIndexName = null;
$newIndexName = $index->getName();
try {
$oldIndexName = $this->getAliasedIndex($client, $aliasName);
} catch (AliasIsIndexException $e) {
if (!$force) {
throw $e;
}
$this->deleteIndex($client, $aliasName);
}
try {
$aliasUpdateRequest = $this->buildAliasUpdateRequest($oldIndexName, $aliasName, $newIndexName);
$client->request('_aliases', 'POST', $aliasUpdateRequest);
} catch (ExceptionInterface $e) {
$this->cleanupRenameFailure($client, $newIndexName, $e);
}
// Delete the old index after the alias has been switched
if (null !== $oldIndexName) {
$this->deleteIndex($client, $oldIndexName);
}
}
/**
* Builds an ElasticSearch request to rename or create an alias.
*
* @param string|null $aliasedIndex
* @param string $aliasName
* @param string $newIndexName
* @return array
*/
private function buildAliasUpdateRequest($aliasedIndex, $aliasName, $newIndexName)
{
$aliasUpdateRequest = array('actions' => array());
if (null !== $aliasedIndex) {
// if the alias is set - add an action to remove it
$aliasUpdateRequest['actions'][] = array(
'remove' => array('index' => $aliasedIndex, 'alias' => $aliasName),
);
}
// add an action to point the alias to the new index
$aliasUpdateRequest['actions'][] = array(
'add' => array('index' => $newIndexName, 'alias' => $aliasName),
);
return $aliasUpdateRequest;
}
/**
* Cleans up an index when we encounter a failure to rename the alias.
*
* @param Client $client
* @param string $indexName
* @param \Exception $renameAliasException
*/
private function cleanupRenameFailure(Client $client, $indexName, \Exception $renameAliasException)
{
$additionalError = '';
try {
$this->deleteIndex($client, $indexName);
} catch (ExceptionInterface $deleteNewIndexException) {
$additionalError = sprintf(
'Tried to delete newly built index %s, but also failed: %s',
$indexName,
$deleteNewIndexException->getMessage()
);
}
throw new \RuntimeException(sprintf(
'Failed to updated index alias: %s. %s',
$renameAliasException->getMessage(),
$additionalError ?: sprintf('Newly built index %s was deleted', $indexName)
), 0, $renameAliasException);
}
/**
* Delete an index.
*
* @param Client $client
* @param string $indexName Index name to delete
*/
private function deleteIndex(Client $client, $indexName)
{
try {
$path = sprintf("%s", $indexName);
$client->request($path, Request::DELETE);
} catch (ExceptionInterface $deleteOldIndexException) {
throw new \RuntimeException(sprintf(
'Failed to delete index %s with message: %s',
$indexName,
$deleteOldIndexException->getMessage()
), 0, $deleteOldIndexException);
}
}
/**
* Returns the name of a single index that an alias points to or throws
* an exception if there is more than one.
*
* @param Client $client
* @param string $aliasName Alias name
*
* @return string|null
*
* @throws AliasIsIndexException
*/
private function getAliasedIndex(Client $client, $aliasName)
{
$aliasesInfo = $client->request('_aliases', 'GET')->getData();
$aliasedIndexes = array();
foreach ($aliasesInfo as $indexName => $indexInfo) {
if ($indexName === $aliasName) {
throw new AliasIsIndexException($indexName);
}
if (!isset($indexInfo['aliases'])) {
continue;
}
$aliases = array_keys($indexInfo['aliases']);
if (in_array($aliasName, $aliases)) {
$aliasedIndexes[] = $indexName;
}
}
if (count($aliasedIndexes) > 1) {
throw new \RuntimeException(sprintf(
'Alias %s is used for multiple indexes: [%s]. Make sure it\'s'.
'either not used or is assigned to one index only',
$aliasName,
implode(', ', $aliasedIndexes)
));
}
return array_shift($aliasedIndexes);
}
}

70
Index/IndexManager.php Normal file
View file

@ -0,0 +1,70 @@
<?php
namespace FOS\ElasticaBundle\Index;
use FOS\ElasticaBundle\Elastica\Index;
class IndexManager
{
/**
* @var Index
*/
private $defaultIndex;
/**
* @var array
*/
private $indexes;
/**
* @param array $indexes
* @param Index $defaultIndex
*/
public function __construct(array $indexes, Index $defaultIndex)
{
$this->defaultIndex = $defaultIndex;
$this->indexes = $indexes;
}
/**
* Gets all registered indexes.
*
* @return array
*/
public function getAllIndexes()
{
return $this->indexes;
}
/**
* Gets an index by its name.
*
* @param string $name Index to return, or the default index if null
*
* @return Index
*
* @throws \InvalidArgumentException if no index exists for the given name
*/
public function getIndex($name = null)
{
if (null === $name) {
return $this->defaultIndex;
}
if (!isset($this->indexes[$name])) {
throw new \InvalidArgumentException(sprintf('The index "%s" does not exist', $name));
}
return $this->indexes[$name];
}
/**
* Gets the default index.
*
* @return Index
*/
public function getDefaultIndex()
{
return $this->defaultIndex;
}
}

134
Index/MappingBuilder.php Normal file
View file

@ -0,0 +1,134 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Infinite Networks Pty Ltd <http://www.infinite.net.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Index;
use FOS\ElasticaBundle\Configuration\IndexConfig;
use FOS\ElasticaBundle\Configuration\TypeConfig;
class MappingBuilder
{
/**
* Skip adding default information to certain fields.
*
* @var array
*/
private $skipTypes = array('completion');
/**
* Builds mappings for an entire index.
*
* @param IndexConfig $indexConfig
*
* @return array
*/
public function buildIndexMapping(IndexConfig $indexConfig)
{
$typeMappings = array();
foreach ($indexConfig->getTypes() as $typeConfig) {
$typeMappings[$typeConfig->getName()] = $this->buildTypeMapping($typeConfig);
}
$mapping = array();
if (!empty($typeMappings)) {
$mapping['mappings'] = $typeMappings;
}
// 'warmers' => $indexConfig->getWarmers(),
$settings = $indexConfig->getSettings();
if (!empty($settings)) {
$mapping['settings'] = $settings;
}
return $mapping;
}
/**
* Builds mappings for a single type.
*
* @param TypeConfig $typeConfig
*
* @return array
*/
public function buildTypeMapping(TypeConfig $typeConfig)
{
$mapping = $typeConfig->getMapping();
if (null !== $typeConfig->getDynamicDateFormats()) {
$mapping['dynamic_date_formats'] = $typeConfig->getDynamicDateFormats();
}
if (null !== $typeConfig->getDateDetection()) {
$mapping['date_detection'] = $typeConfig->getDateDetection();
}
if (null !== $typeConfig->getNumericDetection()) {
$mapping['numeric_detection'] = $typeConfig->getNumericDetection();
}
if ($typeConfig->getIndexAnalyzer()) {
$mapping['index_analyzer'] = $typeConfig->getIndexAnalyzer();
}
if ($typeConfig->getSearchAnalyzer()) {
$mapping['search_analyzer'] = $typeConfig->getSearchAnalyzer();
}
if (isset($mapping['dynamic_templates']) and empty($mapping['dynamic_templates'])) {
unset($mapping['dynamic_templates']);
}
$this->fixProperties($mapping['properties']);
if (!$mapping['properties']) {
unset($mapping['properties']);
}
if ($typeConfig->getModel()) {
$mapping['_meta']['model'] = $typeConfig->getModel();
}
if (empty($mapping)) {
// Empty mapping, we want it encoded as a {} instead of a []
$mapping = new \stdClass();
}
return $mapping;
}
/**
* Fixes any properties and applies basic defaults for any field that does not have
* required options.
*
* @param $properties
*/
private function fixProperties(&$properties)
{
foreach ($properties as $name => &$property) {
unset($property['property_path']);
if (!isset($property['type'])) {
$property['type'] = 'string';
}
if ($property['type'] == 'multi_field' && isset($property['fields'])) {
$this->fixProperties($property['fields']);
}
if (isset($property['properties'])) {
$this->fixProperties($property['properties']);
}
if (in_array($property['type'], $this->skipTypes)) {
continue;
}
if (!isset($property['store'])) {
$property['store'] = true;
}
}
}
}

158
Index/Resetter.php Normal file
View file

@ -0,0 +1,158 @@
<?php
namespace FOS\ElasticaBundle\Index;
use Elastica\Index;
use Elastica\Exception\ResponseException;
use Elastica\Type\Mapping;
use FOS\ElasticaBundle\Configuration\ConfigManager;
use FOS\ElasticaBundle\Event\IndexResetEvent;
use FOS\ElasticaBundle\Event\TypeResetEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Deletes and recreates indexes.
*/
class Resetter
{
/**
* @var AliasProcessor
*/
private $aliasProcessor;
/***
* @var ConfigManager
*/
private $configManager;
/**
* @var EventDispatcherInterface
*/
private $dispatcher;
/**
* @var IndexManager
*/
private $indexManager;
/**
* @var MappingBuilder
*/
private $mappingBuilder;
/**
* @param ConfigManager $configManager
* @param IndexManager $indexManager
* @param AliasProcessor $aliasProcessor
* @param MappingBuilder $mappingBuilder
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(
ConfigManager $configManager,
IndexManager $indexManager,
AliasProcessor $aliasProcessor,
MappingBuilder $mappingBuilder,
EventDispatcherInterface $eventDispatcher
) {
$this->aliasProcessor = $aliasProcessor;
$this->configManager = $configManager;
$this->dispatcher = $eventDispatcher;
$this->indexManager = $indexManager;
$this->mappingBuilder = $mappingBuilder;
}
/**
* Deletes and recreates all indexes.
*
* @param bool $populating
* @param bool $force
*/
public function resetAllIndexes($populating = false, $force = false)
{
foreach ($this->configManager->getIndexNames() as $name) {
$this->resetIndex($name, $populating, $force);
}
}
/**
* Deletes and recreates the named index. If populating, creates a new index
* with a randomised name for an alias to be set after population.
*
* @param string $indexName
* @param bool $populating
* @param bool $force If index exists with same name as alias, remove it
*
* @throws \InvalidArgumentException if no index exists for the given name
*/
public function resetIndex($indexName, $populating = false, $force = false)
{
$indexConfig = $this->configManager->getIndexConfiguration($indexName);
$index = $this->indexManager->getIndex($indexName);
$event = new IndexResetEvent($indexName, $populating, $force);
$this->dispatcher->dispatch(IndexResetEvent::PRE_INDEX_RESET, $event);
if ($indexConfig->isUseAlias()) {
$this->aliasProcessor->setRootName($indexConfig, $index);
}
$mapping = $this->mappingBuilder->buildIndexMapping($indexConfig);
$index->create($mapping, true);
if (!$populating and $indexConfig->isUseAlias()) {
$this->aliasProcessor->switchIndexAlias($indexConfig, $index, $force);
}
$this->dispatcher->dispatch(IndexResetEvent::POST_INDEX_RESET, $event);
}
/**
* Deletes and recreates a mapping type for the named index.
*
* @param string $indexName
* @param string $typeName
*
* @throws \InvalidArgumentException if no index or type mapping exists for the given names
* @throws ResponseException
*/
public function resetIndexType($indexName, $typeName)
{
$typeConfig = $this->configManager->getTypeConfiguration($indexName, $typeName);
$type = $this->indexManager->getIndex($indexName)->getType($typeName);
$event = new TypeResetEvent($indexName, $typeName);
$this->dispatcher->dispatch(TypeResetEvent::PRE_TYPE_RESET, $event);
try {
$type->delete();
} catch (ResponseException $e) {
if (strpos($e->getMessage(), 'TypeMissingException') === false) {
throw $e;
}
}
$mapping = new Mapping();
foreach ($this->mappingBuilder->buildTypeMapping($typeConfig) as $name => $field) {
$mapping->setParam($name, $field);
}
$type->setMapping($mapping);
$this->dispatcher->dispatch(TypeResetEvent::POST_TYPE_RESET, $event);
}
/**
* A command run when a population has finished.
*
* @param string $indexName
*/
public function postPopulate($indexName)
{
$indexConfig = $this->configManager->getIndexConfiguration($indexName);
if ($indexConfig->isUseAlias()) {
$index = $this->indexManager->getIndex($indexName);
$this->aliasProcessor->switchIndexAlias($indexConfig, $index);
}
}
}

View file

@ -2,53 +2,11 @@
namespace FOS\ElasticaBundle;
use InvalidArgumentException;
use FOS\ElasticaBundle\Index\IndexManager as BaseIndexManager;
class IndexManager
/**
* @deprecated Use \FOS\ElasticaBundle\Index\IndexManager
*/
class IndexManager extends BaseIndexManager
{
protected $indexes;
protected $defaultIndex;
public function __construct(array $indexes, $defaultIndex)
{
$this->indexes = $indexes;
$this->defaultIndex = $defaultIndex;
}
/**
* Gets all registered indexes
*
* @return array
*/
public function getAllIndexes()
{
return $this->indexes;
}
/**
* Gets an index by its name
*
* @return Elastica_Index
**/
public function getIndex($name)
{
if (!$name) {
return $this->getDefaultIndex();
}
if (!isset($this->indexes[$name])) {
throw new InvalidArgumentException(sprintf('The index "%s" does not exist', $name));
}
return $this->indexes[$name];
}
/**
* Gets the default index
*
* @return Elastica_Index
**/
public function getDefaultIndex()
{
return $this->defaultIndex;
}
}

18
LICENSE
View file

@ -1,18 +0,0 @@
Copyright (c) 2012 Exercise.com
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.

View file

@ -2,7 +2,7 @@
namespace FOS\ElasticaBundle\Logger;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Psr\Log\LoggerInterface;
/**
* Logger for the Elastica.
@ -12,40 +12,55 @@ use Symfony\Component\HttpKernel\Log\LoggerInterface;
*
* @author Gordon Franke <info@nevalon.de>
*/
class ElasticaLogger
class ElasticaLogger implements LoggerInterface
{
/**
* @var LoggerInterface
*/
protected $logger;
protected $queries;
/**
* @var array
*/
protected $queries = array();
/**
* @var boolean
*/
protected $debug;
/**
* Constructor.
*
* @param LoggerInterface $logger The Symfony logger
* @param LoggerInterface|null $logger The Symfony logger
* @param boolean $debug
*/
public function __construct(LoggerInterface $logger = null, $debug = false)
{
$this->logger = $logger;
$this->queries = array();
$this->debug = $debug;
}
/**
* Logs a query.
*
* @param string $path Path to call
* @param string $method Rest method to use (GET, POST, DELETE, PUT)
* @param array $data arguments
* @param float $time execution time
* @param string $path Path to call
* @param string $method Rest method to use (GET, POST, DELETE, PUT)
* @param array $data Arguments
* @param float $time Execution time
* @param array $connection Host, port, transport, and headers of the query
* @param array $query Arguments
*/
public function logQuery($path, $method, $data, $time)
public function logQuery($path, $method, $data, $time, $connection = array(), $query = array())
{
if ($this->debug) {
$this->queries[] = array(
'path' => $path,
'method' => $method,
'data' => $data,
'executionMS' => $time
'executionMS' => $time,
'connection' => $connection,
'queryString' => $query,
);
}
@ -74,4 +89,76 @@ class ElasticaLogger
{
return $this->queries;
}
/**
* {@inheritdoc}
*/
public function emergency($message, array $context = array())
{
return $this->logger->emergency($message, $context);
}
/**
* {@inheritdoc}
*/
public function alert($message, array $context = array())
{
return $this->logger->alert($message, $context);
}
/**
* {@inheritdoc}
*/
public function critical($message, array $context = array())
{
return $this->logger->critical($message, $context);
}
/**
* {@inheritdoc}
*/
public function error($message, array $context = array())
{
return $this->logger->error($message, $context);
}
/**
* {@inheritdoc}
*/
public function warning($message, array $context = array())
{
return $this->logger->warning($message, $context);
}
/**
* {@inheritdoc}
*/
public function notice($message, array $context = array())
{
return $this->logger->notice($message, $context);
}
/**
* {@inheritdoc}
*/
public function info($message, array $context = array())
{
return $this->logger->info($message, $context);
}
/**
* {@inheritdoc}
*/
public function debug($message, array $context = array())
{
return $this->logger->debug($message, $context);
}
/**
* {@inheritdoc}
*/
public function log($level, $message, array $context = array())
{
return $this->logger->log($level, $message, $context);
}
}

View file

@ -5,6 +5,7 @@ namespace FOS\ElasticaBundle\Manager;
use Doctrine\Common\Annotations\Reader;
use FOS\ElasticaBundle\Finder\FinderInterface;
use RuntimeException;
/**
* @author Richard Miller <info@limethinking.co.uk>
*
@ -24,16 +25,16 @@ class RepositoryManager implements RepositoryManagerInterface
public function addEntity($entityName, FinderInterface $finder, $repositoryName = null)
{
$this->entities[$entityName]= array();
$this->entities[$entityName] = array();
$this->entities[$entityName]['finder'] = $finder;
$this->entities[$entityName]['repositoryName'] = $repositoryName;
}
/**
* Return repository for entity
* Return repository for entity.
*
* Returns custom repository if one specified otherwise
* returns a basic respository.
* returns a basic repository.
*/
public function getRepository($entityName)
{
@ -58,23 +59,26 @@ class RepositoryManager implements RepositoryManagerInterface
}
$refClass = new \ReflectionClass($entityName);
$annotation = $this->reader->getClassAnnotation($refClass, 'FOS\\ElasticaBundle\\Configuration\\Search');
$annotation = $this->reader->getClassAnnotation($refClass, 'FOS\\ElasticaBundle\\Annotation\\Search');
if ($annotation) {
$this->entities[$entityName]['repositoryName']
= $annotation->repositoryClass;
return $annotation->repositoryClass;
}
return 'FOS\ElasticaBundle\Repository';
}
/**
* @param string $entityName
*/
private function createRepository($entityName)
{
$repositoryName = $this->getRepositoryName($entityName);
if (!class_exists($repositoryName)) {
if (!class_exists($repositoryName = $this->getRepositoryName($entityName))) {
throw new RuntimeException(sprintf('%s repository for %s does not exist', $repositoryName, $entityName));
}
return new $repositoryName($this->entities[$entityName]['finder']);
}
}

View file

@ -12,7 +12,6 @@ use FOS\ElasticaBundle\Finder\FinderInterface;
*/
interface RepositoryManagerInterface
{
/**
* Adds entity name and its finder.
* Custom repository class name can also be added.
@ -24,7 +23,7 @@ interface RepositoryManagerInterface
public function addEntity($entityName, FinderInterface $finder, $repositoryName = null);
/**
* Return repository for entity
* Return repository for entity.
*
* Returns custom repository if one specified otherwise
* returns a basic repository.
@ -32,5 +31,4 @@ interface RepositoryManagerInterface
* @param string $entityName
*/
public function getRepository($entityName);
}

View file

@ -1,60 +0,0 @@
<?php
namespace FOS\ElasticaBundle;
use Elastica_Type;
use InvalidArgumentException;
/**
* Stores the configured mappings for all types
* Responsible for applying configured mappings to elastica types
*/
class MappingRegistry
{
/**
* Configured mappings. See http://www.elasticsearch.org/guide/reference/mapping/
* array(
* "index_name/type_name" => array(type_object, mapping_array)
* )
*
* @var array
*/
protected $mappings = null;
/**
* Instanciates a new MappingSetter
*
* @param array mappings
*/
public function __construct($mappings)
{
$this->mappings = $mappings;
}
/**
* Apply mappings to all elastica types
**/
public function applyMappings()
{
foreach ($this->mappings as $pair) {
list($type, $mappings) = $pair;
$type->setMapping($mappings);
}
}
/**
* Gets the type mapping field names
*
* @param Elastica_Type $type
* @return array list of fields names
*/
public function getTypeFieldNames(Elastica_Type $type)
{
$key = sprintf('%s/%s', $type->getIndex()->getName(), $type->getType());
if (!isset($this->mappings[$key])) {
throw new InvalidArgumentException(sprintf('This type is not registered: "%s".', $key));
}
return array_keys($this->mappings[$key][1]);
}
}

View file

@ -1,54 +0,0 @@
<?php
namespace FOS\ElasticaBundle\Paginator;
use Pagerfanta\Adapter\AdapterInterface;
use Elastica_Searchable;
use Elastica_Query;
/**
* Implements the Pagerfanta\Adapter\AdapterInterface for use with Pagerfanta\Pagerfanta
*
* Allows pagination of Elastica_Query. Does not map results
*/
abstract class AbstractPaginatorAdapter implements AdapterInterface
{
/**
* @var Elastica_SearchableInterface the object to search in
*/
protected $searchable = null;
/**
* @var Elastica_Query the query to search
*/
protected $query = null;
/**
* @see PaginatorAdapterInterface::__construct
*
* @param Elastica_SearchableInterface the object to search in
* @param Elastica_Query the query to search
*/
public function __construct(Elastica_Searchable $searchable, Elastica_Query $query)
{
$this->searchable = $searchable;
$this->query = $query;
}
protected function getElasticaResults($offset, $itemCountPerPage)
{
$query = clone $this->query;
$query->setFrom($offset);
$query->setLimit($itemCountPerPage);
return $this->searchable->search($query)->getResults();
}
/**
* @see Pagerfanta\Adapter\AdapterInterface::getNbResults
*/
public function getNbResults()
{
return $this->searchable->count($this->query);
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace FOS\ElasticaBundle\Paginator;
use Pagerfanta\Adapter\AdapterInterface;
class FantaPaginatorAdapter implements AdapterInterface
{
private $adapter;
/**
* @param \FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface $adapter
*/
public function __construct(PaginatorAdapterInterface $adapter)
{
$this->adapter = $adapter;
}
/**
* Returns the number of results.
*
* @return integer The number of results.
*/
public function getNbResults()
{
return $this->adapter->getTotalHits();
}
/**
* Returns Facets.
*
* @return mixed
*/
public function getFacets()
{
return $this->adapter->getFacets();
}
/**
* Returns Aggregations.
*
* @return mixed
*
* @api
*/
public function getAggregations()
{
return $this->adapter->getAggregations();
}
/**
* Returns a slice of the results.
*
* @param integer $offset The offset.
* @param integer $length The length.
*
* @return array|\Traversable The slice.
*/
public function getSlice($offset, $length)
{
return $this->adapter->getResults($offset, $length)->toArray();
}
}

View file

@ -0,0 +1,37 @@
<?php
namespace FOS\ElasticaBundle\Paginator;
interface PaginatorAdapterInterface
{
/**
* Returns the number of results.
*
* @return integer The number of results.
*/
public function getTotalHits();
/**
* Returns an slice of the results.
*
* @param integer $offset The offset.
* @param integer $length The length.
*
* @return PartialResultsInterface
*/
public function getResults($offset, $length);
/**
* Returns Facets.
*
* @return mixed
*/
public function getFacets();
/**
* Returns Aggregations.
*
* @return mixed
*/
public function getAggregations();
}

View file

@ -0,0 +1,34 @@
<?php
namespace FOS\ElasticaBundle\Paginator;
interface PartialResultsInterface
{
/**
* Returns the paginated results.
*
* @return array
*/
public function toArray();
/**
* Returns the number of results.
*
* @return integer The number of results.
*/
public function getTotalHits();
/**
* Returns the facets.
*
* @return array
*/
public function getFacets();
/**
* Returns the aggregations.
*
* @return array
*/
public function getAggregations();
}

View file

@ -2,20 +2,168 @@
namespace FOS\ElasticaBundle\Paginator;
use Elastica\SearchableInterface;
use Elastica\Query;
use Elastica\ResultSet;
use InvalidArgumentException;
/**
* Implements the Pagerfanta\Adapter\AdapterInterface for use with Zend\Paginator\Paginator
*
* Allows pagination of Elastica_Query. Does not map results
* Allows pagination of Elastica\Query. Does not map results.
*/
class RawPaginatorAdapter extends AbstractPaginatorAdapter
class RawPaginatorAdapter implements PaginatorAdapterInterface
{
/**
* @see Pagerfanta\Adapter\AdapterInterface::getSlice
* @var SearchableInterface the object to search in
*/
public function getSlice($offset, $length)
{
$results = $this->getElasticaResults($offset, $length);
private $searchable;
return array_map(function($result) { return $result->getSource(); }, $results);
/**
* @var Query the query to search
*/
private $query;
/**
* @var array search options
*/
private $options;
/**
* @var integer the number of hits
*/
private $totalHits;
/**
* @var array for the facets
*/
private $facets;
/**
* @var array for the aggregations
*/
private $aggregations;
/**
* @see PaginatorAdapterInterface::__construct
*
* @param SearchableInterface $searchable the object to search in
* @param Query $query the query to search
* @param array $options
*/
public function __construct(SearchableInterface $searchable, Query $query, array $options = array())
{
$this->searchable = $searchable;
$this->query = $query;
$this->options = $options;
}
/**
* Returns the paginated results.
*
* @param integer $offset
* @param integer $itemCountPerPage
*
* @throws \InvalidArgumentException
*
* @return ResultSet
*/
protected function getElasticaResults($offset, $itemCountPerPage)
{
$offset = (integer) $offset;
$itemCountPerPage = (integer) $itemCountPerPage;
$size = $this->query->hasParam('size')
? (integer) $this->query->getParam('size')
: null;
if (null !== $size && $size < $offset + $itemCountPerPage) {
$itemCountPerPage = $size - $offset;
}
if ($itemCountPerPage < 1) {
throw new InvalidArgumentException('$itemCountPerPage must be greater than zero');
}
$query = clone $this->query;
$query->setFrom($offset);
$query->setSize($itemCountPerPage);
$resultSet = $this->searchable->search($query, $this->options);
$this->totalHits = $resultSet->getTotalHits();
$this->facets = $resultSet->getFacets();
$this->aggregations = $resultSet->getAggregations();
return $resultSet;
}
/**
* Returns the paginated results.
*
* @param int $offset
* @param int $itemCountPerPage
*
* @return PartialResultsInterface
*/
public function getResults($offset, $itemCountPerPage)
{
return new RawPartialResults($this->getElasticaResults($offset, $itemCountPerPage));
}
/**
* Returns the number of results.
*
* If genuineTotal is provided as true, total hits is returned from the
* hits.total value from the search results instead of just returning
* the requested size.
*
* @param boolean $genuineTotal
*
* @return integer The number of results.
*/
public function getTotalHits($genuineTotal = false)
{
if (! isset($this->totalHits)) {
$this->totalHits = $this->searchable->count($this->query);
}
return $this->query->hasParam('size') && !$genuineTotal
? min($this->totalHits, (integer) $this->query->getParam('size'))
: $this->totalHits;
}
/**
* Returns Facets.
*
* @return mixed
*/
public function getFacets()
{
if (! isset($this->facets)) {
$this->facets = $this->searchable->search($this->query)->getFacets();
}
return $this->facets;
}
/**
* Returns Aggregations.
*
* @return mixed
*/
public function getAggregations()
{
if (!isset($this->aggregations)) {
$this->aggregations = $this->searchable->search($this->query)->getAggregations();
}
return $this->aggregations;
}
/**
* Returns the Query.
*
* @return Query the search query
*/
public function getQuery()
{
return $this->query;
}
}

View file

@ -0,0 +1,64 @@
<?php
namespace FOS\ElasticaBundle\Paginator;
use Elastica\ResultSet;
use Elastica\Result;
/**
* Raw partial results transforms to a simple array.
*/
class RawPartialResults implements PartialResultsInterface
{
protected $resultSet;
/**
* @param ResultSet $resultSet
*/
public function __construct(ResultSet $resultSet)
{
$this->resultSet = $resultSet;
}
/**
* {@inheritDoc}
*/
public function toArray()
{
return array_map(function (Result $result) {
return $result->getSource();
}, $this->resultSet->getResults());
}
/**
* {@inheritDoc}
*/
public function getTotalHits()
{
return $this->resultSet->getTotalHits();
}
/**
* {@inheritDoc}
*/
public function getFacets()
{
if ($this->resultSet->hasFacets()) {
return $this->resultSet->getFacets();
}
return;
}
/**
* {@inheritDoc}
*/
public function getAggregations()
{
if ($this->resultSet->hasAggregations()) {
return $this->resultSet->getAggregations();
}
return;
}
}

View file

@ -3,37 +3,34 @@
namespace FOS\ElasticaBundle\Paginator;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Elastica_Searchable;
use Elastica_Query;
use Elastica\SearchableInterface;
use Elastica\Query;
/**
* Implements the Pagerfanta\Adapter\AdapterInterface Interface for use with Zend\Paginator\Paginator
*
* Allows pagination of Elastica_Query
* Allows pagination of \Elastica\Query.
*/
class TransformedPaginatorAdapter extends AbstractPaginatorAdapter
class TransformedPaginatorAdapter extends RawPaginatorAdapter
{
protected $transformer;
private $transformer;
/**
* @param Elastica_SearchableInterface the object to search in
* @param Elastica_Query the query to search
* @param ElasticaToModelTransformerInterface the transformer for fetching the results
* @param SearchableInterface $searchable the object to search in
* @param Query $query the query to search
* @param array $options
* @param ElasticaToModelTransformerInterface $transformer the transformer for fetching the results
*/
public function __construct(Elastica_Searchable $searchable, Elastica_Query $query, ElasticaToModelTransformerInterface $transformer)
public function __construct(SearchableInterface $searchable, Query $query, array $options = array(), ElasticaToModelTransformerInterface $transformer)
{
parent::__construct($searchable, $query);
parent::__construct($searchable, $query, $options);
$this->transformer = $transformer;
}
/**
* @see Pagerfanta\Adapter\AdapterInterface::getSlice
* {@inheritDoc}
*/
public function getSlice($offset, $length)
public function getResults($offset, $length)
{
$results = $this->getElasticaResults($offset, $length);
return $this->transformer->transform($results);
return new TransformedPartialResults($this->getElasticaResults($offset, $length), $this->transformer);
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace FOS\ElasticaBundle\Paginator;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Elastica\ResultSet;
/**
* Partial transformed result set.
*/
class TransformedPartialResults extends RawPartialResults
{
protected $transformer;
/**
* @param ResultSet $resultSet
* @param \FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface $transformer
*/
public function __construct(ResultSet $resultSet, ElasticaToModelTransformerInterface $transformer)
{
parent::__construct($resultSet);
$this->transformer = $transformer;
}
/**
* {@inheritDoc}
*/
public function toArray()
{
return $this->transformer->transform($this->resultSet->getResults());
}
}

View file

@ -2,16 +2,15 @@
namespace FOS\ElasticaBundle\Persister;
use FOS\ElasticaBundle\Provider\ProviderInterface;
use Psr\Log\LoggerInterface;
use Elastica\Exception\BulkException;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Elastica_Type;
use Elastica_Document;
use Exception;
use Elastica\Type;
use Elastica\Document;
/**
* Inserts, replaces and deletes single documents in an elastica type
* Accepts domain model objects and converts them to elastica documents
* Accepts domain model objects and converts them to elastica documents.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
@ -21,8 +20,9 @@ class ObjectPersister implements ObjectPersisterInterface
protected $transformer;
protected $objectClass;
protected $fields;
protected $logger;
public function __construct(Elastica_Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, array $fields)
public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, array $fields)
{
$this->type = $type;
$this->transformer = $transformer;
@ -30,77 +30,163 @@ class ObjectPersister implements ObjectPersisterInterface
$this->fields = $fields;
}
/**
* If the ObjectPersister handles a given object.
*
* @param object $object
*
* @return bool
*/
public function handlesObject($object)
{
return $object instanceof $this->objectClass;
}
/**
* @param LoggerInterface $logger
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* Log exception if logger defined for persister belonging to the current listener, otherwise re-throw.
*
* @param BulkException $e
*
* @throws BulkException
*/
private function log(BulkException $e)
{
if (! $this->logger) {
throw $e;
}
$this->logger->error($e);
}
/**
* Insert one object into the type
* The object will be transformed to an elastica document
* The object will be transformed to an elastica document.
*
* @param object $object
*/
public function insertOne($object)
{
$document = $this->transformToElasticaDocument($object);
$this->type->addDocument($document);
$this->insertMany(array($object));
}
/**
* Replaces one object in the type
* Replaces one object in the type.
*
* @param object $object
* @return null
**/
public function replaceOne($object)
{
$document = $this->transformToElasticaDocument($object);
$this->type->deleteById($document->getId());
$this->type->addDocument($document);
$this->replaceMany(array($object));
}
/**
* Deletes one object in the type
* Deletes one object in the type.
*
* @param object $object
* @return null
**/
public function deleteOne($object)
{
$document = $this->transformToElasticaDocument($object);
$this->type->deleteById($document->getId());
$this->deleteMany(array($object));
}
/**
* Deletes one object in the type by id
* Deletes one object in the type by id.
*
* @param mixed $id
*
* @return null
**/
public function deleteById($id)
{
$this->type->deleteById($id);
$this->deleteManyByIdentifiers(array($id));
}
/**
* Inserts an array of objects in the type
* Bulk insert an array of objects in the type for the given method.
*
* @param array of domain model objects
**/
* @param array $objects array of domain model objects
* @param string Method to call
*/
public function insertMany(array $objects)
{
$documents = array();
foreach ($objects as $object) {
$documents[] = $this->transformToElasticaDocument($object);
}
$this->type->addDocuments($documents);
try {
$this->type->addDocuments($documents);
} catch (BulkException $e) {
$this->log($e);
}
}
/**
* Transforms an object to an elastica document
* Bulk update an array of objects in the type. Create document if it does not already exist.
*
* @param array $objects array of domain model objects
*/
public function replaceMany(array $objects)
{
$documents = array();
foreach ($objects as $object) {
$document = $this->transformToElasticaDocument($object);
$document->setDocAsUpsert(true);
$documents[] = $document;
}
try {
$this->type->updateDocuments($documents);
} catch (BulkException $e) {
$this->log($e);
}
}
/**
* Bulk deletes an array of objects in the type.
*
* @param array $objects array of domain model objects
*/
public function deleteMany(array $objects)
{
$documents = array();
foreach ($objects as $object) {
$documents[] = $this->transformToElasticaDocument($object);
}
try {
$this->type->deleteDocuments($documents);
} catch (BulkException $e) {
$this->log($e);
}
}
/**
* Bulk deletes records from an array of identifiers.
*
* @param array $identifiers array of domain model object identifiers
*/
public function deleteManyByIdentifiers(array $identifiers)
{
try {
$this->type->getIndex()->getClient()->deleteIds($identifiers, $this->type->getIndex(), $this->type);
} catch (BulkException $e) {
$this->log($e);
}
}
/**
* Transforms an object to an elastica document.
*
* @param object $object
* @return Elastica_Document the elastica document
*
* @return Document the elastica document
*/
protected function transformToElasticaDocument($object)
public function transformToElasticaDocument($object)
{
return $this->transformer->transform($object, $this->fields);
}

View file

@ -4,47 +4,75 @@ namespace FOS\ElasticaBundle\Persister;
/**
* Inserts, replaces and deletes single documents in an elastica type
* Accepts domain model objects and converts them to elastica documents
* Accepts domain model objects and converts them to elastica documents.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
interface ObjectPersisterInterface
{
/**
* Checks if this persister can handle the given object or not.
*
* @param mixed $object
*
* @return boolean
*/
public function handlesObject($object);
/**
* Insert one object into the type
* The object will be transformed to an elastica document
* The object will be transformed to an elastica document.
*
* @param object $object
*/
function insertOne($object);
public function insertOne($object);
/**
* Replaces one object in the type
* Replaces one object in the type.
*
* @param object $object
**/
function replaceOne($object);
public function replaceOne($object);
/**
* Deletes one object in the type
* Deletes one object in the type.
*
* @param object $object
**/
function deleteOne($object);
public function deleteOne($object);
/**
* Deletes one object in the type by id
* Deletes one object in the type by id.
*
* @param mixed $id
*
* @return null
**/
function deleteById($id);
*/
public function deleteById($id);
/**
* Inserts an array of objects in the type
* Bulk inserts an array of objects in the type.
*
* @param array of domain model objects
**/
function insertMany(array $objects);
* @param array $objects array of domain model objects
*/
public function insertMany(array $objects);
/**
* Bulk updates an array of objects in the type.
*
* @param array $objects array of domain model objects
*/
public function replaceMany(array $objects);
/**
* Bulk deletes an array of objects in the type.
*
* @param array $objects array of domain model objects
*/
public function deleteMany(array $objects);
/**
* Bulk deletes records from an array of identifiers.
*
* @param array $identifiers array of domain model object identifiers
*/
public function deleteManyByIdentifiers(array $identifiers);
}

View file

@ -0,0 +1,50 @@
<?php
namespace FOS\ElasticaBundle\Persister;
use Elastica\Document;
use Elastica\Type;
use FOS\ElasticaBundle\Transformer\ModelToElasticaTransformerInterface;
/**
* Inserts, replaces and deletes single objects in an elastica type, making use
* of elastica's serializer support to convert objects in to elastica documents.
* Accepts domain model objects and passes them directly to elastica.
*
* @author Lea Haensenberber <lea.haensenberger@gmail.com>
*/
class ObjectSerializerPersister extends ObjectPersister
{
protected $serializer;
/**
* @param Type $type
* @param ModelToElasticaTransformerInterface $transformer
* @param string $objectClass
* @param callable $serializer
*/
public function __construct(Type $type, ModelToElasticaTransformerInterface $transformer, $objectClass, $serializer)
{
parent::__construct($type, $transformer, $objectClass, array());
$this->serializer = $serializer;
}
/**
* Transforms an object to an elastica document
* with just the identifier set.
*
* @param object $object
*
* @return Document the elastica document
*/
public function transformToElasticaDocument($object)
{
$document = $this->transformer->transform($object, array());
$data = call_user_func($this->serializer, $object);
$document->setData($data);
return $document;
}
}

View file

@ -1,32 +0,0 @@
<?php
namespace FOS\ElasticaBundle;
use FOS\ElasticaBundle\Provider\ProviderInterface;
use Closure;
class Populator
{
protected $providers;
public function __construct(array $providers)
{
foreach ($providers as $name => $provider) {
$this->addProvider($name, $provider);
}
}
public function addProvider($name, ProviderInterface $provider)
{
$this->providers[$name] = $provider;
}
public function populate(Closure $loggerClosure)
{
foreach ($this->providers as $name => $provider) {
$provider->populate(function($text) use ($name, $loggerClosure) {
$loggerClosure(sprintf('Indexing %s, %s', $name, $text));
});
}
}
}

View file

@ -3,74 +3,75 @@
namespace FOS\ElasticaBundle\Propel;
use FOS\ElasticaBundle\HybridResult;
use FOS\ElasticaBundle\Transformer\AbstractElasticaToModelTransformer;
use FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerInterface;
use Elastica_Document;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* Maps Elastica documents with Propel objects
* This mapper assumes an exact match between
* elastica documents ids and propel object ids
* Maps Elastica documents with Propel objects.
*
* This mapper assumes an exact match between Elastica document IDs and Propel
* entity IDs.
*
* @author William Durand <william.durand1@gmail.com>
*/
class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
class ElasticaToModelTransformer extends AbstractElasticaToModelTransformer
{
/**
* Class of the model to map to the elastica documents
* Propel model class to map to Elastica documents.
*
* @var string
*/
protected $objectClass = null;
/**
* Optional parameters
* Transformer options.
*
* @var array
*/
protected $options = array(
'hydrate' => true,
'identifier' => 'id'
'identifier' => 'id',
);
/**
* Instantiates a new Mapper
* Constructor.
*
* @param string $objectClass
* @param array $options
* @param array $options
*/
public function __construct($objectClass, array $options = array())
{
$this->objectClass = $objectClass;
$this->options = array_merge($this->options, $options);
$this->options = array_merge($this->options, $options);
}
/**
* Transforms an array of elastica objects into an array of
* model objects fetched from the propel repository
* Transforms an array of Elastica document into an array of Propel entities
* fetched from the database.
*
* @param array of elastica objects
* @return array
* @param array $elasticaObjects
*
* @return array|\ArrayObject
*/
public function transform(array $elasticaObjects)
{
$ids = array_map(function($elasticaObject) {
return $elasticaObject->getId();
}, $elasticaObjects);
$ids = array();
foreach ($elasticaObjects as $elasticaObject) {
$ids[] = $elasticaObject->getId();
}
$objects = $this->findByIdentifiers($ids, $this->options['hydrate']);
$identifierGetter = 'get'.ucfirst($this->options['identifier']);
// sort objects in the order of ids
// Sort objects in the order of their IDs
$idPos = array_flip($ids);
$identifier = $this->options['identifier'];
$sortCallback = $this->getSortingClosure($idPos, $identifier);
if (is_object($objects)) {
$objects->uasort(function($a, $b) use ($idPos, $identifierGetter) {
return $idPos[$a->$identifierGetter()] > $idPos[$b->$identifierGetter()];
});
$objects->uasort($sortCallback);
} else {
usort($objects, function($a, $b) use ($idPos, $identifierGetter) {
return $idPos[$a->$identifierGetter()] > $idPos[$b->$identifierGetter()];
});
usort($objects, $sortCallback);
}
return $objects;
@ -84,7 +85,7 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$objects = $this->transform($elasticaObjects);
$result = array();
for ($i = 0; $i < count($elasticaObjects); $i++) {
for ($i = 0, $j = count($elasticaObjects); $i < $j; $i++) {
$result[] = new HybridResult($elasticaObjects[$i], $objects[$i]);
}
@ -108,13 +109,15 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
}
/**
* Fetch objects for theses identifier values
* Fetch Propel entities for the given identifier values.
*
* @param string $class the model class
* @param string $identifierField like 'id'
* @param array $identifierValues ids values
* @param Boolean $hydrate whether or not to hydrate the objects, false returns arrays
* @return array of objects or arrays
* If $hydrate is false, the returned array elements will be arrays.
* Otherwise, the results will be hydrated to instances of the model class.
*
* @param array $identifierValues Identifier values
* @param boolean $hydrate Whether or not to hydrate the results
*
* @return array
*/
protected function findByIdentifiers(array $identifierValues, $hydrate)
{
@ -124,7 +127,7 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$query = $this->createQuery($this->objectClass, $this->options['identifier'], $identifierValues);
if (!$hydrate) {
if (! $hydrate) {
return $query->toArray();
}
@ -134,9 +137,10 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
/**
* Create a query to use in the findByIdentifiers() method.
*
* @param string $class the model class
* @param string $identifierField like 'id'
* @param array $identifierValues ids values
* @param string $class Propel model class
* @param string $identifierField Identifier field name (e.g. "id")
* @param array $identifierValues Identifier values
*
* @return \ModelCriteria
*/
protected function createQuery($class, $identifierField, array $identifierValues)
@ -144,13 +148,13 @@ class ElasticaToModelTransformer implements ElasticaToModelTransformerInterface
$queryClass = $class.'Query';
$filterMethod = 'filterBy'.$this->camelize($identifierField);
return $queryClass::create()
->$filterMethod($identifierValues)
;
return $queryClass::create()->$filterMethod($identifierValues);
}
/**
* @see https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Util/Inflector.php
*
* @param string $str
*/
private function camelize($str)
{

View file

@ -2,75 +2,72 @@
namespace FOS\ElasticaBundle\Propel;
use FOS\ElasticaBundle\Provider\ProviderInterface;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use Elastica_Type;
use Elastica_Document;
use Closure;
use InvalidArgumentException;
use FOS\ElasticaBundle\Provider\AbstractProvider;
/**
* Propel provider
* Propel provider.
*
* @author William Durand <william.durand1@gmail.com>
*/
class Provider implements ProviderInterface
class Provider extends AbstractProvider
{
/**
* Elastica type
*
* @var Elastica_Type
* {@inheritDoc}
*/
protected $type;
/**
* Object persister
*
* @var ObjectPersisterInterface
*/
protected $objectPersister;
/**
* Provider options
*
* @var array
*/
protected $options = array(
'batch_size' => 100,
);
public function __construct(Elastica_Type $type, ObjectPersisterInterface $objectPersister, $objectClass, array $options = array())
public function doPopulate($options, \Closure $loggerClosure = null)
{
$this->type = $type;
$this->objectClass = $objectClass;
$this->objectPersister = $objectPersister;
$this->options = array_merge($this->options, $options);
}
$queryClass = $this->objectClass.'Query';
$nbObjects = $queryClass::create()->count();
/**
* Insert the repository objects in the type index
*
* @param Closure $loggerClosure
*/
public function populate(Closure $loggerClosure)
{
$queryClass = $this->objectClass . 'Query';
$nbObjects = $queryClass::create()->count();
$offset = $options['offset'];
for ($offset = 0; $offset < $nbObjects; $offset += $this->options['batch_size']) {
$stepStartTime = microtime(true);
for (; $offset < $nbObjects; $offset += $options['batch_size']) {
$objects = $queryClass::create()
->limit($this->options['batch_size'])
->limit($options['batch_size'])
->offset($offset)
->find();
->find()
->getArrayCopy();
$objects = $this->filterObjects($options, $objects);
if (!empty($objects)) {
$this->objectPersister->insertMany($objects);
}
$this->objectPersister->insertMany($objects->getArrayCopy());
usleep($options['sleep']);
$stepNbObjects = count($objects);
$stepCount = $stepNbObjects+$offset;
$objectsPerSecond = $stepNbObjects / (microtime(true) - $stepStartTime);
$loggerClosure(sprintf('%0.1f%% (%d/%d), %d objects/s', 100*$stepCount/$nbObjects, $stepCount, $nbObjects, $objectsPerSecond));
if ($loggerClosure) {
$loggerClosure($options['batch_size'], $nbObjects);
}
}
}
/**
* {@inheritDoc}
*/
protected function configureOptions()
{
parent::configureOptions();
$this->resolver->setDefaults(array(
'clear_object_manager' => true,
'debug_logging' => false,
'ignore_errors' => false,
'offset' => 0,
'query_builder_method' => null,
'sleep' => 0
));
}
/**
* {@inheritDoc}
*/
protected function disableLogging()
{
}
/**
* {@inheritDoc}
*/
protected function enableLogging($logger)
{
}
}

View file

@ -0,0 +1,195 @@
<?php
namespace FOS\ElasticaBundle\Provider;
use FOS\ElasticaBundle\Persister\ObjectPersisterInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* AbstractProvider.
*/
abstract class AbstractProvider implements ProviderInterface
{
/**
* @var array
*/
protected $baseOptions;
/**
* @var string
*/
protected $objectClass;
/**
* @var ObjectPersisterInterface
*/
protected $objectPersister;
/**
* @var OptionsResolver
*/
protected $resolver;
/**
* @var IndexableInterface
*/
private $indexable;
/**
* Constructor.
*
* @param ObjectPersisterInterface $objectPersister
* @param IndexableInterface $indexable
* @param string $objectClass
* @param array $baseOptions
*/
public function __construct(
ObjectPersisterInterface $objectPersister,
IndexableInterface $indexable,
$objectClass,
array $baseOptions = array()
) {
$this->baseOptions = $baseOptions;
$this->indexable = $indexable;
$this->objectClass = $objectClass;
$this->objectPersister = $objectPersister;
$this->resolver = new OptionsResolver();
$this->configureOptions();
}
/**
* {@inheritDoc}
*/
public function populate(\Closure $loggerClosure = null, array $options = array())
{
$options = $this->resolveOptions($options);
$logger = !$options['debug_logging'] ?
$this->disableLogging() :
null;
$this->doPopulate($options, $loggerClosure);
if (null !== $logger) {
$this->enableLogging($logger);
}
}
/**
* Disables logging and returns the logger that was previously set.
*
* @return mixed
*/
abstract protected function disableLogging();
/**
* Perform actual population.
*
* @param array $options
* @param \Closure $loggerClosure
*/
abstract protected function doPopulate($options, \Closure $loggerClosure = null);
/**
* Reenables the logger with the previously returned logger from disableLogging();.
*
* @param mixed $logger
*
* @return mixed
*/
abstract protected function enableLogging($logger);
/**
* Configures the option resolver.
*/
protected function configureOptions()
{
$this->resolver->setDefaults(array(
'batch_size' => 100,
'skip_indexable_check' => false,
));
$this->resolver->setAllowedTypes(array(
'batch_size' => 'int'
));
$this->resolver->setRequired(array(
'indexName',
'typeName',
));
}
/**
* Filters objects away if they are not indexable.
*
* @param array $options
* @param array $objects
* @return array
*/
protected function filterObjects(array $options, array $objects)
{
if ($options['skip_indexable_check']) {
return $objects;
}
$index = $options['indexName'];
$type = $options['typeName'];
$return = array();
foreach ($objects as $object) {
if (!$this->indexable->isObjectIndexable($index, $type, $object)) {
continue;
}
$return[] = $object;
}
return $return;
}
/**
* Checks if a given object should be indexed or not.
*
* @deprecated To be removed in 4.0
*
* @param object $object
*
* @return bool
*/
protected function isObjectIndexable($object)
{
return $this->indexable->isObjectIndexable(
$this->baseOptions['indexName'],
$this->baseOptions['typeName'],
$object
);
}
/**
* Get string with RAM usage information (current and peak).
*
* @deprecated To be removed in 4.0
*
* @return string
*/
protected function getMemoryUsage()
{
$memory = round(memory_get_usage() / (1024 * 1024)); // to get usage in Mo
$memoryMax = round(memory_get_peak_usage() / (1024 * 1024)); // to get max usage in Mo
return sprintf('(RAM : current=%uMo peak=%uMo)', $memory, $memoryMax);
}
/**
* Merges the base options provided by the class with options passed to the populate
* method and runs them through the resolver.
*
* @param array $options
*
* @return array
*/
protected function resolveOptions(array $options)
{
return $this->resolver->resolve(array_merge($this->baseOptions, $options));
}
}

240
Provider/Indexable.php Normal file
View file

@ -0,0 +1,240 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) FriendsOfSymfony <https://github.com/FriendsOfSymfony/FOSElasticaBundle/graphs/contributors>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Provider;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\SyntaxError;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
class Indexable implements IndexableInterface
{
/**
* An array of raw configured callbacks for all types.
*
* @var array
*/
private $callbacks = array();
/**
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
private $container;
/**
* An instance of ExpressionLanguage.
*
* @var ExpressionLanguage
*/
private $expressionLanguage;
/**
* An array of initialised callbacks.
*
* @var array
*/
private $initialisedCallbacks = array();
/**
* PropertyAccessor instance.
*
* @var PropertyAccessorInterface
*/
private $propertyAccessor;
/**
* @param array $callbacks
* @param ContainerInterface $container
*/
public function __construct(array $callbacks, ContainerInterface $container)
{
$this->callbacks = $callbacks;
$this->container = $container;
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
}
/**
* Return whether the object is indexable with respect to the callback.
*
* @param string $indexName
* @param string $typeName
* @param mixed $object
*
* @return bool
*/
public function isObjectIndexable($indexName, $typeName, $object)
{
$type = sprintf('%s/%s', $indexName, $typeName);
$callback = $this->getCallback($type, $object);
if (!$callback) {
return true;
}
if ($callback instanceof Expression) {
return (bool) $this->getExpressionLanguage()->evaluate($callback, array(
'object' => $object,
$this->getExpressionVar($object) => $object,
));
}
return is_string($callback)
? call_user_func(array($object, $callback))
: call_user_func($callback, $object);
}
/**
* Builds and initialises a callback.
*
* @param string $type
* @param object $object
*
* @return mixed
*/
private function buildCallback($type, $object)
{
if (!array_key_exists($type, $this->callbacks)) {
return;
}
$callback = $this->callbacks[$type];
if (is_callable($callback) or is_callable(array($object, $callback))) {
return $callback;
}
if (is_array($callback) && !is_object($callback[0])) {
return $this->processArrayToCallback($type, $callback);
}
if (is_string($callback)) {
return $this->buildExpressionCallback($type, $object, $callback);
}
throw new \InvalidArgumentException(sprintf('Callback for type "%s" is not a valid callback.', $type));
}
/**
* Processes a string expression into an Expression.
*
* @param string $type
* @param mixed $object
* @param string $callback
*
* @return Expression
*/
private function buildExpressionCallback($type, $object, $callback)
{
$expression = $this->getExpressionLanguage();
if (!$expression) {
throw new \RuntimeException('Unable to process an expression without the ExpressionLanguage component.');
}
try {
$callback = new Expression($callback);
$expression->compile($callback, array(
'object', $this->getExpressionVar($object)
));
return $callback;
} catch (SyntaxError $e) {
throw new \InvalidArgumentException(sprintf(
'Callback for type "%s" is an invalid expression',
$type
), $e->getCode(), $e);
}
}
/**
* Retreives a cached callback, or creates a new callback if one is not found.
*
* @param string $type
* @param object $object
*
* @return mixed
*/
private function getCallback($type, $object)
{
if (!array_key_exists($type, $this->initialisedCallbacks)) {
$this->initialisedCallbacks[$type] = $this->buildCallback($type, $object);
}
return $this->initialisedCallbacks[$type];
}
/**
* Returns the ExpressionLanguage class if it is available.
*
* @return ExpressionLanguage|null
*/
private function getExpressionLanguage()
{
if (null === $this->expressionLanguage && class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
$this->expressionLanguage = new ExpressionLanguage();
}
return $this->expressionLanguage;
}
/**
* Returns the variable name to be used to access the object when using the ExpressionLanguage
* component to parse and evaluate an expression.
*
* @param mixed $object
*
* @return string
*/
private function getExpressionVar($object = null)
{
if (!is_object($object)) {
return 'object';
}
$ref = new \ReflectionClass($object);
return strtolower($ref->getShortName());
}
/**
* Processes an array into a callback. Replaces the first element with a service if
* it begins with an @.
*
* @param string $type
* @param array $callback
* @return array
*/
private function processArrayToCallback($type, array $callback)
{
list($class, $method) = $callback + array(null, '__invoke');
if (strpos($class, '@') === 0) {
$service = $this->container->get(substr($class, 1));
$callback = array($service, $method);
if (!is_callable($callback)) {
throw new \InvalidArgumentException(sprintf(
'Method "%s" on service "%s" is not callable.',
$method,
substr($class, 1)
));
}
return $callback;
}
throw new \InvalidArgumentException(sprintf(
'Unable to parse callback array for type "%s"',
$type
));
}
}

View file

@ -0,0 +1,26 @@
<?php
/**
* This file is part of the FOSElasticaBundle project.
*
* (c) Infinite Networks Pty Ltd <http://www.infinite.net.au>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\ElasticaBundle\Provider;
interface IndexableInterface
{
/**
* Checks if an object passed should be indexable or not.
*
* @param string $indexName
* @param string $typeName
* @param mixed $object
*
* @return bool
*/
public function isObjectIndexable($indexName, $typeName, $object);
}

View file

@ -2,19 +2,25 @@
namespace FOS\ElasticaBundle\Provider;
use Closure;
/**
* Insert application domain objects into elastica types
* Insert application domain objects into elastica types.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
*/
interface ProviderInterface
{
/**
* Add all domain objects of a repository to the elastica type
* Persists all domain objects to ElasticSearch for this provider.
*
* @param Closure $loggerClosure
* The closure can expect 2 or 3 arguments:
* * The step size
* * The total number of objects
* * A message to output in error conditions (not normally provided)
*
* @param \Closure $loggerClosure
* @param array $options
*
* @return
*/
function populate(Closure $loggerClosure);
public function populate(\Closure $loggerClosure = null, array $options = array());
}

View file

@ -0,0 +1,107 @@
<?php
namespace FOS\ElasticaBundle\Provider;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* References persistence providers for each index and type.
*/
class ProviderRegistry implements ContainerAwareInterface
{
/**
* @var ContainerInterface
*/
private $container;
private $providers = array();
/**
* Registers a provider for the specified index and type.
*
* @param string $index
* @param string $type
* @param string $providerId
*/
public function addProvider($index, $type, $providerId)
{
if (!isset($this->providers[$index])) {
$this->providers[$index] = array();
}
$this->providers[$index][$type] = $providerId;
}
/**
* Gets all registered providers.
*
* Providers will be indexed by "index/type" strings in the returned array.
*
* @return array of ProviderInterface instances
*/
public function getAllProviders()
{
$providers = array();
foreach ($this->providers as $index => $indexProviders) {
foreach ($indexProviders as $type => $providerId) {
$providers[sprintf('%s/%s', $index, $type)] = $this->container->get($providerId);
}
}
return $providers;
}
/**
* Gets all providers for an index.
*
* Providers will be indexed by "type" strings in the returned array.
*
* @param string $index
*
* @return ProviderInterface[]
*
* @throws \InvalidArgumentException if no providers were registered for the index
*/
public function getIndexProviders($index)
{
if (!isset($this->providers[$index])) {
throw new \InvalidArgumentException(sprintf('No providers were registered for index "%s".', $index));
}
$providers = array();
foreach ($this->providers[$index] as $type => $providerId) {
$providers[$type] = $this->container->get($providerId);
}
return $providers;
}
/**
* Gets the provider for an index and type.
*
* @param string $index
* @param string $type
*
* @return ProviderInterface
*
* @throws \InvalidArgumentException if no provider was registered for the index and type
*/
public function getProvider($index, $type)
{
if (!isset($this->providers[$index][$type])) {
throw new \InvalidArgumentException(sprintf('No provider was registered for index "%s" and type "%s".', $index, $type));
}
return $this->container->get($this->providers[$index][$type]);
}
/**
* @see Symfony\Component\DependencyInjection\ContainerAwareInterface::setContainer()
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}

568
README.md
View file

@ -1,559 +1,35 @@
[Elastica](https://github.com/ruflin/Elastica) integration in Symfony2
FOSElasticaBundle
=================
### Installation
This bundle provides integration with [ElasticSearch](http://www.elasticsearch.org) and [Elastica](https://github.com/ruflin/Elastica) with
Symfony2. Features include:
#### Bundle and Dependencies
- Integrates the Elastica library into a Symfony2 environment
- Automatically generate mappings using a serializer
- Listeners for Doctrine events for automatic indexing
For Symfony 2.0.x projects, you must use a 1.x release of this bundle.
> **Note** Propel support is limited and contributions fixing issues are welcome!
Add FOSElasticaBundle to your application's `composer.json` file:
[![Build Status](https://secure.travis-ci.org/FriendsOfSymfony/FOSElasticaBundle.png?branch=master)](http://travis-ci.org/FriendsOfSymfony/FOSElasticaBundle) [![Total Downloads](https://poser.pugx.org/FriendsOfSymfony/elastica-bundle/downloads.png)](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle) [![Latest Stable Version](https://poser.pugx.org/FriendsOfSymfony/elastica-bundle/v/stable.png)](https://packagist.org/packages/FriendsOfSymfony/elastica-bundle) [![Latest Unstable Version](https://poser.pugx.org/friendsofsymfony/elastica-bundle/v/unstable.svg)](https://packagist.org/packages/friendsofsymfony/elastica-bundle)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSElasticaBundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/FriendsOfSymfony/FOSElasticaBundle/?branch=master)
```json
{
"require": {
"friendsofsymfony/elastica-bundle": "~1.0"
}
}
```
Documentation
-------------
Install the bundle and its dependencies with the following command:
Documentation for FOSElasticaBundle is in `Resources/doc/index.md`
```bash
$ php composer.phar update friendsofsymfony/elastica-bundle
```
[Read the documentation for 3.1.x](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/index.md)
You may rely on Composer to fetch the appropriate version of Elastica. Lastly,
enable the bundle in your application kernel:
[Read the documentation for 3.0.x](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/3.0.x/Resources/doc/index.md)
```php
// app/AppKernel.php
Installation
------------
public function registerBundles()
{
$bundles = array(
// ...
new FOS\ElasticaBundle\FOSElasticaBundle(),
);
}
```
Installation instructions can be found in the [documentation](https://github.com/FriendsOfSymfony/FOSElasticaBundle/blob/master/Resources/doc/setup.md)
#### Elasticsearch
License
-------
Instructions for installing and deploying Elasticsearch may be found
[here](http://www.elasticsearch.org/guide/reference/setup/installation/).
This bundle is under the MIT license. See the complete license in the bundle:
### Basic configuration
#### Declare a client
Elasticsearch client is comparable to a database connection.
Most of the time, you will need only one.
#app/config/config.yml
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
#### Declare an index
Elasticsearch index is comparable to Doctrine entity manager.
Most of the time, you will need only one.
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
website:
client: default
Here we created a "website" index, that uses our "default" client.
Our index is now available as a service: `fos_elastica.index.website`. It is an instance of `Elastica_Index`.
#### Declare a type
Elasticsearch type is comparable to Doctrine entity repository.
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
website:
client: default
types:
user:
mappings:
username: { boost: 5 }
firstName: { boost: 3 }
lastName: { boost: 3 }
aboutMe:
Our type is now available as a service: `fos_elastica.index.website.user`. It is an instance of `Elastica_Type`.
### Populate the types
php app/console fos:elastica:populate
This command deletes and creates the declared indexes and types.
It applies the configured mappings to the types.
This command needs providers to insert new documents in the elasticsearch types.
There are 2 ways to create providers.
If your elasticsearch type matches a Doctrine repository or a Propel query, go for the persistence automatic provider.
Or, for complete flexibility, go for manual provider.
#### Persistence automatic provider
If we want to index the entities from a Doctrine repository or a Propel query,
some configuration will let ElasticaBundle do it for us.
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
website:
client: default
types:
user:
mappings:
username: { boost: 5 }
firstName: { boost: 3 }
# more mappings...
persistence:
driver: orm # orm, mongodb, propel are available
model: Application\UserBundle\Entity\User
provider:
Three drivers are actually supported: orm, mongodb, and propel.
##### Use a custom Doctrine query builder
You can control which entities will be indexed by specifying a custom query builder method.
persistence:
driver: orm
model: Application\UserBundle\Entity\User
provider:
query_builder_method: createIsActiveQueryBuilder
Your repository must implement this method and return a Doctrine query builder.
> **Propel** doesn't support this feature yet.
##### Change the batch size
By default, ElasticaBundle will index documents by paquets of 100.
You can change this value in the provider configuration.
persistence:
driver: orm
model: Application\UserBundle\Entity\User
provider:
batch_size: 100
##### Change the document identifier field
By default, ElasticaBundle will use the `id` field of your entities as the elasticsearch document identifier.
You can change this value in the provider configuration.
persistence:
driver: orm
model: Application\UserBundle\Entity\User
provider:
identifier: id
#### Manual provider
Create a service with the tag "fos_elastica.provider".
<service id="acme.search_provider.user" class="Acme\UserBundle\Search\UserProvider">
<tag name="fos_elastica.provider" />
<argument type="service" id="fos_elastica.index.website.user" />
</service>
Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
<?php
namespace Acme\UserBundle\Provider;
use FOS\ElasticaBundle\Provider\ProviderInterface;
use Elastica_Type;
class UserProvider implements ProviderInterface
{
protected $userType;
public function __construct(Elastica_Type $userType)
{
$this->userType = $userType;
}
/**
* Insert the repository objects in the type index
*
* @param Closure $loggerClosure
*/
public function populate(Closure $loggerClosure)
{
$loggerClosure('Indexing users');
$document = new \Elastica_Document();
$document->setData(array('username' => 'Bob'));
$this->userType->addDocuments(array($document));
}
}
You will find a more complete implementation example in `src/FOS/ElasticaBundle/Doctrine/AbstractProvider.php`.
### Search
You can just use the index and type Elastica objects, provided as services, to perform searches.
/** var Elastica_Type */
$userType = $this->container->get('fos_elastica.index.website.user');
/** var Elastica_ResultSet */
$resultSet = $userType->search('bob');
#### Doctrine/Propel finder
If your elasticsearch type is bound to a Doctrine entity repository or a Propel query,
you can get your entities instead of Elastica results when you perform a search.
Declare that you want a Doctrine/Propel finder in your configuration:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
website:
client: default
types:
user:
mappings:
# your mappings
persistence:
driver: orm
model: Application\UserBundle\Entity\User
provider:
finder:
You can now use the `fos_elastica.finder.website.user` service:
/** var FOS\ElasticaBundle\Finder\TransformedFinder */
$finder = $container->get('fos_elastica.finder.website.user');
/** var array of Acme\UserBundle\Entity\User */
$users = $finder->find('bob');
/** var array of Acme\UserBundle\Entity\User limited to 10 results */
$users = $finder->find('bob', 10);
You can even get paginated results!
/** var Pagerfanta\Pagerfanta */
$userPaginator = $finder->findPaginated('bob');
You can also get both the Elastica results and the entities together from the finder.
YOu can then access the score, highlights etc. from the Elastica_Result whilst
still also getting the entity.
/** var array of FOS\ElasticaBundle\HybridResult */
$hybridResults = $finder->findHybrid('bob');
foreach ($hybridResults as $hybridResult) {
/** var Acme\UserBundle\Entity\User */
$user = $hybridResult->getTransformed();
/** var Elastica_Result */
$result = $hybridResult->getResult();
}
##### Index wide finder
You can also define a finder that will work on the entire index. Adjust your index
configuration as per below:
fos_elastica:
indexes:
website:
client: default
finder:
You can now use the index wide finder service `fos_elastica.finder.website`:
/** var FOS\ElasticaBundle\Finder\MappedFinder */
$finder = $container->get('fos_elastica.finder.website');
// Returns a mixed array of any objects mapped
$results = $finder->find('bob');
#### Repositories
As well as using the finder service for a particular Doctrine/Propel entity you
can use a manager service for each driver and get a repository for an entity to search
against. This allows you to use the same service rather than the particular finder. For
example:
/** var FOS\ElasticaBundle\Manager\RepositoryManager */
$repositoryManager = $container->get('fos_elastica.manager.orm');
/** var FOS\ElasticaBundle\Repository */
$repository = $repositoryManager->getRepository('UserBundle:User');
/** var array of Acme\UserBundle\Entity\User */
$users = $finder->find('bob');
You can also specify the full name of the entity instead of the shortcut syntax:
/** var FOS\ElasticaBundle\Repository */
$repository = $repositoryManager->getRepository('Application\UserBundle\Entity\User');
> The **2.0** branch doesn't support using `UserBundle:User` style syntax and you must use the full name of the entity. .
##### Default Manager
If you are only using one driver then its manager service is automatically aliased
to `fos_elastica.manager`. So the above example could be simplified to:
/** var FOS\ElasticaBundle\Manager\RepositoryManager */
$repositoryManager = $container->get('fos_elastica.manager');
/** var FOS\ElasticaBundle\Repository */
$repository = $repositoryManager->getRepository('UserBundle:User');
/** var array of Acme\UserBundle\Entity\User */
$users = $finder->find('bob');
If you use multiple drivers then you can choose which one is aliased to `fos_elastica.manager`
using the `default_manager` parameter:
fos_elastica:
default_manager: mongodb #defauults to orm
clients:
default: { host: localhost, port: 9200 }
#--
##### Custom Repositories
As well as the default repository you can create a custom repository for an entity and add
methods for particular searches. These need to extend `FOS\ElasticaBundle\Repository` to have
access to the finder:
```
<?php
namespace Acme\ElasticaBundle\SearchRepository;
use FOS\ElasticaBundle\Repository;
class UserRepository extends Repository
{
public function findWithCustomQuery($searchText)
{
// build $query with Elastica objects
$this->find($query);
}
}
```
To use the custom repository specify it in the mapping for the entity:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
website:
client: default
types:
user:
mappings:
# your mappings
persistence:
driver: orm
model: Application\UserBundle\Entity\User
provider:
finder:
repository: Acme\ElasticaBundle\SearchRepository\UserRepository
Then the custom queries will be available when using the repository returned from the manager:
/** var FOS\ElasticaBundle\Manager\RepositoryManager */
$repositoryManager = $container->get('fos_elastica.manager');
/** var FOS\ElasticaBundle\Repository */
$repository = $repositoryManager->getRepository('UserBundle:User');
/** var array of Acme\UserBundle\Entity\User */
$users = $finder->findWithCustomQuery('bob');
Alternatively you can specify the custom repository using an annotation in the entity:
```
<?php
namespace Application\UserBundle\Entity;
use FOS\ElasticaBundle\Configuration\Search;
/**
* @Search(repositoryClass="Acme\ElasticaBundle\SearchRepository\UserRepository")
*/
class User
{
//---
}
```
### Realtime, selective index update
If you use the Doctrine integration, you can let ElasticaBundle update the indexes automatically
when an object is added, updated or removed. It uses Doctrine lifecycle events.
Declare that you want to update the index in real time:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
website:
client: default
types:
user:
mappings:
# your mappings
persistence:
driver: orm
model: Application\UserBundle\Entity\User
listener: # by default, listens to "insert", "update" and "delete"
Now the index is automatically updated each time the state of the bound Doctrine repository changes.
No need to repopulate the whole "user" index when a new `User` is created.
You can also choose to only listen for some of the events:
persistence:
listener:
insert: true
update: false
delete: true
> **Propel** doesn't support this feature yet.
### Advanced elasticsearch configuration
Any setting can be specified when declaring a type. For example, to enable a custom analyzer, you could write:
fos_elastica:
indexes:
doc:
settings:
index:
analysis:
analyzer:
my_analyzer:
type: custom
tokenizer: lowercase
filter : [my_ngram]
filter:
my_ngram:
type: "nGram"
min_gram: 3
max_gram: 5
types:
blog:
mappings:
title: { boost: 8, analyzer: my_analyzer }
### Overriding the Client class to suppress exceptions
By default, exceptions from the Elastica client library will propagate through
the bundle's Client class. For instance, if the elasticsearch server is offline,
issuing a request will result in an `Elastica_Exception_Client` being thrown.
Depending on your needs, it may be desirable to suppress these exceptions and
allow searches to fail silently.
One way to achieve this is to override the `fos_elastica.client.class` service
container parameter with a custom class. In the following example, we override
the `Client::request()` method and return the equivalent of an empty search
response if an exception occurred.
```
<?php
namespace Acme\ElasticaBundle;
use FOS\ElasticaBundle\Client as BaseClient;
class Client extends BaseClient
{
public function request($path, $method, $data = array())
{
try {
return parent::request($path, $method, $data);
} catch (\Elastica_Exception_Abstract $e) {
return new \Elastica_Response('{"took":0,"timed_out":false,"hits":{"total":0,"max_score":0,"hits":[]}}');
}
}
}
```
### Example of Advanced Query
If you would like to perform more advanced queries, here is one example using
the snowball stemming algorithm.
It searches for Article entities using `title`, `tags`, and `categoryIds`.
Results must match at least one specified `categoryIds`, and should match the
`title` or `tags` criteria. Additionally, we define a snowball analyzer to
apply to queries against the `title` field.
```php
$finder = $this->container->get('fos_elastica.finder.website.article');
$boolQuery = new \Elastica_Query_Bool();
$fieldQuery = new \Elastica_Query_Text();
$fieldQuery->setFieldQuery('title', 'I am a title string');
$fieldQuery->setFieldParam('title', 'analyzer', 'my_analyzer');
$boolQuery->addShould($fieldQuery);
$tagsQuery = new \Elastica_Query_Terms();
$tagsQuery->setTerms('tags', array('tag1', 'tag2'));
$boolQuery->addShould($tagsQuery);
$categoryQuery = new \Elastica_Query_Terms();
$categoryQuery->setTerms('categoryIds', array('1', '2', '3'));
$boolQuery->addMust($categoryQuery);
$data = $finder->find($boolQuery);
```
Configuration:
```yaml
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
site:
settings:
index:
analysis:
analyzer:
my_analyzer:
type: snowball
language: English
types:
article:
mappings:
title: { boost: 10, analyzer: my_analyzer }
tags:
categoryIds:
persistence:
driver: orm
model: Acme\DemoBundle\Entity\Article
provider:
finder:
```
Resources/meta/LICENSE

View file

@ -2,33 +2,66 @@
namespace FOS\ElasticaBundle;
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
/**
* @author Richard Miller <info@limethinking.co.uk>
*
* Basic respoitory to be extended to hold custom queries to be run
* Basic repository to be extended to hold custom queries to be run
* in the finder.
*/
class Repository
{
protected $finder;
public function __construct($finder)
public function __construct(PaginatedFinderInterface $finder)
{
$this->finder = $finder;
}
public function find($query, $limit=null)
/**
* @param mixed $query
* @param integer $limit
* @param array $options
*
* @return array
*/
public function find($query, $limit = null, $options = array())
{
return $this->finder->find($query, $limit);
return $this->finder->find($query, $limit, $options);
}
public function findHybrid($query, $limit=null)
/**
* @param mixed $query
* @param integer $limit
* @param array $options
*
* @return mixed
*/
public function findHybrid($query, $limit = null, $options = array())
{
return $this->finder->findHybrid($query, $limit);
return $this->finder->findHybrid($query, $limit, $options);
}
public function findPaginated($query)
/**
* @param mixed $query
* @param array $options
*
* @return \Pagerfanta\Pagerfanta
*/
public function findPaginated($query, $options = array())
{
return $this->finder->findPaginated($query);
return $this->finder->findPaginated($query, $options);
}
/**
* @param string $query
* @param array $options
*
* @return Paginator\PaginatorAdapterInterface
*/
public function createPaginatorAdapter($query, $options = array())
{
return $this->finder->createPaginatorAdapter($query, $options);
}
}

View file

@ -1,35 +0,0 @@
<?php
namespace FOS\ElasticaBundle;
use Elastica_Exception_Response;
/**
* Deletes and recreates indexes
**/
class Reseter
{
/**
* Index settings and mappings
*
* @var array
*/
protected $indexConfigs;
public function __construct(array $indexConfigs)
{
$this->indexConfigs = $indexConfigs;
}
/**
* Resets all indexes
*
* @return null
**/
public function reset()
{
foreach ($this->indexConfigs as $indexConfig) {
$indexConfig['index']->create($indexConfig['config'], true);
}
}
}

12
Resetter.php Normal file
View file

@ -0,0 +1,12 @@
<?php
namespace FOS\ElasticaBundle;
use FOS\ElasticaBundle\Index\Resetter as BaseResetter;
/**
* @deprecated Use \FOS\ElasticaBundle\Index\Resetter
*/
class Resetter extends BaseResetter
{
}

View file

@ -1,71 +1,51 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_elastica.client.class">FOS\ElasticaBundle\Client</parameter>
<parameter key="fos_elastica.index.class">Elastica_Index</parameter>
<parameter key="fos_elastica.type.class">Elastica_Type</parameter>
<parameter key="fos_elastica.client.class">FOS\ElasticaBundle\Elastica\Client</parameter>
<parameter key="fos_elastica.logger.class">FOS\ElasticaBundle\Logger\ElasticaLogger</parameter>
<parameter key="fos_elastica.data_collector.class">FOS\ElasticaBundle\DataCollector\ElasticaDataCollector</parameter>
<parameter key="fos_elastica.manager.class">FOS\ElasticaBundle\Manager\RepositoryManager</parameter>
<parameter key="fos_elastica.elastica_to_model_transformer.collection.class">FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection</parameter>
<parameter key="fos_elastica.mapping_builder.class">FOS\ElasticaBundle\Index\MappingBuilder</parameter>
<parameter key="fos_elastica.property_accessor.class">Symfony\Component\PropertyAccess\PropertyAccessor</parameter>
</parameters>
<services>
<service id="fos_elastica.client_prototype" class="%fos_elastica.client.class%" abstract="true">
<argument type="collection" /> <!-- configuration -->
<argument /> <!-- callback -->
<call method="setStopwatch">
<argument type="service" id="debug.stopwatch" on-invalid="null" />
</call>
</service>
<service id="fos_elastica.config_manager" class="FOS\ElasticaBundle\Configuration\ConfigManager">
<argument type="collection" /> <!-- collection of SourceInterface services -->
</service>
<service id="fos_elastica.data_collector" class="%fos_elastica.data_collector.class%">
<tag name="data_collector" template="FOSElasticaBundle:Collector:elastica" id="elastica" />
<argument type="service" id="fos_elastica.logger" />
</service>
<service id="fos_elastica.paginator.subscriber" class="FOS\ElasticaBundle\Subscriber\PaginateElasticaQuerySubscriber">
<call method="setRequest">
<argument type="service" id="request" on-invalid="null" strict="false" />
</call>
<tag name="knp_paginator.subscriber" />
</service>
<service id="fos_elastica.logger" class="%fos_elastica.logger.class%">
<argument type="service" id="logger" on-invalid="null" />
<argument>%kernel.debug%</argument>
<tag name="monolog.logger" channel="elastica" />
</service>
<service id="fos_elastica.data_collector" class="%fos_elastica.data_collector.class%" public="true">
<tag name="data_collector" template="FOSElasticaBundle:Collector:elastica" id="elastica" />
<argument type="service" id="fos_elastica.logger" />
</service>
<service id="fos_elastica.client" class="%fos_elastica.client.class%">
<argument /> <!-- config -->
<call method="setLogger">
<argument type="service" id="fos_elastica.logger" />
</call>
</service>
<service id="fos_elastica.index_manager" class="FOS\ElasticaBundle\IndexManager">
<argument /> <!-- indexes -->
<argument /> <!-- default index -->
</service>
<service id="fos_elastica.populator" class="FOS\ElasticaBundle\Populator">
<argument /> <!-- providers -->
</service>
<service id="fos_elastica.reseter" class="FOS\ElasticaBundle\Reseter">
<argument /> <!-- index configs -->
</service>
<service id="fos_elastica.object_persister.prototype" class="FOS\ElasticaBundle\Persister\ObjectPersister" abstract="true">
<argument /> <!-- type -->
<argument /> <!-- model to elastica transformer -->
<argument /> <!-- model -->
<argument /> <!-- properties mapping -->
</service>
<service id="fos_elastica.finder.prototype" class="FOS\ElasticaBundle\Finder\TransformedFinder" public="true" abstract="true">
<argument /> <!-- searchable -->
<argument /> <!-- transformer -->
</service>
<service id="fos_elastica.model_to_elastica_transformer.prototype.auto" class="FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer" public="false" abstract="true">
<argument /> <!-- options -->
</service>
<service id="fos_elastica.elastica_to_model_transformer.collection.prototype" class="%fos_elastica.elastica_to_model_transformer.collection.class%" public="true" abstract="true">
<argument type="collection" /> <!-- transformers -->
</service>
<service id="fos_elastica.mapping_builder" class="%fos_elastica.mapping_builder.class%" />
<service id="fos_elastica.property_accessor" class="%fos_elastica.property_accessor.class%" />
</services>
</container>

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_elastica.alias_processor.class">FOS\ElasticaBundle\Index\AliasProcessor</parameter>
<parameter key="fos_elastica.finder.class">FOS\ElasticaBundle\Finder\TransformedFinder</parameter>
<parameter key="fos_elastica.index.class">FOS\ElasticaBundle\Elastica\Index</parameter>
<parameter key="fos_elastica.indexable.class">FOS\ElasticaBundle\Provider\Indexable</parameter>
<parameter key="fos_elastica.index_manager.class">FOS\ElasticaBundle\Index\IndexManager</parameter>
<parameter key="fos_elastica.resetter.class">FOS\ElasticaBundle\Index\Resetter</parameter>
<parameter key="fos_elastica.type.class">Elastica\Type</parameter>
</parameters>
<services>
<service id="fos_elastica.alias_processor" class="%fos_elastica.alias_processor.class%" />
<service id="fos_elastica.indexable" class="%fos_elastica.indexable.class%">
<argument type="collection" /> <!-- array of indexable callbacks keyed by type name -->
<argument type="service" id="service_container" />
</service>
<service id="fos_elastica.index_prototype" class="%fos_elastica.index.class%" factory-service="fos_elastica.client" factory-method="getIndex" abstract="true">
<argument /> <!-- index name -->
<!-- tagged with fos_elastica.index in the Extension -->
</service>
<service id="fos_elastica.type_prototype" class="%fos_elastica.type.class%" factory-method="getType" abstract="true">
<argument /> <!-- type name -->
</service>
<service id="fos_elastica.index_manager" class="%fos_elastica.index_manager.class%">
<argument /> <!-- indexes -->
<argument type="service" id="fos_elastica.index" /> <!-- default index -->
</service>
<service id="fos_elastica.resetter" class="%fos_elastica.resetter.class%">
<argument type="service" id="fos_elastica.config_manager" />
<argument type="service" id="fos_elastica.index_manager" />
<argument type="service" id="fos_elastica.alias_processor" />
<argument type="service" id="fos_elastica.mapping_builder" />
<argument type="service" id="event_dispatcher"/>
</service>
<!-- Abstract definition for all finders. -->
<service id="fos_elastica.finder" class="%fos_elastica.finder.class%" public="true" abstract="true">
<argument /> <!-- searchable -->
<argument /> <!-- transformer -->
</service>
</services>
</container>

View file

@ -4,33 +4,46 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_elastica.slice_fetcher.mongodb.class">FOS\ElasticaBundle\Doctrine\MongoDB\SliceFetcher</parameter>
<parameter key="fos_elastica.provider.prototype.mongodb.class">FOS\ElasticaBundle\Doctrine\MongoDB\Provider</parameter>
<parameter key="fos_elastica.listener.prototype.mongodb.class">FOS\ElasticaBundle\Doctrine\Listener</parameter>
<parameter key="fos_elastica.elastica_to_model_transformer.prototype.mongodb.class">FOS\ElasticaBundle\Doctrine\MongoDB\ElasticaToModelTransformer</parameter>
<parameter key="fos_elastica.manager.mongodb.class">FOS\ElasticaBundle\Doctrine\RepositoryManager</parameter>
</parameters>
<services>
<service id="fos_elastica.slice_fetcher.mongodb" class="%fos_elastica.slice_fetcher.mongodb.class%">
</service>
<service id="fos_elastica.provider.prototype.mongodb" class="FOS\ElasticaBundle\Doctrine\MongoDB\Provider" public="false" abstract="true">
<argument /> <!-- type -->
<argument type="service" id="doctrine.odm.mongodb.document_manager" />
<service id="fos_elastica.provider.prototype.mongodb" class="%fos_elastica.provider.prototype.mongodb.class%" public="true" abstract="true">
<argument /> <!-- object persister -->
<argument type="service" id="fos_elastica.indexable" />
<argument /> <!-- model -->
<argument type="collection" /> <!-- options -->
<argument type="service" id="doctrine_mongodb" /> <!-- manager registry -->
<argument type="service" id="fos_elastica.slice_fetcher.mongodb" /> <!-- slice fetcher -->
</service>
<service id="fos_elastica.listener.prototype.mongodb" class="FOS\ElasticaBundle\Doctrine\MongoDB\Listener" public="false" abstract="true">
<service id="fos_elastica.listener.prototype.mongodb" class="%fos_elastica.listener.prototype.mongodb.class%" public="false" abstract="true">
<argument /> <!-- object persister -->
<argument /> <!-- model -->
<argument type="collection" /> <!-- events -->
<argument/> <!-- identifier -->
<argument type="service" id="fos_elastica.indexable" />
<argument type="collection" /> <!-- configuration -->
<argument>null</argument> <!-- logger -->
</service>
<service id="fos_elastica.elastica_to_model_transformer.prototype.mongodb" class="FOS\ElasticaBundle\Doctrine\MongoDB\ElasticaToModelTransformer" public="false">
<argument type="service" id="doctrine.odm.mongodb.document_manager" />
<service id="fos_elastica.elastica_to_model_transformer.prototype.mongodb" class="%fos_elastica.elastica_to_model_transformer.prototype.mongodb.class%" public="false" abstract="true">
<argument type="service" id="doctrine_mongodb" />
<argument /> <!-- model -->
<argument type="collection" /> <!-- options -->
<call method="setPropertyAccessor">
<argument type="service" id="fos_elastica.property_accessor" />
</call>
</service>
<service id="fos_elastica.manager.mongodb" class="%fos_elastica.manager.class%">
<service id="fos_elastica.manager.mongodb" class="%fos_elastica.manager.mongodb.class%">
<argument type="service" id="doctrine_mongodb"/>
<argument type="service" id="annotation_reader"/>
</service>
</services>
</container>

View file

@ -1,36 +1,49 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_elastica.slice_fetcher.orm.class">FOS\ElasticaBundle\Doctrine\ORM\SliceFetcher</parameter>
<parameter key="fos_elastica.provider.prototype.orm.class">FOS\ElasticaBundle\Doctrine\ORM\Provider</parameter>
<parameter key="fos_elastica.listener.prototype.orm.class">FOS\ElasticaBundle\Doctrine\Listener</parameter>
<parameter key="fos_elastica.elastica_to_model_transformer.prototype.orm.class">FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer</parameter>
<parameter key="fos_elastica.manager.orm.class">FOS\ElasticaBundle\Doctrine\RepositoryManager</parameter>
</parameters>
<services>
<service id="fos_elastica.slice_fetcher.orm" class="%fos_elastica.slice_fetcher.orm.class%">
</service>
<service id="fos_elastica.provider.prototype.orm" class="FOS\ElasticaBundle\Doctrine\ORM\Provider" public="false" abstract="true">
<argument /> <!-- type -->
<argument type="service" id="doctrine.orm.entity_manager" />
<service id="fos_elastica.provider.prototype.orm" class="%fos_elastica.provider.prototype.orm.class%" public="true" abstract="true">
<argument /> <!-- object persister -->
<argument type="service" id="fos_elastica.indexable" />
<argument /> <!-- model -->
<argument type="collection" /> <!-- options -->
<argument type="service" id="doctrine" /> <!-- manager registry -->
<argument type="service" id="fos_elastica.slice_fetcher.orm" /> <!-- slice fetcher -->
</service>
<service id="fos_elastica.listener.prototype.orm" class="FOS\ElasticaBundle\Doctrine\ORM\Listener" public="false" abstract="true">
<service id="fos_elastica.listener.prototype.orm" class="%fos_elastica.listener.prototype.orm.class%" public="false" abstract="true">
<argument /> <!-- object persister -->
<argument /> <!-- model -->
<argument type="collection" /> <!-- events -->
<argument/> <!-- identifier -->
<argument type="service" id="fos_elastica.indexable" />
<argument type="collection" /> <!-- configuration -->
<argument>null</argument> <!-- logger -->
</service>
<service id="fos_elastica.elastica_to_model_transformer.prototype.orm" class="FOS\ElasticaBundle\Doctrine\ORM\ElasticaToModelTransformer" public="false">
<argument type="service" id="doctrine.orm.entity_manager" />
<service id="fos_elastica.elastica_to_model_transformer.prototype.orm" class="%fos_elastica.elastica_to_model_transformer.prototype.orm.class%" public="false" abstract="true">
<argument type="service" id="doctrine" />
<argument /> <!-- model -->
<argument type="collection" /> <!-- options -->
<call method="setPropertyAccessor">
<argument type="service" id="fos_elastica.property_accessor" />
</call>
</service>
<service id="fos_elastica.manager.orm" class="%fos_elastica.manager.class%">
<argument type="service" id="annotation_reader"/>
<service id="fos_elastica.manager.orm" class="%fos_elastica.manager.orm.class%">
<argument type="service" id="doctrine" />
<argument type="service" id="annotation_reader" />
</service>
</services>
</container>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_elastica.object_persister.class">FOS\ElasticaBundle\Persister\ObjectPersister</parameter>
<parameter key="fos_elastica.object_serializer_persister.class">FOS\ElasticaBundle\Persister\ObjectSerializerPersister</parameter>
</parameters>
<services>
<service id="fos_elastica.object_persister" class="%fos_elastica.object_persister.class%" abstract="true">
<argument /> <!-- type -->
<argument /> <!-- model to elastica transformer -->
<argument /> <!-- model -->
<argument /> <!-- properties mapping -->
</service>
<service id="fos_elastica.object_serializer_persister" class="%fos_elastica.object_serializer_persister.class%" abstract="true">
<argument /> <!-- type -->
<argument /> <!-- model to elastica transformer -->
<argument /> <!-- model -->
<argument /> <!-- serializer -->
</service>
</services>
</container>

View file

@ -4,10 +4,9 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_elastica.provider.prototype.propel" class="FOS\ElasticaBundle\Propel\Provider" public="false" abstract="true">
<argument /> <!-- type -->
<service id="fos_elastica.provider.prototype.propel" class="FOS\ElasticaBundle\Propel\Provider" public="true" abstract="true">
<argument /> <!-- object persister -->
<argument type="service" id="fos_elastica.indexable" />
<argument /> <!-- model -->
<argument type="collection" /> <!-- options -->
</service>
@ -15,12 +14,13 @@
<service id="fos_elastica.elastica_to_model_transformer.prototype.propel" class="FOS\ElasticaBundle\Propel\ElasticaToModelTransformer" public="false">
<argument /> <!-- model -->
<argument type="collection" /> <!-- options -->
<call method="setPropertyAccessor">
<argument type="service" id="fos_elastica.property_accessor" />
</call>
</service>
<service id="fos_elastica.manager.propel" class="%fos_elastica.manager.class%">
<service id="fos_elastica.manager.propel" class="FOS\ElasticaBundle\Doctrine\RepositoryManager">
<argument type="service" id="annotation_reader"/>
</service>
</services>
</container>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_elastica.provider_registry.class">FOS\ElasticaBundle\Provider\ProviderRegistry</parameter>
</parameters>
<services>
<service id="fos_elastica.provider_registry" class="%fos_elastica.provider_registry.class%">
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
</services>
</container>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_elastica.serializer_callback_prototype" public="false" abstract="true">
<call method="setSerializer">
<argument type="service" id="fos_elastica.serializer" />
</call>
</service>
</services>
</container>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="fos_elastica.config_source.container" class="FOS\ElasticaBundle\Configuration\Source\ContainerSource" public="false">
<argument type="collection" /> <!-- index configs -->
<tag name="fos_elastica.config_source" />
</service>
</services>
</container>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_elastica.elastica_to_model_transformer.collection.class">FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection</parameter>
<parameter key="fos_elastica.model_to_elastica_transformer.class">FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer</parameter>
<parameter key="fos_elastica.model_to_elastica_identifier_transformer.class">FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer</parameter>
</parameters>
<services>
<service id="fos_elastica.model_to_elastica_transformer" class="%fos_elastica.model_to_elastica_transformer.class%" public="false" abstract="true">
<argument type="collection" /> <!-- options -->
<argument type="service" id="event_dispatcher" /> <!-- options -->
<call method="setPropertyAccessor">
<argument type="service" id="fos_elastica.property_accessor" />
</call>
</service>
<service id="fos_elastica.model_to_elastica_identifier_transformer" class="%fos_elastica.model_to_elastica_identifier_transformer.class%" public="false" abstract="true">
<argument type="collection" /> <!-- options -->
<call method="setPropertyAccessor">
<argument type="service" id="fos_elastica.property_accessor" />
</call>
</service>
<service id="fos_elastica.elastica_to_model_transformer.collection" class="%fos_elastica.elastica_to_model_transformer.collection.class%" public="true" abstract="true">
<argument type="collection" /> <!-- transformers -->
</service>
</services>
</container>

Some files were not shown because too many files have changed in this diff Show more