diff --git a/src/Context/PageContextRepository.php b/src/Context/PageContextRepository.php index fceaf3e..3a3114d 100644 --- a/src/Context/PageContextRepository.php +++ b/src/Context/PageContextRepository.php @@ -113,4 +113,53 @@ public function getAvailablePageOnlyContexts(PageInterface $page) { return $contexts; } + /** + * {@inheritdoc} + */ + public function getRuntimePageOnlyContexts(array $context_ids, PageInterface $page = NULL) { + $contexts = []; + + // Create a map of context providers (service IDs) to unqualified context + // IDs. + $context_ids_by_service = []; + foreach ($context_ids as $id) { + if (isset($this->contexts[$id])) { + $contexts[$id] = $this->contexts[$id]; + continue; + } + // The IDs have been passed in @{service_id}:{unqualified_context_id} + // format. + // @todo Convert to an assert once https://www.drupal.org/node/2408013 is + // in. + if ($id[0] === '@' && strpos($id, ':') !== FALSE) { + list($service_id, $unqualified_context_id) = explode(':', $id, 2); + // Remove the leading '@'. + $service_id = substr($service_id, 1); + } + else { + throw new \InvalidArgumentException('You must provide the context IDs in the @{service_id}:{unqualified_context_id} format.'); + } + $context_ids_by_service[$service_id][] = $unqualified_context_id; + } + + // Iterate over all missing context providers (services), gather the + // runtime contexts and assign them as requested. + foreach ($context_ids_by_service as $service_id => $unqualified_context_ids) { + $service = $this->container->get($service_id); + if ($service instanceof PageVariantContextProviderInterface) { + $contexts_by_service = $service->getRuntimePageOnlyContexts($unqualified_context_ids, $page); + } + else { + $contexts_by_service = $service->getRuntimeContexts($unqualified_context_ids); + } + $wanted_contexts = array_intersect_key($contexts_by_service, array_flip($unqualified_context_ids)); + foreach ($wanted_contexts as $unqualified_context_id => $context) { + $context_id = '@' . $service_id . ':' . $unqualified_context_id; + $this->contexts[$context_id] = $contexts[$context_id] = $context; + } + } + + return $contexts; + } + } diff --git a/src/Context/PageContextRepositoryInterface.php b/src/Context/PageContextRepositoryInterface.php index 46c6826..934afe3 100644 --- a/src/Context/PageContextRepositoryInterface.php +++ b/src/Context/PageContextRepositoryInterface.php @@ -18,6 +18,16 @@ /** * @todo. * + * @param array $context_ids + * @param \Drupal\page_manager\PageInterface $page + * + * @return + */ + public function getRuntimePageOnlyContexts(array $context_ids, PageInterface $page); + + /** + * @todo. + * * @param \Drupal\page_manager\PageInterface $page * * @return diff --git a/src/ContextProvider/PageVariantContextProviderInterface.php b/src/ContextProvider/PageVariantContextProviderInterface.php index 4dcbe15..b8850be 100644 --- a/src/ContextProvider/PageVariantContextProviderInterface.php +++ b/src/ContextProvider/PageVariantContextProviderInterface.php @@ -41,4 +41,13 @@ public function getAvailableContexts(PageVariantInterface $page_variant = NULL); */ public function getAvailablePageOnlyContexts(PageInterface $page); + /** + * @todo. + * + * @param \Drupal\page_manager\PageInterface $page + * + * @return + */ + public function getRuntimePageOnlyContexts(array $unqualified_context_ids, PageInterface $page); + } diff --git a/src/ContextProvider/RouteParamContext.php b/src/ContextProvider/RouteParamContext.php index 975487f..5a44550 100644 --- a/src/ContextProvider/RouteParamContext.php +++ b/src/ContextProvider/RouteParamContext.php @@ -110,4 +110,11 @@ public function getAvailablePageOnlyContexts(PageInterface $page) { return $this->getPageContexts($page); } + /** + * {@inheritdoc} + */ + public function getRuntimePageOnlyContexts(array $unqualified_context_ids, PageInterface $page) { + return $this->getPageContexts($page); + } + } diff --git a/src/ContextProvider/StaticContextProvider.php b/src/ContextProvider/StaticContextProvider.php index 104dcf1..7a82882 100644 --- a/src/ContextProvider/StaticContextProvider.php +++ b/src/ContextProvider/StaticContextProvider.php @@ -56,4 +56,11 @@ public function getAvailablePageOnlyContexts(PageInterface $page) { return []; } + /** + * {@inheritdoc} + */ + public function getRuntimePageOnlyContexts(array $unqualified_context_ids, PageInterface $page) { + return []; + } + } diff --git a/src/Entity/Page.php b/src/Entity/Page.php index 43b586c..000b562 100644 --- a/src/Entity/Page.php +++ b/src/Entity/Page.php @@ -285,9 +285,9 @@ protected function filterParameters() { /** * {@inheritdoc} */ - public function getRuntimeContexts(array $context_ids = []) { - $context_ids = array_unique($context_ids + $this->getAllContextMappingIds($this)); - return $this->contextRepository()->getRuntimeContexts($context_ids); + public function getRuntimeContexts() { + $context_ids = $this->getAllContextMappingIds($this); + return $this->contextRepository()->getRuntimePageOnlyContexts($context_ids, $this); } /** diff --git a/src/PageInterface.php b/src/PageInterface.php index 6a3644b..d5a6c10 100644 --- a/src/PageInterface.php +++ b/src/PageInterface.php @@ -179,15 +179,12 @@ public function getParameterNames(); /** * Gets runtime context values for all defined contexts. * - * @param array $context_ids - * (optional) An array of unqualified context IDs. - * * @return \Drupal\Core\Plugin\Context\ContextInterface[] * An array of set context values, keyed by context name. * * @see \Drupal\Core\Plugin\Context\ContextProviderInterface::getRuntimeContexts() */ - public function getRuntimeContexts(array $context_ids = []); + public function getRuntimeContexts(); /** * Gets all available contexts for the purposes of configuration. diff --git a/tests/src/Unit/PageTest.php b/tests/src/Unit/PageTest.php index 00d58c8..5589d94 100644 --- a/tests/src/Unit/PageTest.php +++ b/tests/src/Unit/PageTest.php @@ -13,7 +13,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Plugin\Context\Context; use Drupal\Core\Plugin\Context\ContextDefinition; -use Drupal\Core\Plugin\Context\ContextRepositoryInterface; +use Drupal\page_manager\Context\PageContextRepositoryInterface; use Drupal\page_manager\Entity\Page; use Drupal\page_manager\PageVariantInterface; use Drupal\Tests\UnitTestCase; @@ -78,8 +78,8 @@ public function testGetVariants() { public function testGetRuntimeContexts() { $context = new Context(new ContextDefinition('bar')); - $context_repository = $this->prophesize(ContextRepositoryInterface::class); - $context_repository->getRuntimeContexts([])->willReturn(['foo' => $context]); + $context_repository = $this->prophesize(PageContextRepositoryInterface::class); + $context_repository->getRuntimePageOnlyContexts([], $this->page)->willReturn(['foo' => $context]); $condition_plugin_manager = $this->prophesize(PluginManagerInterface::class); diff --git a/tests/src/Unit/PageVariantTest.php b/tests/src/Unit/PageVariantTest.php index ed915a5..43d177e 100644 --- a/tests/src/Unit/PageVariantTest.php +++ b/tests/src/Unit/PageVariantTest.php @@ -9,7 +9,7 @@ use Drupal\Component\Plugin\PluginManagerInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; -use Drupal\Core\Plugin\Context\ContextRepositoryInterface; +use Drupal\page_manager\Context\PageContextRepositoryInterface; use Drupal\page_manager\Entity\PageVariant; use Drupal\Tests\UnitTestCase; @@ -31,7 +31,7 @@ class PageVariantTest extends UnitTestCase { protected $page; /** - * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface|\Prophecy\Prophecy\ProphecyInterface + * @var \Drupal\page_manager\Context\PageContextRepositoryInterface|\Prophecy\Prophecy\ProphecyInterface */ protected $contextRepository; @@ -43,7 +43,7 @@ protected function setUp() { $this->pageVariant = new PageVariant(['id' => 'the_page_variant', 'page' => 'the_page'], 'page_variant'); - $this->contextRepository = $this->prophesize(ContextRepositoryInterface::class); + $this->contextRepository = $this->prophesize(PageContextRepositoryInterface::class); $condition_plugin_manager = $this->prophesize(PluginManagerInterface::class); $display_variant_plugin_manager = $this->prophesize(PluginManagerInterface::class);