From 4c961a757d8b9cca38e1312f196f0a766192fb88 Mon Sep 17 00:00:00 2001 From: Tim Nagel Date: Mon, 21 Apr 2014 09:21:50 +1000 Subject: [PATCH 1/3] Deprecate top level classes --- CHANGELOG-3.0.md | 14 +- Client.php | 38 +-- DynamicIndex.php | 22 +- Elastica/LoggingClient.php | 47 ++++ Elastica/TransformingIndex.php | 45 ++++ Index/IndexManager.php | 63 +++++ Index/Resetter.php | 246 ++++++++++++++++++ IndexManager.php | 61 +---- Resetter.php | 238 +---------------- Resources/config/config.xml | 4 +- .../LoggingClientTest.php} | 6 +- Tests/{ => Index}/IndexManagerTest.php | 4 +- Tests/{ => Index}/ResetterTest.php | 4 +- 13 files changed, 436 insertions(+), 356 deletions(-) create mode 100644 Elastica/LoggingClient.php create mode 100644 Elastica/TransformingIndex.php create mode 100644 Index/IndexManager.php create mode 100644 Index/Resetter.php rename Tests/{ClientTest.php => Elastica/LoggingClientTest.php} (86%) rename Tests/{ => Index}/IndexManagerTest.php (95%) rename Tests/{ => Index}/ResetterTest.php (98%) diff --git a/CHANGELOG-3.0.md b/CHANGELOG-3.0.md index abd05cd..e57fb4d 100644 --- a/CHANGELOG-3.0.md +++ b/CHANGELOG-3.0.md @@ -12,7 +12,19 @@ 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.0-ALPHA3 (xxxx-xx-xx) +* 3.0.0 + + * Deprecated FOS\ElasticaBundle\Client in favour of FOS\ElasticaBundle\Elastica\LoggingClient + * Deprecated FOS\ElasticaBundle\DynamicIndex in favour of FOS\ElasticaBundle\Elastica\TransformingIndex + * 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-ALPHA4 (2014-04-10) + + * Indexes are now capable of logging errors with Elastica + * Fixed deferred indexing of deleted documents + +* 3.0.0-ALPHA3 (2014-04-01) * a9c4c93: Logger is now only enabled in debug mode by default * #463: allowing hot swappable reindexing diff --git a/Client.php b/Client.php index 3eb98fe..f85756d 100644 --- a/Client.php +++ b/Client.php @@ -2,43 +2,11 @@ namespace FOS\ElasticaBundle; -use Elastica\Client as ElasticaClient; -use Elastica\Request; -use FOS\ElasticaBundle\Logger\ElasticaLogger; +use FOS\ElasticaBundle\Elastica\LoggingClient; /** - * @author Gordon Franke + * @deprecated Use \FOS\ElasticaBundle\Elastica\LoggingClient */ -class Client extends ElasticaClient +class Client extends LoggingClient { - /** - * {@inheritdoc} - */ - public function request($path, $method = Request::GET, $data = array(), array $query = array()) - { - $start = microtime(true); - $response = parent::request($path, $method, $data, $query); - - if (null !== $this->_logger and $this->_logger instanceof ElasticaLogger) { - $time = microtime(true) - $start; - - $connection = $this->getLastRequest()->getConnection(); - - $connection_array = array( - 'host' => $connection->getHost(), - 'port' => $connection->getPort(), - 'transport' => $connection->getTransport(), - 'headers' => $connection->getConfig('headers'), - ); - - $this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query); - } - - return $response; - } - - public function getIndex($name) - { - return new DynamicIndex($this, $name); - } } diff --git a/DynamicIndex.php b/DynamicIndex.php index cbec8e9..992f650 100644 --- a/DynamicIndex.php +++ b/DynamicIndex.php @@ -2,27 +2,11 @@ namespace FOS\ElasticaBundle; -use Elastica\Index; +use FOS\ElasticaBundle\Elastica\TransformingIndex; /** - * Elastica index capable of reassigning name dynamically - * - * @author Konstantin Tjuterev + * @deprecated Use \FOS\ElasticaBundle\Elastica\TransformingIndex */ -class DynamicIndex extends Index +class DynamicIndex extends TransformingIndex { - /** - * 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 - * - * @return void - */ - public function overrideName($name) - { - $this->_name = $name; - } } diff --git a/Elastica/LoggingClient.php b/Elastica/LoggingClient.php new file mode 100644 index 0000000..0ff1997 --- /dev/null +++ b/Elastica/LoggingClient.php @@ -0,0 +1,47 @@ + + */ +class LoggingClient extends Client +{ + /** + * {@inheritdoc} + */ + public function request($path, $method = Request::GET, $data = array(), array $query = array()) + { + $start = microtime(true); + $response = parent::request($path, $method, $data, $query); + + if (null !== $this->_logger and $this->_logger instanceof ElasticaLogger) { + $time = microtime(true) - $start; + + $connection = $this->getLastRequest()->getConnection(); + + $connection_array = array( + 'host' => $connection->getHost(), + 'port' => $connection->getPort(), + 'transport' => $connection->getTransport(), + 'headers' => $connection->getConfig('headers'), + ); + + $this->_logger->logQuery($path, $method, $data, $time, $connection_array, $query); + } + + return $response; + } + + public function getIndex($name) + { + return new DynamicIndex($this, $name); + } +} diff --git a/Elastica/TransformingIndex.php b/Elastica/TransformingIndex.php new file mode 100644 index 0000000..a0cc001 --- /dev/null +++ b/Elastica/TransformingIndex.php @@ -0,0 +1,45 @@ + + * @author Tim Nagel + */ +class TransformingIndex extends Index +{ + /** + * Indexes a + * @param string $query + * @param int|array $options + * @return \Elastica\Search + */ + public function createSearch($query = '', $options = null) + { + $search = new Search($this->getClient()); + $search->addIndex($this); + $search->setOptionsAndQuery($options, $query); + + return $search; + } + + /** + * 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 + * + * @return void + */ + public function overrideName($name) + { + $this->_name = $name; + } +} diff --git a/Index/IndexManager.php b/Index/IndexManager.php new file mode 100644 index 0000000..543ccae --- /dev/null +++ b/Index/IndexManager.php @@ -0,0 +1,63 @@ +indexesByName = $indexesByName; + $this->defaultIndexName = $defaultIndex->getName(); + } + + /** + * Gets all registered indexes + * + * @return array + */ + public function getAllIndexes() + { + return $this->indexesByName; + } + + /** + * 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) { + $name = $this->defaultIndexName; + } + + if (!isset($this->indexesByName[$name])) { + throw new \InvalidArgumentException(sprintf('The index "%s" does not exist', $name)); + } + + return $this->indexesByName[$name]; + } + + /** + * Gets the default index + * + * @return Index + */ + public function getDefaultIndex() + { + return $this->getIndex($this->defaultIndexName); + } +} diff --git a/Index/Resetter.php b/Index/Resetter.php new file mode 100644 index 0000000..1151ed7 --- /dev/null +++ b/Index/Resetter.php @@ -0,0 +1,246 @@ +indexConfigsByName = $indexConfigsByName; + } + + /** + * Deletes and recreates all indexes + */ + public function resetAllIndexes() + { + foreach (array_keys($this->indexConfigsByName) as $name) { + $this->resetIndex($name); + } + } + + /** + * Deletes and recreates the named index + * + * @param string $indexName + * @throws \InvalidArgumentException if no index exists for the given name + */ + public function resetIndex($indexName) + { + $indexConfig = $this->getIndexConfig($indexName); + $esIndex = $indexConfig['index']; + if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) { + $name = $indexConfig['name_or_alias']; + $name .= uniqid(); + $esIndex->overrideName($name); + $esIndex->create($indexConfig['config']); + + return; + } + + $esIndex->create($indexConfig['config'], true); + } + + /** + * 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) + { + $indexConfig = $this->getIndexConfig($indexName); + + if (!isset($indexConfig['config']['mappings'][$typeName]['properties'])) { + throw new \InvalidArgumentException(sprintf('The mapping for index "%s" and type "%s" does not exist.', $indexName, $typeName)); + } + + $type = $indexConfig['index']->getType($typeName); + try { + $type->delete(); + } catch (ResponseException $e) { + if (strpos($e->getMessage(), 'TypeMissingException') === false) { + throw $e; + } + } + $mapping = $this->createMapping($indexConfig['config']['mappings'][$typeName]); + $type->setMapping($mapping); + } + + /** + * create type mapping object + * + * @param array $indexConfig + * @return Mapping + */ + protected function createMapping($indexConfig) + { + $mapping = Mapping::create($indexConfig['properties']); + + $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_routing', '_index', '_size', '_timestamp', '_ttl', 'dynamic_templates'); + foreach ($mappingSpecialFields as $specialField) { + if (isset($indexConfig[$specialField])) { + $mapping->setParam($specialField, $indexConfig[$specialField]); + } + } + + if (isset($indexConfig['_parent'])) { + $mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type'])); + } + + return $mapping; + } + + /** + * Gets an index config by its name + * + * @param string $indexName Index name + * + * @param $indexName + * @return array + * @throws \InvalidArgumentException if no index config exists for the given name + */ + protected function getIndexConfig($indexName) + { + if (!isset($this->indexConfigsByName[$indexName])) { + throw new \InvalidArgumentException(sprintf('The configuration for index "%s" does not exist.', $indexName)); + } + + return $this->indexConfigsByName[$indexName]; + } + + public function postPopulate($indexName) + { + $indexConfig = $this->getIndexConfig($indexName); + if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) { + $this->switchIndexAlias($indexName); + } + } + + /** + * Switches the alias for given index (by key) to the newly populated index + * and deletes the old index + * + * @param string $indexName Index name + * + * @throws \RuntimeException + */ + private function switchIndexAlias($indexName) + { + $indexConfig = $this->getIndexConfig($indexName); + $esIndex = $indexConfig['index']; + $aliasName = $indexConfig['name_or_alias']; + $oldIndexName = false; + $newIndexName = $esIndex->getName(); + + $aliasedIndexes = $this->getAliasedIndexes($esIndex, $aliasName); + + 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, + join(', ', $aliasedIndexes) + ) + ); + } + + // Change the alias to point to the new index + // Elastica's addAlias can't be used directly, because in current (0.19.x) version it's not atomic + // In 0.20.x it's atomic, but it doesn't return the old index name + $aliasUpdateRequest = array('actions' => array()); + if (count($aliasedIndexes) == 1) { + // if the alias is set - add an action to remove it + $oldIndexName = $aliasedIndexes[0]; + $aliasUpdateRequest['actions'][] = array( + 'remove' => array('index' => $oldIndexName, 'alias' => $aliasName) + ); + } + + // add an action to point the alias to the new index + $aliasUpdateRequest['actions'][] = array( + 'add' => array('index' => $newIndexName, 'alias' => $aliasName) + ); + + try { + $esIndex->getClient()->request('_aliases', 'POST', $aliasUpdateRequest); + } catch (ExceptionInterface $renameAliasException) { + $additionalError = ''; + // if we failed to move the alias, delete the newly built index + try { + $esIndex->delete(); + } catch (ExceptionInterface $deleteNewIndexException) { + $additionalError = sprintf( + 'Tried to delete newly built index %s, but also failed: %s', + $newIndexName, + $deleteNewIndexException->getError() + ); + } + + throw new \RuntimeException( + sprintf( + 'Failed to updated index alias: %s. %s', + $renameAliasException->getMessage(), + $additionalError ?: sprintf('Newly built index %s was deleted', $newIndexName) + ) + ); + } + + // Delete the old index after the alias has been switched + if ($oldIndexName) { + $oldIndex = new Index($esIndex->getClient(), $oldIndexName); + try { + $oldIndex->delete(); + } catch (ExceptionInterface $deleteOldIndexException) { + throw new \RuntimeException( + sprintf( + 'Failed to delete old index %s with message: %s', + $oldIndexName, + $deleteOldIndexException->getMessage() + ) + ); + } + } + } + + /** + * Returns array of indexes which are mapped to given alias + * + * @param Index $esIndex ES Index + * @param string $aliasName Alias name + * + * @return array + */ + private function getAliasedIndexes(Index $esIndex, $aliasName) + { + $aliasesInfo = $esIndex->getClient()->request('_aliases', 'GET')->getData(); + $aliasedIndexes = array(); + + foreach ($aliasesInfo as $indexName => $indexInfo) { + $aliases = array_keys($indexInfo['aliases']); + if (in_array($aliasName, $aliases)) { + $aliasedIndexes[] = $indexName; + } + } + + return $aliasedIndexes; + } +} diff --git a/IndexManager.php b/IndexManager.php index e20a791..e7c74c8 100644 --- a/IndexManager.php +++ b/IndexManager.php @@ -2,62 +2,11 @@ namespace FOS\ElasticaBundle; -use Elastica\Index; +use FOS\ElasticaBundle\Index\IndexManager as BaseIndexManager; -class IndexManager +/** + * @deprecated Use \FOS\ElasticaBundle\Index\IndexManager + */ +class IndexManager extends BaseIndexManager { - protected $indexesByName; - protected $defaultIndexName; - - /** - * Constructor. - * - * @param array $indexesByName - * @param Index $defaultIndex - */ - public function __construct(array $indexesByName, Index $defaultIndex) - { - $this->indexesByName = $indexesByName; - $this->defaultIndexName = $defaultIndex->getName(); - } - - /** - * Gets all registered indexes - * - * @return array - */ - public function getAllIndexes() - { - return $this->indexesByName; - } - - /** - * 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) { - $name = $this->defaultIndexName; - } - - if (!isset($this->indexesByName[$name])) { - throw new \InvalidArgumentException(sprintf('The index "%s" does not exist', $name)); - } - - return $this->indexesByName[$name]; - } - - /** - * Gets the default index - * - * @return Index - */ - public function getDefaultIndex() - { - return $this->getIndex($this->defaultIndexName); - } } diff --git a/Resetter.php b/Resetter.php index fe963d0..dd24451 100644 --- a/Resetter.php +++ b/Resetter.php @@ -2,245 +2,11 @@ namespace FOS\ElasticaBundle; -use Elastica\Exception\ExceptionInterface; -use Elastica\Index; -use Elastica\Exception\ResponseException; -use Elastica\Type\Mapping; +use FOS\ElasticaBundle\Index\Resetter as BaseResetter; /** * Deletes and recreates indexes */ -class Resetter +class Resetter extends BaseResetter { - protected $indexConfigsByName; - - /** - * Constructor. - * - * @param array $indexConfigsByName - */ - public function __construct(array $indexConfigsByName) - { - $this->indexConfigsByName = $indexConfigsByName; - } - - /** - * Deletes and recreates all indexes - */ - public function resetAllIndexes() - { - foreach (array_keys($this->indexConfigsByName) as $name) { - $this->resetIndex($name); - } - } - - /** - * Deletes and recreates the named index - * - * @param string $indexName - * @throws \InvalidArgumentException if no index exists for the given name - */ - public function resetIndex($indexName) - { - $indexConfig = $this->getIndexConfig($indexName); - $esIndex = $indexConfig['index']; - if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) { - $name = $indexConfig['name_or_alias']; - $name .= uniqid(); - $esIndex->overrideName($name); - $esIndex->create($indexConfig['config']); - - return; - } - - $esIndex->create($indexConfig['config'], true); - } - - /** - * 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) - { - $indexConfig = $this->getIndexConfig($indexName); - - if (!isset($indexConfig['config']['mappings'][$typeName]['properties'])) { - throw new \InvalidArgumentException(sprintf('The mapping for index "%s" and type "%s" does not exist.', $indexName, $typeName)); - } - - $type = $indexConfig['index']->getType($typeName); - try { - $type->delete(); - } catch (ResponseException $e) { - if (strpos($e->getMessage(), 'TypeMissingException') === false) { - throw $e; - } - } - $mapping = $this->createMapping($indexConfig['config']['mappings'][$typeName]); - $type->setMapping($mapping); - } - - /** - * create type mapping object - * - * @param array $indexConfig - * @return Mapping - */ - protected function createMapping($indexConfig) - { - $mapping = Mapping::create($indexConfig['properties']); - - $mappingSpecialFields = array('_uid', '_id', '_source', '_all', '_analyzer', '_boost', '_routing', '_index', '_size', '_timestamp', '_ttl', 'dynamic_templates'); - foreach ($mappingSpecialFields as $specialField) { - if (isset($indexConfig[$specialField])) { - $mapping->setParam($specialField, $indexConfig[$specialField]); - } - } - - if (isset($indexConfig['_parent'])) { - $mapping->setParam('_parent', array('type' => $indexConfig['_parent']['type'])); - } - - return $mapping; - } - - /** - * Gets an index config by its name - * - * @param string $indexName Index name - * - * @param $indexName - * @return array - * @throws \InvalidArgumentException if no index config exists for the given name - */ - protected function getIndexConfig($indexName) - { - if (!isset($this->indexConfigsByName[$indexName])) { - throw new \InvalidArgumentException(sprintf('The configuration for index "%s" does not exist.', $indexName)); - } - - return $this->indexConfigsByName[$indexName]; - } - - public function postPopulate($indexName) - { - $indexConfig = $this->getIndexConfig($indexName); - if (isset($indexConfig['use_alias']) && $indexConfig['use_alias']) { - $this->switchIndexAlias($indexName); - } - } - - /** - * Switches the alias for given index (by key) to the newly populated index - * and deletes the old index - * - * @param string $indexName Index name - * - * @throws \RuntimeException - */ - private function switchIndexAlias($indexName) - { - $indexConfig = $this->getIndexConfig($indexName); - $esIndex = $indexConfig['index']; - $aliasName = $indexConfig['name_or_alias']; - $oldIndexName = false; - $newIndexName = $esIndex->getName(); - - $aliasedIndexes = $this->getAliasedIndexes($esIndex, $aliasName); - - 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, - join(', ', $aliasedIndexes) - ) - ); - } - - // Change the alias to point to the new index - // Elastica's addAlias can't be used directly, because in current (0.19.x) version it's not atomic - // In 0.20.x it's atomic, but it doesn't return the old index name - $aliasUpdateRequest = array('actions' => array()); - if (count($aliasedIndexes) == 1) { - // if the alias is set - add an action to remove it - $oldIndexName = $aliasedIndexes[0]; - $aliasUpdateRequest['actions'][] = array( - 'remove' => array('index' => $oldIndexName, 'alias' => $aliasName) - ); - } - - // add an action to point the alias to the new index - $aliasUpdateRequest['actions'][] = array( - 'add' => array('index' => $newIndexName, 'alias' => $aliasName) - ); - - try { - $esIndex->getClient()->request('_aliases', 'POST', $aliasUpdateRequest); - } catch (ExceptionInterface $renameAliasException) { - $additionalError = ''; - // if we failed to move the alias, delete the newly built index - try { - $esIndex->delete(); - } catch (ExceptionInterface $deleteNewIndexException) { - $additionalError = sprintf( - 'Tried to delete newly built index %s, but also failed: %s', - $newIndexName, - $deleteNewIndexException->getError() - ); - } - - throw new \RuntimeException( - sprintf( - 'Failed to updated index alias: %s. %s', - $renameAliasException->getMessage(), - $additionalError ?: sprintf('Newly built index %s was deleted', $newIndexName) - ) - ); - } - - // Delete the old index after the alias has been switched - if ($oldIndexName) { - $oldIndex = new Index($esIndex->getClient(), $oldIndexName); - try { - $oldIndex->delete(); - } catch (ExceptionInterface $deleteOldIndexException) { - throw new \RuntimeException( - sprintf( - 'Failed to delete old index %s with message: %s', - $oldIndexName, - $deleteOldIndexException->getMessage() - ) - ); - } - } - } - - /** - * Returns array of indexes which are mapped to given alias - * - * @param Index $esIndex ES Index - * @param string $aliasName Alias name - * - * @return array - */ - private function getAliasedIndexes(Index $esIndex, $aliasName) - { - $aliasesInfo = $esIndex->getClient()->request('_aliases', 'GET')->getData(); - $aliasedIndexes = array(); - - foreach ($aliasesInfo as $indexName => $indexInfo) { - $aliases = array_keys($indexInfo['aliases']); - if (in_array($aliasName, $aliases)) { - $aliasedIndexes[] = $indexName; - } - } - - return $aliasedIndexes; - } } diff --git a/Resources/config/config.xml b/Resources/config/config.xml index c10568d..fbf6d1c 100644 --- a/Resources/config/config.xml +++ b/Resources/config/config.xml @@ -5,8 +5,8 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - FOS\ElasticaBundle\Client - FOS\ElasticaBundle\DynamicIndex + FOS\ElasticaBundle\Elastica\LoggingClient + FOS\ElasticaBundle\Elastica\TransformingIndex Elastica\Type FOS\ElasticaBundle\IndexManager FOS\ElasticaBundle\Resetter diff --git a/Tests/ClientTest.php b/Tests/Elastica/LoggingClientTest.php similarity index 86% rename from Tests/ClientTest.php rename to Tests/Elastica/LoggingClientTest.php index 8a9d91a..b08a2cf 100644 --- a/Tests/ClientTest.php +++ b/Tests/Elastica/LoggingClientTest.php @@ -1,11 +1,11 @@ isType('array') ); - $client = $this->getMockBuilder('FOS\ElasticaBundle\Client') + $client = $this->getMockBuilder('FOS\ElasticaBundle\Elastica\LoggingClient') ->setMethods(array('getConnection')) ->getMock(); diff --git a/Tests/IndexManagerTest.php b/Tests/Index/IndexManagerTest.php similarity index 95% rename from Tests/IndexManagerTest.php rename to Tests/Index/IndexManagerTest.php index 0a8ea37..624f64e 100644 --- a/Tests/IndexManagerTest.php +++ b/Tests/Index/IndexManagerTest.php @@ -1,8 +1,8 @@ Date: Fri, 25 Apr 2014 21:31:04 +1000 Subject: [PATCH 2/3] New Api --- Doctrine/AbstractLookup.php | 22 ++++++ Doctrine/MongoDB/Lookup.php | 49 ++++++++++++ Doctrine/ORM/Lookup.php | 58 ++++++++++++++ Elastica/LoggingClient.php | 38 +++++++-- Elastica/TransformingIndex.php | 29 +++++-- Elastica/TransformingResult.php | 51 ++++++++++++ Elastica/TransformingResultSet.php | 82 ++++++++++++++++++++ Elastica/TransformingSearch.php | 73 +++++++++++++++++ Elastica/TransformingType.php | 25 ++++++ Exception/MissingModelException.php | 15 ++++ Exception/UnexpectedObjectException.php | 13 ++++ Propel/Lookup.php | 54 +++++++++++++ Tests/Elastica/LoggingClientTest.php | 25 ++++++ Tests/Elastica/TransformingIndexTest.php | 42 ++++++++++ Tests/Elastica/TransformingResultSetTest.php | 42 ++++++++++ Tests/Elastica/TransformingResultTest.php | 22 ++++++ Transformer/CombinedResultTransformer.php | 71 +++++++++++++++++ Transformer/ResultTransformer.php | 80 +++++++++++++++++++ Transformer/ResultTransformerInterface.php | 16 ++++ Type/LookupInterface.php | 27 +++++++ Type/LookupManager.php | 36 +++++++++ Type/TypeConfigurationInterface.php | 54 +++++++++++++ composer.json | 1 + 23 files changed, 912 insertions(+), 13 deletions(-) create mode 100644 Doctrine/AbstractLookup.php create mode 100644 Doctrine/MongoDB/Lookup.php create mode 100644 Doctrine/ORM/Lookup.php create mode 100644 Elastica/TransformingResult.php create mode 100644 Elastica/TransformingResultSet.php create mode 100644 Elastica/TransformingSearch.php create mode 100644 Elastica/TransformingType.php create mode 100644 Exception/MissingModelException.php create mode 100644 Exception/UnexpectedObjectException.php create mode 100644 Propel/Lookup.php create mode 100644 Tests/Elastica/TransformingIndexTest.php create mode 100644 Tests/Elastica/TransformingResultSetTest.php create mode 100644 Tests/Elastica/TransformingResultTest.php create mode 100644 Transformer/CombinedResultTransformer.php create mode 100644 Transformer/ResultTransformer.php create mode 100644 Transformer/ResultTransformerInterface.php create mode 100644 Type/LookupInterface.php create mode 100644 Type/LookupManager.php create mode 100644 Type/TypeConfigurationInterface.php diff --git a/Doctrine/AbstractLookup.php b/Doctrine/AbstractLookup.php new file mode 100644 index 0000000..6560bab --- /dev/null +++ b/Doctrine/AbstractLookup.php @@ -0,0 +1,22 @@ +registry = $registry; + } +} diff --git a/Doctrine/MongoDB/Lookup.php b/Doctrine/MongoDB/Lookup.php new file mode 100644 index 0000000..6c48759 --- /dev/null +++ b/Doctrine/MongoDB/Lookup.php @@ -0,0 +1,49 @@ +createQueryBuilder($configuration); + $qb->hydrate($configuration->isHydrate()); + + $qb->field($configuration->getIdentifierProperty()) + ->in($ids); + + return $qb->getQuery()->execute()->toArray(); + } + + /** + * @param TypeConfigurationInterface $configuration + * @return \Doctrine\ODM\MongoDB\Query\Builder + */ + private function createQueryBuilder(TypeConfigurationInterface $configuration) + { + $method = $configuration->getRepositoryMethod(); + $manager = $this->registry->getManagerForClass($configuration->getModelClass()); + + return $manager->{$method}($configuration->getModelClass()); + } +} diff --git a/Doctrine/ORM/Lookup.php b/Doctrine/ORM/Lookup.php new file mode 100644 index 0000000..2e2cfe3 --- /dev/null +++ b/Doctrine/ORM/Lookup.php @@ -0,0 +1,58 @@ +isHydrate() ? + Query::HYDRATE_OBJECT : + Query::HYDRATE_ARRAY; + + $qb = $this->createQueryBuilder($configuration); + + $qb->andWhere($qb->expr()->in( + sprintf('%s.%s', static::ENTITY_ALIAS, $configuration->getIdentifierProperty()), + ':identifiers' + )); + $qb->setParameter('identifiers', $ids); + + return $qb->getQuery()->execute(array(), $hydrationMode); + } + + /** + * @param TypeConfigurationInterface $configuration + * @return \Doctrine\ORM\QueryBuilder + */ + private function createQueryBuilder(TypeConfigurationInterface $configuration) + { + $repository = $this->registry->getRepository($configuration->getModelClass()); + $method = $configuration->getRepositoryMethod(); + + return $repository->{$method}(static::ENTITY_ALIAS); + } +} diff --git a/Elastica/LoggingClient.php b/Elastica/LoggingClient.php index 0ff1997..faecdfc 100644 --- a/Elastica/LoggingClient.php +++ b/Elastica/LoggingClient.php @@ -5,6 +5,7 @@ namespace FOS\ElasticaBundle\Elastica; use Elastica\Client as Client; use Elastica\Request; use FOS\ElasticaBundle\Logger\ElasticaLogger; +use FOS\ElasticaBundle\Transformer\CombinedResultTransformer; /** * Extends the default Elastica client to provide logging for errors that occur @@ -14,6 +15,38 @@ use FOS\ElasticaBundle\Logger\ElasticaLogger; */ class LoggingClient extends Client { + /** + * @var CombinedResultTransformer + */ + private $resultTransformer; + + public function __construct(array $config = array(), $callback = null, CombinedResultTransformer $resultTransformer) + { + parent::__construct($config, $callback); + + $this->resultTransformer = $resultTransformer; + } + + /** + * Overridden Elastica method to return TransformingIndex instances instead of the + * default Index instances. + * + * @param string $name + * @return TransformingIndex + */ + public function getIndex($name) + { + return new TransformingIndex($this, $name, $this->resultTransformer); + } + + /** + * @return CombinedResultTransformer + */ + public function getResultTransformer() + { + return $this->resultTransformer; + } + /** * {@inheritdoc} */ @@ -39,9 +72,4 @@ class LoggingClient extends Client return $response; } - - public function getIndex($name) - { - return new DynamicIndex($this, $name); - } } diff --git a/Elastica/TransformingIndex.php b/Elastica/TransformingIndex.php index a0cc001..2bab636 100644 --- a/Elastica/TransformingIndex.php +++ b/Elastica/TransformingIndex.php @@ -1,8 +1,11 @@ getClient()); + $search = new TransformingSearch($this->getClient()); $search->addIndex($this); $search->setOptionsAndQuery($options, $query); return $search; } + /** + * Returns a type object for the current index with the given name + * + * @param string $type Type name + * @return TransformingType Type object + */ + public function getType($type) + { + return new TransformingType($this, $type); + } + /** * Reassign index name * @@ -35,8 +50,6 @@ class TransformingIndex extends Index * since it's used for a very specific case and normally should not be used * * @param string $name Index name - * - * @return void */ public function overrideName($name) { diff --git a/Elastica/TransformingResult.php b/Elastica/TransformingResult.php new file mode 100644 index 0000000..08d09bc --- /dev/null +++ b/Elastica/TransformingResult.php @@ -0,0 +1,51 @@ +resultSet = $resultSet; + } + + /** + * Returns the transformed result of the hit. + * + * @return mixed + */ + public function getTransformed() + { + if (null === $this->transformed) { + $this->resultSet->transform(); + } + + return $this->transformed; + } + + /** + * An internal method used to set the transformed result on the Result. + * + * @internal + */ + public function setTransformed($transformed) + { + $this->transformed = $transformed; + } +} diff --git a/Elastica/TransformingResultSet.php b/Elastica/TransformingResultSet.php new file mode 100644 index 0000000..c775cd3 --- /dev/null +++ b/Elastica/TransformingResultSet.php @@ -0,0 +1,82 @@ +resultTransformer = $resultTransformer; + } + + /** + * Overridden default method to set our TransformingResult objects. + * + * @param \Elastica\Response $response Response object + */ + protected function _init(Response $response) + { + $this->_response = $response; + $result = $response->getData(); + $this->_totalHits = isset($result['hits']['total']) ? $result['hits']['total'] : 0; + $this->_maxScore = isset($result['hits']['max_score']) ? $result['hits']['max_score'] : 0; + $this->_took = isset($result['took']) ? $result['took'] : 0; + $this->_timedOut = !empty($result['timed_out']); + if (isset($result['hits']['hits'])) { + foreach ($result['hits']['hits'] as $hit) { + $this->_results[] = new TransformingResult($hit, $this); + } + } + } + + /** + * Returns an array of transformed results. + * + * @return object[] + */ + public function getTransformed() + { + $this->transform(); + + return array_map(function (TransformingResult $result) { + return $result->getTransformed(); + }, $this->getResults()); + } + + /** + * Triggers the transformation of all Results. + */ + public function transform() + { + if ($this->transformed) { + return; + } + + if (!$this->count()) { + return; + } + + $this->resultTransformer->transform($this->getResults()); + $this->transformed = true; + } +} diff --git a/Elastica/TransformingSearch.php b/Elastica/TransformingSearch.php new file mode 100644 index 0000000..eee1a96 --- /dev/null +++ b/Elastica/TransformingSearch.php @@ -0,0 +1,73 @@ +value) + * @throws \Elastica\Exception\InvalidException + * @return TransformingResultSet + */ + public function search($query = '', $options = null) + { + $this->setOptionsAndQuery($options, $query); + + $query = $this->getQuery(); + $path = $this->getPath(); + + $params = $this->getOptions(); + + // Send scroll_id via raw HTTP body to handle cases of very large (> 4kb) ids. + if ('_search/scroll' == $path) { + $data = $params[self::OPTION_SCROLL_ID]; + unset($params[self::OPTION_SCROLL_ID]); + } else { + $data = $query->toArray(); + } + + $response = $this->getClient()->request( + $path, + Request::GET, + $data, + $params + ); + + return new TransformingResultSet($response, $query, $this->_client->getResultTransformer()); + } + + /** + * + * @param mixed $query + * @param $fullResult (default = false) By default only the total hit count is returned. If set to true, the full ResultSet including facets is returned. + * @return int|TransformingResultSet + */ + public function count($query = '', $fullResult = false) + { + $this->setOptionsAndQuery(null, $query); + + $query = $this->getQuery(); + $path = $this->getPath(); + + $response = $this->getClient()->request( + $path, + Request::GET, + $query->toArray(), + array(self::OPTION_SEARCH_TYPE => self::OPTION_SEARCH_TYPE_COUNT) + ); + $resultSet = new TransformingResultSet($response, $query, $this->_client->getResultTransformer()); + + return $fullResult ? $resultSet : $resultSet->getTotalHits(); + } +} diff --git a/Elastica/TransformingType.php b/Elastica/TransformingType.php new file mode 100644 index 0000000..f359c24 --- /dev/null +++ b/Elastica/TransformingType.php @@ -0,0 +1,25 @@ +getId() . '/_mlt'; + $query = Query::create($query); + $response = $this->request($path, Request::GET, $query->toArray(), $params); + + return new TransformingResultSet($response, $query, $this->_index->getClient()->getResultTransformer()); + } +} diff --git a/Exception/MissingModelException.php b/Exception/MissingModelException.php new file mode 100644 index 0000000..cfbb750 --- /dev/null +++ b/Exception/MissingModelException.php @@ -0,0 +1,15 @@ +createQuery($configuration, $ids); + + if (!$configuration->isHydrate()) { + return $query->toArray(); + } + + return $query->find(); + } + + /** + * Create a query to use in the findByIdentifiers() method. + * + * @param TypeConfigurationInterface $configuration + * @param array $ids + * @return \ModelCriteria + */ + protected function createQuery(TypeConfigurationInterface $configuration, array $ids) + { + $queryClass = $configuration->getModelClass() . 'Query'; + $query = $queryClass::create(); + $filterMethod = 'filterBy' . Inflector::camelize($configuration->getIdentifierProperty()); + + return $query->$filterMethod($ids); + } +} diff --git a/Tests/Elastica/LoggingClientTest.php b/Tests/Elastica/LoggingClientTest.php index b08a2cf..0b3e71d 100644 --- a/Tests/Elastica/LoggingClientTest.php +++ b/Tests/Elastica/LoggingClientTest.php @@ -4,9 +4,33 @@ namespace FOS\ElasticaBundle\Tests\Client; use Elastica\Request; use Elastica\Transport\Null as NullTransport; +use FOS\ElasticaBundle\Elastica\LoggingClient; class LoggingClientTest extends \PHPUnit_Framework_TestCase { + public function testOverriddenElasticaMethods() + { + $resultTransformer = $this->getMockBuilder('FOS\ElasticaBundle\Transformer\CombinedResultTransformer') + ->disableOriginalConstructor() + ->getMock(); + $client = new LoggingClient(array(), null, $resultTransformer); + $index = $client->getIndex('index'); + $type = $index->getType('type'); + + $this->assertInstanceOf('FOS\ElasticaBundle\Elastica\TransformingIndex', $index); + $this->assertInstanceOf('FOS\ElasticaBundle\Elastica\TransformingType', $type); + } + + public function testGetResultTransformer() + { + $resultTransformer = $this->getMockBuilder('FOS\ElasticaBundle\Transformer\CombinedResultTransformer') + ->disableOriginalConstructor() + ->getMock(); + $client = new LoggingClient(array(), null, $resultTransformer); + + $this->assertSame($resultTransformer, $client->getResultTransformer()); + } + public function testRequestsAreLogged() { $transport = new NullTransport; @@ -29,6 +53,7 @@ class LoggingClientTest extends \PHPUnit_Framework_TestCase ); $client = $this->getMockBuilder('FOS\ElasticaBundle\Elastica\LoggingClient') + ->disableOriginalConstructor() ->setMethods(array('getConnection')) ->getMock(); diff --git a/Tests/Elastica/TransformingIndexTest.php b/Tests/Elastica/TransformingIndexTest.php new file mode 100644 index 0000000..e652119 --- /dev/null +++ b/Tests/Elastica/TransformingIndexTest.php @@ -0,0 +1,42 @@ +index->createSearch(); + + $this->assertInstanceOf('FOS\ElasticaBundle\Elastica\TransformingSearch', $search); + } + + public function testOverrideName() + { + $this->assertEquals('testindex', $this->index->getName()); + + $this->index->overrideName('newindex'); + + $this->assertEquals('newindex', $this->index->getName()); + } + + protected function setUp() + { + $this->client = $this->getMockBuilder('FOS\ElasticaBundle\Elastica\LoggingClient') + ->disableOriginalConstructor() + ->getMock(); + $this->index = new TransformingIndex($this->client, 'testindex'); + } +} diff --git a/Tests/Elastica/TransformingResultSetTest.php b/Tests/Elastica/TransformingResultSetTest.php new file mode 100644 index 0000000..9b9b38a --- /dev/null +++ b/Tests/Elastica/TransformingResultSetTest.php @@ -0,0 +1,42 @@ + array( + 'hits' => array( + array(), + array(), + array(), + ) + ))); + $query = new Query(); + $transformer = $this->getMockBuilder('FOS\ElasticaBundle\Transformer\CombinedResultTransformer') + ->disableOriginalConstructor() + ->getMock(); + + $resultSet = new TransformingResultSet($response, $query, $transformer); + + $this->assertCount(3, $resultSet); + $this->assertInstanceOf('FOS\ElasticaBundle\Elastica\TransformingResult', $resultSet[0]); + + $transformer->expects($this->once()) + ->method('transform') + ->with($resultSet->getResults()); + + $resultSet->transform(); + $resultSet->transform(); + + $this->assertSame(array( + 0 => null, 1 => null, 2 => null + ), $resultSet->getTransformed()); + } +} diff --git a/Tests/Elastica/TransformingResultTest.php b/Tests/Elastica/TransformingResultTest.php new file mode 100644 index 0000000..286b7d1 --- /dev/null +++ b/Tests/Elastica/TransformingResultTest.php @@ -0,0 +1,22 @@ +getMockBuilder('FOS\ElasticaBundle\Elastica\TransformingResultSet') + ->disableOriginalConstructor() + ->getMock(); + $result = new TransformingResult(array(), $resultSet); + + $resultSet->expects($this->exactly(2)) + ->method('transform'); + + $result->getTransformed(); + $result->getTransformed(); + } +} diff --git a/Transformer/CombinedResultTransformer.php b/Transformer/CombinedResultTransformer.php new file mode 100644 index 0000000..791e601 --- /dev/null +++ b/Transformer/CombinedResultTransformer.php @@ -0,0 +1,71 @@ + + */ +class CombinedResultTransformer +{ + /** + * @var \FOS\ElasticaBundle\Type\TypeConfigurationInterface + */ + private $configurations; + + /** + * @var ResultTransformerInterface + */ + private $transformer; + + /** + * @param \FOS\ElasticaBundle\Type\TypeConfigurationInterface[] $configurations + * @param ResultTransformerInterface $transformer + */ + public function __construct(array $configurations, ResultTransformerInterface $transformer) + { + $this->configurations = $configurations; + $this->transformer = $transformer; + } + + /** + * Transforms Elastica results into Models. + * + * @param TransformingResult[] $results + * @return object[] + */ + public function transform($results) + { + $grouped = array(); + + foreach ($results as $result) { + $grouped[$result->getType()][] = $result; + } + + foreach ($grouped as $type => $group) { + $this->transformer->transform($this->getConfiguration($type), $group); + } + } + + /** + * Retrieves the transformer for a given type. + * + * @param string $type + * @return \FOS\ElasticaBundle\Type\TypeConfigurationInterface + * @throws \InvalidArgumentException + */ + private function getConfiguration($type) + { + if (!array_key_exists($type, $this->configurations)) { + throw new \InvalidArgumentException(sprintf( + 'Configuration for type "%s" is not registered with this combined transformer.', + $type + )); + } + + return $this->configurations[$type]; + } +} diff --git a/Transformer/ResultTransformer.php b/Transformer/ResultTransformer.php new file mode 100644 index 0000000..68b9364 --- /dev/null +++ b/Transformer/ResultTransformer.php @@ -0,0 +1,80 @@ +lookupManager = $lookupManager; + $this->propertyAccessor = $propertyAccessor; + } + + /** + * Transforms Elastica results into Models. + * + * @param TypeConfigurationInterface $configuration + * @param \FOS\ElasticaBundle\Elastica\TransformingResult[] $results + * @throws \FOS\ElasticaBundle\Exception\MissingModelException + * @throws \FOS\ElasticaBundle\Exception\UnexpectedObjectException + */ + public function transform(TypeConfigurationInterface $configuration, $results) + { + $results = $this->processResults($results); + $lookup = $this->lookupManager->getLookup($configuration->getType()); + $objects = $lookup->lookup($configuration, array_keys($results)); + + if (!$configuration->isIgnoreMissing() and count($objects) < count($results)) { + throw new MissingModelException(count($objects), count($results)); + } + + $identifierProperty = $configuration->getIdentifierProperty(); + foreach ($objects as $object) { + $id = $this->propertyAccessor->getValue($object, $identifierProperty); + + if (!array_key_exists($id, $results)) { + throw new UnexpectedObjectException($id); + } + + $results[$id]->setTransformed($object); + } + } + + /** + * Processes the results array into a more usable format for the transformation. + * + * @param \FOS\ElasticaBundle\Elastica\TransformingResult[] $results + * @return \FOS\ElasticaBundle\Elastica\TransformingResult[] + */ + private function processResults($results) + { + $sorted = array(); + foreach ($results as $result) { + $sorted[$result->getId()] = $result; + } + + return $sorted; + } +} diff --git a/Transformer/ResultTransformerInterface.php b/Transformer/ResultTransformerInterface.php new file mode 100644 index 0000000..c18fc7c --- /dev/null +++ b/Transformer/ResultTransformerInterface.php @@ -0,0 +1,16 @@ + + */ +interface LookupInterface +{ + /** + * Returns the lookup key. + * + * @return string + */ + public function getKey(); + + /** + * Look up objects of a specific type with ids as supplied. + * + * @param TypeConfigurationInterface $configuration + * @param int[] $ids + * @return object[] + */ + public function lookup(TypeConfigurationInterface $configuration, array $ids); +} diff --git a/Type/LookupManager.php b/Type/LookupManager.php new file mode 100644 index 0000000..0db0fd1 --- /dev/null +++ b/Type/LookupManager.php @@ -0,0 +1,36 @@ +lookups[$lookup->getKey()] = $lookup; + } + } + + + /** + * @param string $type + * @return LookupInterface + * @throws \InvalidArgumentException + */ + public function getLookup($type) + { + if (!array_key_exists($type, $this->lookups)) { + throw new \InvalidArgumentException(sprintf('Lookup with key "%s" does not exist', $type)); + } + + return $this->lookups[$type]; + } +} diff --git a/Type/TypeConfigurationInterface.php b/Type/TypeConfigurationInterface.php new file mode 100644 index 0000000..bee3388 --- /dev/null +++ b/Type/TypeConfigurationInterface.php @@ -0,0 +1,54 @@ + + */ +interface TypeConfigurationInterface +{ + /** + * The identifier property that is used to retrieve an identifier from the model. + * + * @return string + */ + public function getIdentifierProperty(); + + /** + * Returns the fully qualified class for the model that this type represents. + * + * @return string + */ + public function getModelClass(); + + /** + * Returns the repository method that will create a query builder or associated + * query object for lookup purposes. + * + * @return string + */ + public function getRepositoryMethod(); + + /** + * Returns the name of the type. + * + * @return string + */ + public function getType(); + + /** + * If the lookup should hydrate models to objects or leave data as an array. + * + * @return bool + */ + public function isHydrate(); + + /** + * If the type should ignore missing results from a lookup. + * + * @return bool + */ + public function isIgnoreMissing(); +} \ No newline at end of file diff --git a/composer.json b/composer.json index 8dd19b6..e827ac6 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ ], "require": { "php": ">=5.3.2", + "doctrine/inflector": "~1.0", "symfony/framework-bundle": "~2.3", "symfony/console": "~2.1", "symfony/form": "~2.1", From 7d06cc429b16849d831372280c1307ec6311c155 Mon Sep 17 00:00:00 2001 From: Tim Nagel Date: Thu, 15 May 2014 22:55:35 +1000 Subject: [PATCH 3/3] dev --- DependencyInjection/Compiler/LookupPass.php | 33 +++++ DependencyInjection/FOSElasticaExtension.php | 118 +++++++++------- Doctrine/MongoDB/Lookup.php | 10 +- Doctrine/ORM/Lookup.php | 10 +- Exception/UnexpectedObjectException.php | 2 +- Finder/PaginatedFinderInterface.php | 28 ---- Finder/TransformedFinder.php | 29 +--- Index/IndexManager.php | 23 +-- Paginator/FantaPaginatorAdapter.php | 57 -------- Paginator/PaginatorAdapterInterface.php | 34 ----- Paginator/PartialResultsInterface.php | 31 ----- Paginator/RawPaginatorAdapter.php | 139 ------------------- Paginator/RawPartialResults.php | 52 ------- Paginator/TransformedPaginatorAdapter.php | 36 ----- Paginator/TransformedPartialResults.php | 33 ----- Propel/Lookup.php | 10 +- Resources/config/config.xml | 79 +---------- Resources/config/index.xml | 35 +++++ Resources/config/orm.xml | 4 +- Resources/config/persister.xml | 27 ++++ Resources/config/provider.xml | 18 +++ Resources/config/transformer.xml | 32 +++++ Transformer/CombinedResultTransformer.php | 6 +- Transformer/ResultTransformer.php | 7 +- Transformer/ResultTransformerInterface.php | 6 +- Type/LookupInterface.php | 4 +- Type/LookupManager.php | 1 - Type/TypeConfiguration.php | 102 ++++++++++++++ Type/TypeConfigurationInterface.php | 54 ------- 29 files changed, 364 insertions(+), 656 deletions(-) create mode 100644 DependencyInjection/Compiler/LookupPass.php delete mode 100644 Finder/PaginatedFinderInterface.php delete mode 100644 Paginator/FantaPaginatorAdapter.php delete mode 100644 Paginator/PaginatorAdapterInterface.php delete mode 100644 Paginator/PartialResultsInterface.php delete mode 100644 Paginator/RawPaginatorAdapter.php delete mode 100644 Paginator/RawPartialResults.php delete mode 100644 Paginator/TransformedPaginatorAdapter.php delete mode 100644 Paginator/TransformedPartialResults.php create mode 100644 Resources/config/index.xml create mode 100644 Resources/config/persister.xml create mode 100644 Resources/config/provider.xml create mode 100644 Resources/config/transformer.xml create mode 100644 Type/TypeConfiguration.php delete mode 100644 Type/TypeConfigurationInterface.php diff --git a/DependencyInjection/Compiler/LookupPass.php b/DependencyInjection/Compiler/LookupPass.php new file mode 100644 index 0000000..e82a56f --- /dev/null +++ b/DependencyInjection/Compiler/LookupPass.php @@ -0,0 +1,33 @@ + + */ +class LookupPass implements CompilerPassInterface +{ + /** + * {@inheritDoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('fos_elastica.lookup_manager')) { + return; + } + + $lookups = array(); + foreach ($container->findTaggedServiceIds('fos_elastica.lookup') as $id => $tags) { + $lookups[] = new Reference($id); + } + + $managerDefinition = $container->getDefinition('fos_elastica.lookup_manager'); + $managerDefinition->setArguments(0, $lookups); + } +} diff --git a/DependencyInjection/FOSElasticaExtension.php b/DependencyInjection/FOSElasticaExtension.php index 51cb94f..6bf1880 100644 --- a/DependencyInjection/FOSElasticaExtension.php +++ b/DependencyInjection/FOSElasticaExtension.php @@ -4,7 +4,6 @@ namespace FOS\ElasticaBundle\DependencyInjection; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; -use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\DefinitionDecorator; @@ -14,6 +13,13 @@ use InvalidArgumentException; class FOSElasticaExtension extends Extension { + /** + * Stores references to all defined clients loaded by the extension. + * + * @var array + */ + private $clients = array(); + protected $indexConfigs = array(); protected $typeFields = array(); protected $loadedDrivers = array(); @@ -21,9 +27,7 @@ class FOSElasticaExtension extends Extension public function load(array $configs, ContainerBuilder $container) { - $configuration = $this->getConfiguration($configs, $container); - $config = $this->processConfiguration($configuration, $configs); - + $config = $this->processConfiguration(new Configuration($configs, $container), $configs); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); if (empty($config['clients']) || empty($config['indexes'])) { @@ -43,25 +47,19 @@ class FOSElasticaExtension extends Extension $config['default_index'] = reset($keys); } - $clientIdsByName = $this->loadClients($config['clients'], $container); - $this->serializerConfig = isset($config['serializer']) ? $config['serializer'] : null; - $indexIdsByName = $this->loadIndexes($config['indexes'], $container, $clientIdsByName, $config['default_client']); - $indexRefsByName = array_map(function($id) { - return new Reference($id); - }, $indexIdsByName); - - $this->loadIndexManager($indexRefsByName, $container); - $this->loadResetter($this->indexConfigs, $container); - + $this->loadClients($config['clients'], $container); $container->setAlias('fos_elastica.client', sprintf('fos_elastica.client.%s', $config['default_client'])); + + // XX serializer can be done better.... + // $this->serializerConfig = isset($config['serializer']) ? $config['serializer'] : null; + + $this->loadIndexes($config['indexes'], $container); $container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index'])); - $this->createDefaultManagerAlias($config['default_manager'], $container); - } + $this->loadIndexManager($container); + $this->loadResetter($container); - public function getConfiguration(array $config, ContainerBuilder $container) - { - return new Configuration($config); + $this->createDefaultManagerAlias($config['default_manager'], $container); } /** @@ -73,22 +71,24 @@ class FOSElasticaExtension extends Extension */ protected function loadClients(array $clients, ContainerBuilder $container) { - $clientIds = array(); foreach ($clients as $name => $clientConfig) { $clientId = sprintf('fos_elastica.client.%s', $name); - $clientDef = new Definition('%fos_elastica.client.class%', array($clientConfig)); + + $clientDef = new DefinitionDecorator('fos_elastica.client_prototype'); + $clientDef->replaceArgument(0, $clientConfig); + $logger = $clientConfig['servers'][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; } /** @@ -96,35 +96,29 @@ class FOSElasticaExtension extends Extension * * @param array $indexes An array of indexes configurations * @param ContainerBuilder $container A ContainerBuilder instance - * @param array $clientIdsByName - * @param $defaultClientName - * @param $serializerConfig * @throws \InvalidArgumentException * @return array */ - protected function loadIndexes(array $indexes, ContainerBuilder $container, array $clientIdsByName, $defaultClientName) + protected function loadIndexes(array $indexes, ContainerBuilder $container) { $indexIds = array(); + foreach ($indexes as $name => $index) { - 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; + $indexId = sprintf('fos_elastica.index.%s', $name); + $indexName = $index['index_name'] ?: $name; + + $indexDef = new DefinitionDecorator('fos_elastica.index_prototype'); + $indexDef->replaceArgument(0, $indexName); + + if ($index['client']) { + $client = $this->getClient($index['client']); + $indexDef->setFactoryService($client); } - $clientId = $clientIdsByName[$clientName]; - $indexId = sprintf('fos_elastica.index.%s', $name); - $indexName = isset($index['index_name']) ? $index['index_name'] : $name; - $indexDefArgs = array($indexName); - $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; + $this->indexConfigs[$name] = array( 'index' => new Reference($indexId), 'name_or_alias' => $indexName, @@ -132,10 +126,13 @@ class FOSElasticaExtension extends Extension 'mappings' => array() ) ); + if ($index['finder']) { + // XX Deprecated $this->loadIndexFinder($container, $name, $indexId); } if (!empty($index['settings'])) { + // XX What is this for? $this->indexConfigs[$name]['config']['settings'] = $index['settings']; } if ($index['use_alias']) { @@ -522,26 +519,26 @@ class FOSElasticaExtension extends Extension /** * Loads the index manager * - * @param array $indexRefsByName * @param ContainerBuilder $container - **/ - protected function loadIndexManager(array $indexRefsByName, ContainerBuilder $container) + */ + protected function loadIndexManager(ContainerBuilder $container) { + $indexRefs = array_map(function ($index) { return $index['index']; }, $this->indexConfigs); + $managerDef = $container->getDefinition('fos_elastica.index_manager'); - $managerDef->replaceArgument(0, $indexRefsByName); + $managerDef->replaceArgument(0, $indexRefs); $managerDef->replaceArgument(1, new Reference('fos_elastica.index')); } /** * Loads the resetter * - * @param array $indexConfigs - * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container + * @param ContainerBuilder $container */ - protected function loadResetter(array $indexConfigs, ContainerBuilder $container) + protected function loadResetter(ContainerBuilder $container) { $resetterDef = $container->getDefinition('fos_elastica.resetter'); - $resetterDef->replaceArgument(0, $indexConfigs); + $resetterDef->replaceArgument(0, $this->indexConfigs); } protected function loadDriver(ContainerBuilder $container, $driver) @@ -549,6 +546,7 @@ class FOSElasticaExtension extends Extension if (in_array($driver, $this->loadedDrivers)) { return; } + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load($driver.'.xml'); $this->loadedDrivers[] = $driver; @@ -570,4 +568,20 @@ class FOSElasticaExtension extends Extension $container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService)); } + + /** + * Returns a reference to a client. + * + * @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']; + } } diff --git a/Doctrine/MongoDB/Lookup.php b/Doctrine/MongoDB/Lookup.php index 6c48759..1951964 100644 --- a/Doctrine/MongoDB/Lookup.php +++ b/Doctrine/MongoDB/Lookup.php @@ -3,7 +3,7 @@ namespace FOS\ElasticaBundle\Doctrine\MongoDB; use FOS\ElasticaBundle\Doctrine\AbstractLookup; -use FOS\ElasticaBundle\Type\TypeConfigurationInterface; +use FOS\ElasticaBundle\Type\TypeConfiguration; class Lookup extends AbstractLookup { @@ -20,11 +20,11 @@ class Lookup extends AbstractLookup /** * Look up objects of a specific type with ids as supplied. * - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @param array $ids * @return array */ - public function lookup(TypeConfigurationInterface $configuration, array $ids) + public function lookup(TypeConfiguration $configuration, array $ids) { $qb = $this->createQueryBuilder($configuration); $qb->hydrate($configuration->isHydrate()); @@ -36,10 +36,10 @@ class Lookup extends AbstractLookup } /** - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @return \Doctrine\ODM\MongoDB\Query\Builder */ - private function createQueryBuilder(TypeConfigurationInterface $configuration) + private function createQueryBuilder(TypeConfiguration $configuration) { $method = $configuration->getRepositoryMethod(); $manager = $this->registry->getManagerForClass($configuration->getModelClass()); diff --git a/Doctrine/ORM/Lookup.php b/Doctrine/ORM/Lookup.php index 2e2cfe3..6ec2167 100644 --- a/Doctrine/ORM/Lookup.php +++ b/Doctrine/ORM/Lookup.php @@ -4,7 +4,7 @@ namespace FOS\ElasticaBundle\Doctrine\ORM; use Doctrine\ORM\Query; use FOS\ElasticaBundle\Doctrine\AbstractLookup; -use FOS\ElasticaBundle\Type\TypeConfigurationInterface; +use FOS\ElasticaBundle\Type\TypeConfiguration; class Lookup extends AbstractLookup { @@ -23,11 +23,11 @@ class Lookup extends AbstractLookup /** * Look up objects of a specific type with ids as supplied. * - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @param array $ids * @return array */ - public function lookup(TypeConfigurationInterface $configuration, array $ids) + public function lookup(TypeConfiguration $configuration, array $ids) { $hydrationMode = $configuration->isHydrate() ? Query::HYDRATE_OBJECT : @@ -45,10 +45,10 @@ class Lookup extends AbstractLookup } /** - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @return \Doctrine\ORM\QueryBuilder */ - private function createQueryBuilder(TypeConfigurationInterface $configuration) + private function createQueryBuilder(TypeConfiguration $configuration) { $repository = $this->registry->getRepository($configuration->getModelClass()); $method = $configuration->getRepositoryMethod(); diff --git a/Exception/UnexpectedObjectException.php b/Exception/UnexpectedObjectException.php index afe671d..d247778 100644 --- a/Exception/UnexpectedObjectException.php +++ b/Exception/UnexpectedObjectException.php @@ -8,6 +8,6 @@ class UnexpectedObjectException extends \Exception { public function __construct($id) { - parent::__construct(sprintf('Lookup returned an unknown object with id %d', $id)); + parent::__construct(sprintf('Lookup returned an unexpected object with id %d', $id)); } } diff --git a/Finder/PaginatedFinderInterface.php b/Finder/PaginatedFinderInterface.php deleted file mode 100644 index fa10b70..0000000 --- a/Finder/PaginatedFinderInterface.php +++ /dev/null @@ -1,28 +0,0 @@ -search($query, $limit, $options); @@ -78,29 +78,4 @@ class TransformedFinder implements PaginatedFinderInterface return $results; } - - /** - * Gets a paginator wrapping the result of a search - * - * @param string $query - * @param array $options - * @return Pagerfanta - */ - public function findPaginated($query, $options = array()) - { - $queryObject = Query::create($query); - $paginatorAdapter = $this->createPaginatorAdapter($queryObject, $options); - - return new Pagerfanta(new FantaPaginatorAdapter($paginatorAdapter)); - } - - /** - * {@inheritdoc} - */ - public function createPaginatorAdapter($query, $options = array()) - { - $query = Query::create($query); - - return new TransformedPaginatorAdapter($this->searchable, $query, $options, $this->transformer); - } } diff --git a/Index/IndexManager.php b/Index/IndexManager.php index 543ccae..dc270be 100644 --- a/Index/IndexManager.php +++ b/Index/IndexManager.php @@ -2,20 +2,25 @@ namespace FOS\ElasticaBundle\Index; -use Elastica\Index; +use FOS\ElasticaBundle\Elastica\TransformingIndex; class IndexManager { + /** + * @var TransformingIndex[] + */ protected $indexesByName; + + /** + * @var string + */ protected $defaultIndexName; /** - * Constructor. - * - * @param array $indexesByName - * @param Index $defaultIndex + * @param TransformingIndex[] $indexesByName + * @param TransformingIndex $defaultIndex */ - public function __construct(array $indexesByName, Index $defaultIndex) + public function __construct(array $indexesByName, TransformingIndex $defaultIndex) { $this->indexesByName = $indexesByName; $this->defaultIndexName = $defaultIndex->getName(); @@ -24,7 +29,7 @@ class IndexManager /** * Gets all registered indexes * - * @return array + * @return TransformingIndex[] */ public function getAllIndexes() { @@ -35,7 +40,7 @@ class IndexManager * Gets an index by its name * * @param string $name Index to return, or the default index if null - * @return Index + * @return TransformingIndex * @throws \InvalidArgumentException if no index exists for the given name */ public function getIndex($name = null) @@ -54,7 +59,7 @@ class IndexManager /** * Gets the default index * - * @return Index + * @return TransformingIndex */ public function getDefaultIndex() { diff --git a/Paginator/FantaPaginatorAdapter.php b/Paginator/FantaPaginatorAdapter.php deleted file mode 100644 index 2ad6983..0000000 --- a/Paginator/FantaPaginatorAdapter.php +++ /dev/null @@ -1,57 +0,0 @@ -adapter = $adapter; - } - - /** - * Returns the number of results. - * - * @return integer The number of results. - * - * @api - */ - public function getNbResults() - { - return $this->adapter->getTotalHits(); - } - - /** - * Returns Facets - * - * @return mixed - * - * @api - */ - public function getFacets() - { - return $this->adapter->getFacets(); - } - - /** - * Returns a slice of the results. - * - * @param integer $offset The offset. - * @param integer $length The length. - * - * @return array|\Traversable The slice. - * - * @api - */ - public function getSlice($offset, $length) - { - return $this->adapter->getResults($offset, $length)->toArray(); - } -} diff --git a/Paginator/PaginatorAdapterInterface.php b/Paginator/PaginatorAdapterInterface.php deleted file mode 100644 index 25786a0..0000000 --- a/Paginator/PaginatorAdapterInterface.php +++ /dev/null @@ -1,34 +0,0 @@ -searchable = $searchable; - $this->query = $query; - $this->options = $options; - } - - /** - * Returns the paginated results. - * - * @param $offset - * @param $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 ($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(); - 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. - * - * @return integer The number of results. - */ - public function getTotalHits() - { - if ( ! isset($this->totalHits)) { - $this->totalHits = $this->searchable->search($this->query)->getTotalHits(); - } - - return $this->query->hasParam('size') - ? 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 the Query - * - * @return Query the search query - */ - public function getQuery() - { - return $this->query; - } -} diff --git a/Paginator/RawPartialResults.php b/Paginator/RawPartialResults.php deleted file mode 100644 index a4afb00..0000000 --- a/Paginator/RawPartialResults.php +++ /dev/null @@ -1,52 +0,0 @@ -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 null; - } -} \ No newline at end of file diff --git a/Paginator/TransformedPaginatorAdapter.php b/Paginator/TransformedPaginatorAdapter.php deleted file mode 100644 index 3b4716f..0000000 --- a/Paginator/TransformedPaginatorAdapter.php +++ /dev/null @@ -1,36 +0,0 @@ -transformer = $transformer; - } - - /** - * {@inheritDoc} - */ - public function getResults($offset, $length) - { - return new TransformedPartialResults($this->getElasticaResults($offset, $length), $this->transformer); - } -} diff --git a/Paginator/TransformedPartialResults.php b/Paginator/TransformedPartialResults.php deleted file mode 100644 index 13d716c..0000000 --- a/Paginator/TransformedPartialResults.php +++ /dev/null @@ -1,33 +0,0 @@ -transformer = $transformer; - } - - /** - * {@inheritDoc} - */ - public function toArray() - { - return $this->transformer->transform($this->resultSet->getResults()); - } -} \ No newline at end of file diff --git a/Propel/Lookup.php b/Propel/Lookup.php index 61e4c94..1793b05 100644 --- a/Propel/Lookup.php +++ b/Propel/Lookup.php @@ -4,7 +4,7 @@ namespace FOS\ElasticaBundle\Propel; use Doctrine\Common\Util\Inflector; use FOS\ElasticaBundle\Type\LookupInterface; -use FOS\ElasticaBundle\Type\TypeConfigurationInterface; +use FOS\ElasticaBundle\Type\TypeConfiguration; class Lookup implements LookupInterface { @@ -21,11 +21,11 @@ class Lookup implements LookupInterface /** * Look up objects of a specific type with ids as supplied. * - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @param int[] $ids * @return object[] */ - public function lookup(TypeConfigurationInterface $configuration, array $ids) + public function lookup(TypeConfiguration $configuration, array $ids) { $query = $this->createQuery($configuration, $ids); @@ -39,11 +39,11 @@ class Lookup implements LookupInterface /** * Create a query to use in the findByIdentifiers() method. * - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @param array $ids * @return \ModelCriteria */ - protected function createQuery(TypeConfigurationInterface $configuration, array $ids) + protected function createQuery(TypeConfiguration $configuration, array $ids) { $queryClass = $configuration->getModelClass() . 'Query'; $query = $queryClass::create(); diff --git a/Resources/config/config.xml b/Resources/config/config.xml index fbf6d1c..08993dd 100644 --- a/Resources/config/config.xml +++ b/Resources/config/config.xml @@ -6,96 +6,29 @@ FOS\ElasticaBundle\Elastica\LoggingClient - FOS\ElasticaBundle\Elastica\TransformingIndex - Elastica\Type - FOS\ElasticaBundle\IndexManager - FOS\ElasticaBundle\Resetter - FOS\ElasticaBundle\Finder\TransformedFinder - FOS\ElasticaBundle\Subscriber\PaginateElasticaQuerySubscriber FOS\ElasticaBundle\Logger\ElasticaLogger FOS\ElasticaBundle\DataCollector\ElasticaDataCollector - FOS\ElasticaBundle\Manager\RepositoryManager - FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection - FOS\ElasticaBundle\Provider\ProviderRegistry Symfony\Component\PropertyAccess\PropertyAccessor - FOS\ElasticaBundle\Persister\ObjectPersister - FOS\ElasticaBundle\Persister\ObjectSerializerPersister - FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer - FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer + + + + + %kernel.debug% + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Resources/config/index.xml b/Resources/config/index.xml new file mode 100644 index 0000000..02b2948 --- /dev/null +++ b/Resources/config/index.xml @@ -0,0 +1,35 @@ + + + + + + FOS\ElasticaBundle\Elastica\TransformingIndex + Elastica\Type + FOS\ElasticaBundle\IndexManager + FOS\ElasticaBundle\Resetter + FOS\ElasticaBundle\Finder\TransformedFinder + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/config/orm.xml b/Resources/config/orm.xml index 5bd16e5..d44d9ae 100644 --- a/Resources/config/orm.xml +++ b/Resources/config/orm.xml @@ -31,8 +31,8 @@ - - + + diff --git a/Resources/config/persister.xml b/Resources/config/persister.xml new file mode 100644 index 0000000..8bd4dca --- /dev/null +++ b/Resources/config/persister.xml @@ -0,0 +1,27 @@ + + + + + + FOS\ElasticaBundle\Persister\ObjectPersister + FOS\ElasticaBundle\Persister\ObjectSerializerPersister + + + + + + + + + + + + + + + + + + diff --git a/Resources/config/provider.xml b/Resources/config/provider.xml new file mode 100644 index 0000000..0732d54 --- /dev/null +++ b/Resources/config/provider.xml @@ -0,0 +1,18 @@ + + + + + + FOS\ElasticaBundle\Provider\ProviderRegistry + + + + + + + + + + diff --git a/Resources/config/transformer.xml b/Resources/config/transformer.xml new file mode 100644 index 0000000..e3abbbc --- /dev/null +++ b/Resources/config/transformer.xml @@ -0,0 +1,32 @@ + + + + + + FOS\ElasticaBundle\Transformer\ElasticaToModelTransformerCollection + FOS\ElasticaBundle\Transformer\ModelToElasticaAutoTransformer + FOS\ElasticaBundle\Transformer\ModelToElasticaIdentifierTransformer + + + + + + + + + + + + + + + + + + + + + + diff --git a/Transformer/CombinedResultTransformer.php b/Transformer/CombinedResultTransformer.php index 791e601..50822ae 100644 --- a/Transformer/CombinedResultTransformer.php +++ b/Transformer/CombinedResultTransformer.php @@ -12,7 +12,7 @@ use FOS\ElasticaBundle\Elastica\TransformingResult; class CombinedResultTransformer { /** - * @var \FOS\ElasticaBundle\Type\TypeConfigurationInterface + * @var \FOS\ElasticaBundle\Type\TypeConfiguration */ private $configurations; @@ -22,7 +22,7 @@ class CombinedResultTransformer private $transformer; /** - * @param \FOS\ElasticaBundle\Type\TypeConfigurationInterface[] $configurations + * @param \FOS\ElasticaBundle\Type\TypeConfiguration[] $configurations * @param ResultTransformerInterface $transformer */ public function __construct(array $configurations, ResultTransformerInterface $transformer) @@ -54,7 +54,7 @@ class CombinedResultTransformer * Retrieves the transformer for a given type. * * @param string $type - * @return \FOS\ElasticaBundle\Type\TypeConfigurationInterface + * @return \FOS\ElasticaBundle\Type\TypeConfiguration * @throws \InvalidArgumentException */ private function getConfiguration($type) diff --git a/Transformer/ResultTransformer.php b/Transformer/ResultTransformer.php index 68b9364..31a4b9f 100644 --- a/Transformer/ResultTransformer.php +++ b/Transformer/ResultTransformer.php @@ -5,8 +5,7 @@ namespace FOS\ElasticaBundle\Transformer; use FOS\ElasticaBundle\Exception\MissingModelException; use FOS\ElasticaBundle\Exception\UnexpectedObjectException; use FOS\ElasticaBundle\Type\LookupManager; -use FOS\ElasticaBundle\Type\TypeConfigurationInterface; -use Psr\Log\LoggerInterface; +use FOS\ElasticaBundle\Type\TypeConfiguration; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; /** @@ -35,12 +34,12 @@ class ResultTransformer implements ResultTransformerInterface /** * Transforms Elastica results into Models. * - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @param \FOS\ElasticaBundle\Elastica\TransformingResult[] $results * @throws \FOS\ElasticaBundle\Exception\MissingModelException * @throws \FOS\ElasticaBundle\Exception\UnexpectedObjectException */ - public function transform(TypeConfigurationInterface $configuration, $results) + public function transform(TypeConfiguration $configuration, $results) { $results = $this->processResults($results); $lookup = $this->lookupManager->getLookup($configuration->getType()); diff --git a/Transformer/ResultTransformerInterface.php b/Transformer/ResultTransformerInterface.php index c18fc7c..ebce242 100644 --- a/Transformer/ResultTransformerInterface.php +++ b/Transformer/ResultTransformerInterface.php @@ -2,15 +2,15 @@ namespace FOS\ElasticaBundle\Transformer; -use FOS\ElasticaBundle\Type\TypeConfigurationInterface; +use FOS\ElasticaBundle\Type\TypeConfiguration; interface ResultTransformerInterface { /** * Transforms Elastica results into Models. * - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @param array $results */ - public function transform(TypeConfigurationInterface $configuration, $results); + public function transform(TypeConfiguration $configuration, $results); } diff --git a/Type/LookupInterface.php b/Type/LookupInterface.php index c956511..2f117b9 100644 --- a/Type/LookupInterface.php +++ b/Type/LookupInterface.php @@ -19,9 +19,9 @@ interface LookupInterface /** * Look up objects of a specific type with ids as supplied. * - * @param TypeConfigurationInterface $configuration + * @param TypeConfiguration $configuration * @param int[] $ids * @return object[] */ - public function lookup(TypeConfigurationInterface $configuration, array $ids); + public function lookup(TypeConfiguration $configuration, array $ids); } diff --git a/Type/LookupManager.php b/Type/LookupManager.php index 0db0fd1..15a7dc6 100644 --- a/Type/LookupManager.php +++ b/Type/LookupManager.php @@ -19,7 +19,6 @@ class LookupManager } } - /** * @param string $type * @return LookupInterface diff --git a/Type/TypeConfiguration.php b/Type/TypeConfiguration.php new file mode 100644 index 0000000..6a9ff0d --- /dev/null +++ b/Type/TypeConfiguration.php @@ -0,0 +1,102 @@ + + */ +final class TypeConfiguration +{ + /** + * The identifier property that is used to retrieve an identifier from the model. + * + * @var string + */ + private $identifierProperty; + + /** + * Returns the fully qualified class for the model that this type represents. + * + * @var string + */ + private $modelClass; + + /** + * Returns the repository method that will create a query builder or associated + * query object for lookup purposes. + * + * @var string + */ + private $repositoryMethod; + + /** + * Returns the name of the type. + * + * @var string + */ + private $type; + + /** + * If the lookup should hydrate models to objects or leave data as an array. + * + * @var bool + */ + private $hydrate = true; + + /** + * If the type should ignore missing results from a lookup. + * + * @var bool + */ + private $ignoreMissing = false; + + /** + * @return boolean + */ + public function isHydrate() + { + return $this->hydrate; + } + + /** + * @return string + */ + public function getIdentifierProperty() + { + return $this->identifierProperty; + } + + /** + * @return boolean + */ + public function isIgnoreMissing() + { + return $this->ignoreMissing; + } + + /** + * @return string + */ + public function getModelClass() + { + return $this->modelClass; + } + + /** + * @return string + */ + public function getRepositoryMethod() + { + return $this->repositoryMethod; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } +} diff --git a/Type/TypeConfigurationInterface.php b/Type/TypeConfigurationInterface.php deleted file mode 100644 index bee3388..0000000 --- a/Type/TypeConfigurationInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ -interface TypeConfigurationInterface -{ - /** - * The identifier property that is used to retrieve an identifier from the model. - * - * @return string - */ - public function getIdentifierProperty(); - - /** - * Returns the fully qualified class for the model that this type represents. - * - * @return string - */ - public function getModelClass(); - - /** - * Returns the repository method that will create a query builder or associated - * query object for lookup purposes. - * - * @return string - */ - public function getRepositoryMethod(); - - /** - * Returns the name of the type. - * - * @return string - */ - public function getType(); - - /** - * If the lookup should hydrate models to objects or leave data as an array. - * - * @return bool - */ - public function isHydrate(); - - /** - * If the type should ignore missing results from a lookup. - * - * @return bool - */ - public function isIgnoreMissing(); -} \ No newline at end of file