diff --git a/.travis.yml b/.travis.yml index 564e9428..f0adde8f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: php php: - - 5.6 - - 7.0 - 7.1 - hhvm @@ -24,7 +22,7 @@ matrix: allow_failures: - php: hhvm include: - - php: 5.6 + - php: 7.1 env: deps=low sudo: false diff --git a/Attribute/SpecializedAttribute.php b/Attribute/SpecializedAttribute.php index 8894061b..3ffd1d4f 100644 --- a/Attribute/SpecializedAttribute.php +++ b/Attribute/SpecializedAttribute.php @@ -12,55 +12,66 @@ class SpecializedAttribute extends Attribute implements SpecializedAttributeInterface { /** - * @var AttributeSpecializationInterface + * @var AttributeSpecializationInterface[] */ - protected $specialization; + protected $specializations; /** - * @var AttributeSpecializationContextInterface + * @var AttributeSpecializationContextInterface[] */ - protected $context; + protected $contexts; /** - * @param AttributeSpecializationInterface $specialization + * @param AttributeSpecializationInterface[] $specializations * @param string $name * @param string $key * @param string $displayName * @param callable|null $valueDisplayStrategy */ public function __construct( - AttributeSpecializationInterface $specialization, - $name, - $key = null, - $displayName = null, + array $specializations, + string $name, + string $key = null, + string $displayName = null, callable $valueDisplayStrategy = null ) { - $this->specialization = $specialization; + $this->specializations = $specializations; + $this->contexts = []; parent::__construct($name, $key, $displayName, $valueDisplayStrategy); } /** * {@inheritDoc} */ - public function getSpecialization() + public function getSpecializations() { - return $this->specialization; + return $this->specializations; } /** * {@inheritDoc} */ - public function setContext(AttributeSpecializationContextInterface $context) - { - $this->context = $context; + public function setContext( + AttributeSpecializationContextInterface $context, + string $specialization + ) { + $this->contexts[$specialization] = $context; } /** * {@inheritDoc} */ - public function getContext() + public function getContext(string $specialization) { - return $this->context; + if (!array_key_exists($specialization, $this->contexts)) { + throw new \LogicException( + 'Cannot get context for specialization `%s` on attribute `%s` as it has not been set', + $specialization, + $this->getName() + ); + } + + return $this->contexts[$specialization]; } /** @@ -68,19 +79,41 @@ public function getContext() */ public function getSearchKey(array $options = []) { - if (!$this->context) { - throw new \LogicException(sprintf('Cannot get a search key for a specialized attribute without a context where name is %s', $this->getName())); + foreach ($this->specializations as $specialization) { + if (!array_key_exists($specialization->getName(), $this->contexts)) { + throw new \LogicException( + sprintf( + 'Cannot get context for specialization `%s` on attribute `%s` as it has not been set', + $specialization->getName(), + $this->getName() + ) + ); + } } - if ($this->context instanceof AttributeSpecializationNullContextInterface) { - return parent::getSearchKey(); + ksort($this->contexts); + $contextValues = []; + + foreach ($this->contexts as $context) { + if ($context instanceof AttributeSpecializationNullContextInterface) { + continue; + } + + try { + $contextValues[] = $context->getValue(); + } catch (IllegalContextValueException $e) { + throw new UnformableSearchKeyException( + sprintf( + 'The attribute "%s" cannot form a search key due to incomplete context data.', + $this->getName()) + ); + } } - try { - $contextValue = $this->context->getValue(); - } catch (IllegalContextValueException $e) { - throw new UnformableSearchKeyException(sprintf('The attribute "%s" cannot form a search key due to incomplete context data.', $this->getName())); + + if (empty($contextValues)) { + return parent::getSearchKey(); } - return sprintf('%s_%s', parent::getSearchKey(), $contextValue); + return sprintf('%s_%s', parent::getSearchKey(), implode('_', $contextValues)); } } diff --git a/Attribute/SpecializedAttributeDecorator.php b/Attribute/SpecializedAttributeDecorator.php index 45496e6b..51697cbc 100644 --- a/Attribute/SpecializedAttributeDecorator.php +++ b/Attribute/SpecializedAttributeDecorator.php @@ -10,7 +10,7 @@ abstract class SpecializedAttributeDecorator implements SpecializedAttributeInte /** * The attribute being decorated. * - * @var SpecializedAttributeInterface + * @var SpecializedAttributeInterface|AttributeInterface **/ private $attribute; @@ -58,25 +58,27 @@ public function getAttribute() /** * {@inheritDoc} */ - public function getSpecialization() + public function getSpecializations() { - return $this->attribute->getSpecialization(); + return $this->attribute->getSpecializations(); } /** * {@inheritDoc} */ - public function setContext(AttributeSpecializationContextInterface $context) - { - $this->attribute->setContext($context); + public function setContext( + AttributeSpecializationContextInterface $context, + string $specialization + ) { + $this->attribute->setContext($context, $specialization); } /** * {@inheritDoc} */ - public function getContext() + public function getContext(string $specialization) { - return $this->attribute->getContext(); + return $this->attribute->getContext($specialization); } public function __toString() diff --git a/Attribute/SpecializedAttributeInterface.php b/Attribute/SpecializedAttributeInterface.php index a8b011f5..534a3373 100644 --- a/Attribute/SpecializedAttributeInterface.php +++ b/Attribute/SpecializedAttributeInterface.php @@ -3,23 +3,25 @@ namespace Markup\NeedleBundle\Attribute; /** - * An attribute implementation that has a specialization set on it + * An attribute implementation that has one or more specializations set on it * allowing the search key to be changed by adding a context */ interface SpecializedAttributeInterface { /** - * @return AttributeSpecialization + * @return AttributeSpecialization[] */ - public function getSpecialization(); + public function getSpecializations(); /** * @param AttributeSpecializationContextInterface + * @param string */ - public function setContext(AttributeSpecializationContextInterface $context); + public function setContext(AttributeSpecializationContextInterface $context, string $specialization); /** + * @param string * @return AttributeSpecializationContextInterface */ - public function getContext(); + public function getContext(string $specialization); } diff --git a/composer.json b/composer.json index d62b7709..080d10c1 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": ">=5.6", + "php": ">=7.1", "nelmio/solarium-bundle": "^2.0.4", "solarium/solarium": "^3.1.0", "pagerfanta/pagerfanta": "~1.0.1",