Skip to content

Commit

Permalink
Removed MLProperty annotation in favour of multilanguage=true setting…
Browse files Browse the repository at this point in the history
… of Property annotation
  • Loading branch information
pmishev committed Nov 23, 2015
1 parent 688ff2b commit a52becd
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 129 deletions.
59 changes: 0 additions & 59 deletions Annotation/AbstractProperty.php

This file was deleted.

54 changes: 0 additions & 54 deletions Annotation/MLProperty.php

This file was deleted.

83 changes: 82 additions & 1 deletion Annotation/Property.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,95 @@

namespace Sineflow\ElasticsearchBundle\Annotation;

use Sineflow\ElasticsearchBundle\Mapping\DumperInterface;

/**
* Annotation used to check mapping type during the parsing process.
*
* @Annotation
* @Target("PROPERTY")
*/
final class Property extends AbstractProperty
final class Property implements DumperInterface
{
const LANGUAGE_PLACEHOLDER = '{lang}';
const DEFAULT_LANG_SUFFIX = 'default';

/**
* @var string
*
* @Required
*/
public $name;

/**
* @var string
*
* @Required
* @Enum({"string", "boolean", "integer", "float", "date", "object", "nested", "geo_point", "geo_shape", "ip"})
*/
public $type;

/**
* @var bool
*/
public $multilanguage;

/**
* The object name must be defined, if type is 'object' or 'nested'
*
* @var string Object name to map.
*/
public $objectName;

/**
* Defines if related object will have one or multiple values.
* If this value is set to true, ObjectIterator will be provided in the result, as opposed to a Document object
*
* @var bool
*/
public $multiple;

/**
* Settings directly passed to Elasticsearch client as-is
*
* @var array
*/
public $options;

/**
* {@inheritdoc}
*/
public function dump(array $settings = [])
{
$result = array_merge((array) $this->options, ['type' => $this->type]);

if (isset($settings['language'])) {
if (!isset($settings['indexAnalyzers'])) {
throw new \InvalidArgumentException('Available index analyzers missing');
}

// Replace {lang} in any analyzers with the respective language
// If no analyzer is defined for a certain language, replace {lang} with 'default'
array_walk($result, function (&$value, $key, $settings) {
if (in_array($key, ['analyzer', 'index_analyzer', 'search_analyzer']) && false !== strpos($value, self::LANGUAGE_PLACEHOLDER)) {
// Get the names of all available analyzers in the index
$indexAnalyzers = array_keys($settings['indexAnalyzers']);

// Make sure a default analyzer is defined, even if we don't need it right now
// because, if a new language is added and we don't have an analyzer for it, ES mapping would fail
$defaultAnalyzer = str_replace(self::LANGUAGE_PLACEHOLDER, self::DEFAULT_LANG_SUFFIX, $value);
if (!in_array($defaultAnalyzer, $indexAnalyzers)) {
throw new \LogicException(sprintf('There must be a default language analyzer "%s" defined for index', $defaultAnalyzer));
}

$value = str_replace(self::LANGUAGE_PLACEHOLDER, $settings['language'], $value);
if (!in_array($value, $indexAnalyzers)) {
$value = $defaultAnalyzer;
}
}
}, $settings);
}

return $result;
}
}
1 change: 0 additions & 1 deletion Mapping/DocumentMetadataCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ public function __construct(array $indexManagers, DocumentLocator $documentLocat
*/
private function isCacheFresh()
{
return false;
$documentDirs = $this->documentLocator->getAllDocumentDirs();

foreach ($documentDirs as $dir) {
Expand Down
23 changes: 9 additions & 14 deletions Mapping/DocumentParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\Reader;
use Sineflow\ElasticsearchBundle\Annotation\AbstractProperty;
use Sineflow\ElasticsearchBundle\Annotation\Document;
use Sineflow\ElasticsearchBundle\Annotation\MLProperty;
use Sineflow\ElasticsearchBundle\Annotation\Property;
use Sineflow\ElasticsearchBundle\LanguageProvider\LanguageProviderInterface;

/**
Expand All @@ -17,7 +16,7 @@ class DocumentParser
/**
* @const string
*/
const PROPERTY_ANNOTATION = 'Sineflow\ElasticsearchBundle\Annotation\AbstractProperty';
const PROPERTY_ANNOTATION = 'Sineflow\ElasticsearchBundle\Annotation\Property';

/**
* @const string
Expand Down Expand Up @@ -148,7 +147,7 @@ private function getDocumentType(\ReflectionClass $documentReflection)
*
* @param \ReflectionProperty $property
*
* @return AbstractProperty
* @return Property
*/
public function getPropertyAnnotationData($property)
{
Expand Down Expand Up @@ -189,13 +188,9 @@ private function getPropertiesMetadata(\ReflectionClass $documentReflection)
$propertyMetadata[$propertyAnnotation->name] = [
'propertyName' => $propertyName,
'type' => $propertyAnnotation->type,
'multilanguage' => $propertyAnnotation->multilanguage,
];

// If property is multilanguage
if ($propertyAnnotation instanceof MLProperty) {
$propertyMetadata[$propertyAnnotation->name]['multilanguage'] = true;
}

// If property is a (nested) object
if (in_array($propertyAnnotation->type, ['object', 'nested'])) {
if (!$propertyAnnotation->objectName) {
Expand Down Expand Up @@ -313,19 +308,19 @@ private function getProperties(\ReflectionClass $documentReflection, array $inde
}

// If it is a multi-language property
if ($propertyAnnotation instanceof MLProperty) {
if (true === $propertyAnnotation->multilanguage) {
if ($propertyAnnotation->type != 'string') {
throw new \InvalidArgumentException(sprintf('"%s" property in %s is declared as "MLProperty", so can only be of type "string"', $propertyAnnotation->name, $documentReflection->getName()));
throw new \InvalidArgumentException(sprintf('"%s" property in %s is declared as multilanguage, so can only be of type "string"', $propertyAnnotation->name, $documentReflection->getName()));
}
if (!$this->languageProvider) {
throw new \InvalidArgumentException('There must be a service tagged as "sfes.language_provider" in order to use MLProperty');
throw new \InvalidArgumentException('There must be a service tagged as "sfes.language_provider" in order to use multilanguage properties');
}
foreach ($this->languageProvider->getLanguages() as $language) {
$mapping[$propertyAnnotation->name . $this->languageSeparator . $language] = $this->getPropertyMapping($propertyAnnotation, $language, $indexAnalyzers);
}
// TODO: The application should decide whether it wants to use a default field at all and set its mapping on a global base (or per property?)
// The custom mapping from the application should be set here, using perhaps some kind of decorator
$mapping[$propertyAnnotation->name . $this->languageSeparator . MLProperty::DEFAULT_LANG_SUFFIX] = [
$mapping[$propertyAnnotation->name . $this->languageSeparator . Property::DEFAULT_LANG_SUFFIX] = [
'type' => 'string',
'index' => 'not_analyzed'
];
Expand All @@ -338,7 +333,7 @@ private function getProperties(\ReflectionClass $documentReflection, array $inde
return $mapping;
}

private function getPropertyMapping(AbstractProperty $propertyAnnotation, $language = null, array $indexAnalyzers = [])
private function getPropertyMapping(Property $propertyAnnotation, $language = null, array $indexAnalyzers = [])
{
$propertyMapping = $propertyAnnotation->dump([
'language' => $language,
Expand Down

0 comments on commit a52becd

Please sign in to comment.