diff --git a/pathauto.install b/pathauto.install index a8ecabf..0adbc03 100644 --- a/pathauto.install +++ b/pathauto.install @@ -200,3 +200,21 @@ function pathauto_update_8100() { return implode('
', $messages); } } + +/** + * Update relationship storage. + */ +function pathauto_update_8101() { + foreach (\Drupal::configFactory()->listAll('pathauto.pattern.') as $pattern_config_name) { + $pattern_config = \Drupal::configFactory()->getEditable($pattern_config_name); + + $relationships = []; + foreach ((array) $pattern_config->get('context_definitions') as $context_definition) { + $relationships[$context_definition['id']] = ['label' => $context_definition['label']]; + } + + $pattern_config->clear('context_definitions'); + $pattern_config->set('relationships', $relationships); + $pattern_config->save(); + } +} diff --git a/src/Entity/PathautoPattern.php b/src/Entity/PathautoPattern.php index c0d8862..321948d 100644 --- a/src/Entity/PathautoPattern.php +++ b/src/Entity/PathautoPattern.php @@ -7,16 +7,14 @@ namespace Drupal\pathauto\Entity; +use Drupal\Component\Plugin\Exception\ContextException; use Drupal\Core\Condition\ConditionPluginCollection; use Drupal\Core\Config\Entity\ConfigEntityBase; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Plugin\Context\Context; -use Drupal\Core\Plugin\Context\ContextDefinition; -use Drupal\Core\Plugin\Context\ContextInterface; use Drupal\Core\Plugin\ContextAwarePluginInterface; use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection; use Drupal\pathauto\PathautoPatternInterface; -use Drupal\rules\Context\ContextDefinitionInterface; /** * Defines the Pathauto pattern entity. @@ -111,11 +109,6 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa protected $weight = 0; /** - * @var \Drupal\Core\Plugin\Context\ContextInterface[]|NULL - */ - protected $contexts = NULL; - - /** * @var array */ protected $relationships = []; @@ -219,35 +212,27 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa /** * {@inheritdoc} */ - protected function getContexts() { - if (is_null($this->contexts)) { - $this->contexts = $this->getAliasType()->getContexts(); - foreach ($this->getRelationships() as $definition) { - /** @var \Drupal\ctools\TypedDataResolver $resolver */ - $resolver = \Drupal::service('ctools.typed_data.resolver'); - /** @var \Drupal\pathauto\Entity\PathautoPattern $entity */ - $context = $resolver->convertTokenToContext($definition['id'], $this->contexts); - $context_definition = $context->getContextDefinition(); - if (!empty($definition['label'])) { - $context_definition->setLabel($definition['label']); - } - $contexts[$definition['id']] = new Context($context_definition, $context->getContextValue()); - $this->contexts[$definition['id']] = $contexts[$definition['id']]; + public function getContexts() { + $contexts = $this->getAliasType()->getContexts(); + foreach ($this->getRelationships() as $token => $definition) { + /** @var \Drupal\ctools\TypedDataResolver $resolver */ + $resolver = \Drupal::service('ctools.typed_data.resolver'); + /** @var \Drupal\pathauto\Entity\PathautoPattern $entity */ + $context = $resolver->convertTokenToContext($token, $contexts); + $context_definition = $context->getContextDefinition(); + if (!empty($definition['label'])) { + $context_definition->setLabel($definition['label']); } + $contexts[$token] = $context; } - return $this->contexts; + return $contexts; } /** * {@inheritdoc} */ public function hasRelationship($token) { - foreach ($this->getRelationships() as $key => $definition) { - if ($definition['id'] == $token) { - return TRUE; - } - } - return FALSE; + return isset($this->relationships[$token]); } /** @@ -255,11 +240,9 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa */ public function addRelationship($token, $label = NULL) { if (!$this->hasRelationship($token)) { - $this->relationships[] = [ - 'id' => $token, + $this->relationships[$token] = [ 'label' => $label, ]; - $this->contexts = NULL; } return $this; } @@ -269,11 +252,9 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa */ public function replaceRelationship($token, $label) { if ($this->hasRelationship($token)) { - $this->relationships[] = [ - 'id' => $token, + $this->relationships[$token] = [ 'label' => $label, ]; - $this->contexts = NULL; } return $this; } @@ -282,12 +263,7 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa * {@inheritdoc} */ public function removeRelationship($token) { - foreach ($this->getRelationships() as $key => $definition) { - if ($definition['id'] == $token) { - unset($this->relationships[$key]); - $this->contexts = NULL; - } - } + unset($this->relationships[$token]); return $this; } @@ -352,22 +328,19 @@ class PathautoPattern extends ConfigEntityBase implements PathautoPatternInterfa // Set the context object on our Alias plugin before retrieving contexts. $this->getAliasType()->setContextValue($keys[0], $object); /** @var \Drupal\Core\Plugin\Context\ContextInterface[] $base_contexts */ - $base_contexts = $this->getAliasType()->getContexts(); - $contexts = []; - foreach ($base_contexts as $context_id => $base_context) { - $contexts[$context_id] = new Context($base_context->getContextDefinition(), $object); - } - /** @var \Drupal\ctools\TypedDataResolver $resolver */ - $resolver = \Drupal::service('ctools.typed_data.resolver'); - foreach ($this->getContexts() as $token => $context) { - $contexts[$token] = $resolver->convertTokenToContext($token, $contexts); - } + $contexts = $this->getContexts(); /** @var \Drupal\Core\Plugin\Context\ContextHandler $context_handler */ $context_handler = \Drupal::service('context.handler'); $conditions = $this->getSelectionConditions(); foreach ($conditions as $condition) { if ($condition instanceof ContextAwarePluginInterface) { - $context_handler->applyContextMapping($condition, $contexts); + try { + $context_handler->applyContextMapping($condition, $contexts); + } + catch (ContextException $e) { + watchdog_exception('pathauto', $e); + return FALSE; + } } $result = $condition->execute(); if ($this->getSelectionLogic() == 'and' && !$result) { diff --git a/src/PathautoPatternInterface.php b/src/PathautoPatternInterface.php index 0597187..9493dca 100644 --- a/src/PathautoPatternInterface.php +++ b/src/PathautoPatternInterface.php @@ -60,33 +60,69 @@ interface PathautoPatternInterface extends ConfigEntityInterface { public function setWeight($weight); /** + * Returns the contexts of this pattern. + * + * @return \Drupal\Core\Plugin\Context\ContextInterface[] + */ + public function getContexts(); + + /** + * Returns whether a relationship exists. + * + * @param string $token + * Relationship identifier. + * * @return bool + * TRUE if the relationship exists, FALSE otherwise. */ public function hasRelationship($token); /** + * Adds a relationship. + * + * The relationship will not be changed if it already exists. + * * @param string $token - * @param \Drupal\Core\Plugin\Context\ContextInterface $context + * Relationship identifier. + * @param string|null $label + * (optional) A label, will use the label of the referenced context if not + * provided. * * @return $this */ public function addRelationship($token, $label = NULL); /** + * Replaces a relationship. + * + * Only already existing relationships are updated. + * * @param string $token - * @param \Drupal\Core\Plugin\Context\ContextInterface $context + * Relationship identifier. + * @param string|null $label + * (optional) A label, will use the label of the referenced context if not + * provided. * * @return $this */ public function replaceRelationship($token, $label); /** + * Removes a relationship. + * * @param string $token + * Relationship identifier. * * @return $this */ public function removeRelationship($token); + /** + * Returns a list of relationships. + * + * @return array + * Relationships keyed by ID, a relationship is an array with a label key. + */ public function getRelationships(); /**