/**
  * Builds a Mapping collection from the annotation sources that are present
  *
  * @throws \Flowpack\ElasticSearch\Exception
  * @return \Flowpack\ElasticSearch\Mapping\MappingCollection<\Flowpack\ElasticSearch\Domain\Model\Mapping>
  */
 public function buildMappingInformation()
 {
     if (!$this->client instanceof Model\Client) {
         throw new \Flowpack\ElasticSearch\Exception('No client was given for mapping retrieval. Set a client BackendMappingBuilder->setClient().', 1339678111);
     }
     $this->indicesWithoutTypeInformation = array();
     $response = $this->client->request('GET', '/_mapping');
     $mappingInformation = new MappingCollection(MappingCollection::TYPE_BACKEND);
     $mappingInformation->setClient($this->client);
     $indexNames = $this->indexInformer->getAllIndexNames();
     foreach ($response->getTreatedContent() as $indexName => $indexSettings) {
         if (!in_array($indexName, $indexNames)) {
             continue;
         }
         $index = new Model\Index($indexName);
         if (empty($indexSettings)) {
             $this->indicesWithoutTypeInformation[] = $indexName;
         }
         foreach ($indexSettings as $typeName => $typeSettings) {
             $type = new Model\GenericType($index, $typeName);
             $mapping = new Model\Mapping($type);
             if (isset($typeSettings['properties'])) {
                 foreach ($typeSettings['properties'] as $propertyName => $propertySettings) {
                     foreach ($propertySettings as $key => $value) {
                         $mapping->setPropertyByPath(array($propertyName, $key), $value);
                     }
                 }
             }
             $mappingInformation->add($mapping);
         }
     }
     return $mappingInformation;
 }
 /**
  * @param string $className
  * @param \Flowpack\ElasticSearch\Annotations\Indexable $annotation
  * @return Mapping
  */
 protected function buildMappingFromClassAndAnnotation($className, \Flowpack\ElasticSearch\Annotations\Indexable $annotation)
 {
     $index = new \Flowpack\ElasticSearch\Domain\Model\Index($annotation->indexName);
     $type = new \Flowpack\ElasticSearch\Domain\Model\GenericType($index, $annotation->typeName);
     $mapping = new Mapping($type);
     foreach ($this->indexInformer->getClassProperties($className) as $propertyName) {
         $this->augmentMappingByProperty($mapping, $className, $propertyName);
     }
     return $mapping;
 }
 /**
  * Returns the ElasticSearch type for a specific object, by its annotation
  *
  * @param $object
  * @param \Flowpack\ElasticSearch\Domain\Model\Client $client
  *
  * @return \Flowpack\ElasticSearch\Domain\Model\GenericType
  */
 protected function getIndexTypeForObject($object, Client $client = null)
 {
     if ($client === null) {
         $client = $this->client;
     }
     $className = $this->reflectionService->getClassNameByObject($object);
     $indexAnnotation = $this->indexInformer->getClassAnnotation($className);
     if ($indexAnnotation === null) {
         return null;
     }
     $index = $client->findIndex($indexAnnotation->indexName);
     $type = new GenericType($index, $indexAnnotation->typeName);
     return $type;
 }
 /**
  * @test
  */
 public function classWithNoPropertyAnnotatedHasAllPropertiesToBeIndexed()
 {
     $actual = $this->informer->getClassProperties('Flowpack\\ElasticSearch\\Tests\\Functional\\Fixtures\\Tweet');
     $this->assertGreaterThan(1, $actual);
 }
 /**
  * Shows the status of the current mapping
  *
  * @param string $object Class name of a domain object. If given, will only work on this single object
  * @param boolean $conductUpdate Set to TRUE to conduct the required corrections
  * @param string $clientName The client name to use
  */
 public function statusCommand($object = null, $conductUpdate = false, $clientName = null)
 {
     $result = new ErrorResult();
     $client = $this->clientFactory->create($clientName);
     $classesAndAnnotations = $this->indexInformer->getClassesAndAnnotations();
     if ($object !== null) {
         if (!isset($classesAndAnnotations[$object])) {
             $this->outputFormatted("Error: Object '<b>%s</b>' is not configured correctly, check the Indexable annotation.", array($object));
             $this->quit(1);
         }
         $classesAndAnnotations = array($object => $classesAndAnnotations[$object]);
     }
     array_walk($classesAndAnnotations, function (Indexable $annotation, $className) use($result, $client, $conductUpdate) {
         $this->outputFormatted("Object %s", array($className), 4);
         $this->outputFormatted("Index <b>%s</b> Type <b>%s</b>", array($annotation->indexName, $annotation->typeName), 8);
         $count = $client->findIndex($annotation->indexName)->findType($annotation->typeName)->count();
         if ($count === null) {
             $result->forProperty($className)->addError(new Error('ElasticSearch was unable to retrieve a count for the type "%s" at index "%s". Probably these don\' exist.', 1340289921, array($annotation->typeName, $annotation->indexName)));
         }
         $this->outputFormatted("Documents in Search: <b>%s</b>", array($count !== null ? $count : "Error"), 8);
         try {
             $count = $this->persistenceManager->createQueryForType($className)->count();
         } catch (\Exception $exception) {
             $count = null;
             $result->forProperty($className)->addError(new Error('The persistence backend was unable to retrieve a count for the type "%s". The exception message was "%s".', 1340290088, array($className, $exception->getMessage())));
         }
         $this->outputFormatted("Documents in Persistence: <b>%s</b>", array($count !== null ? $count : "Error"), 8);
         if (!$result->forProperty($className)->hasErrors()) {
             $states = $this->getModificationsNeededStatesAndIdentifiers($client, $className);
             if ($conductUpdate) {
                 $inserted = 0;
                 $updated = 0;
                 foreach ($states[ObjectIndexer::ACTION_TYPE_CREATE] as $identifier) {
                     try {
                         $this->objectIndexer->indexObject($this->persistenceManager->getObjectByIdentifier($identifier, $className));
                         $inserted++;
                     } catch (\Exception $exception) {
                         $result->forProperty($className)->addError(new Error('An error occurred while trying to add an object to the ElasticSearch backend. The exception message was "%s".', 1340356330, array($exception->getMessage())));
                     }
                 }
                 foreach ($states[ObjectIndexer::ACTION_TYPE_UPDATE] as $identifier) {
                     try {
                         $this->objectIndexer->indexObject($this->persistenceManager->getObjectByIdentifier($identifier, $className));
                         $updated++;
                     } catch (\Exception $exception) {
                         $result->forProperty($className)->addError(new Error('An error occurred while trying to update an object to the ElasticSearch backend. The exception message was "%s".', 1340358590, array($exception->getMessage())));
                     }
                 }
                 $this->outputFormatted("Objects inserted: <b>%s</b>", array($inserted), 8);
                 $this->outputFormatted("Objects updated: <b>%s</b>", array($updated), 8);
             } else {
                 $this->outputFormatted("Modifications needed: <b>create</b> %d, <b>update</b> %d", array(count($states[ObjectIndexer::ACTION_TYPE_CREATE]), count($states[ObjectIndexer::ACTION_TYPE_UPDATE])), 8);
             }
         }
     });
     if ($result->hasErrors()) {
         $this->outputLine();
         $this->outputLine('The following errors occurred:');
         /** @var $error \TYPO3\Flow\Error\Error */
         foreach ($result->getFlattenedErrors() as $className => $errors) {
             foreach ($errors as $error) {
                 $this->outputLine();
                 $this->outputFormatted("<b>Error</b> for %s:", array($className), 8);
                 $this->outputFormatted((string) $error, array(), 4);
             }
         }
     }
 }