/** * @covers ::getContexts * @covers ::removeStaticContext */ public function testGetContextsAfterReset() { $this->contextMapper->getContextValues([])->willReturn([])->shouldBeCalledTimes(2); $this->page->getContexts()->willReturn([])->shouldBeCalledTimes(2); $expected = []; $contexts = $this->pageVariant->getContexts(); $this->assertSame($expected, $contexts); $this->pageVariant->removeStaticContext('anything'); $contexts = $this->pageVariant->getContexts(); $this->assertSame($expected, $contexts); }
/** * {@inheritdoc} */ protected function setUp() { parent::setUp(); ConfigurableLanguage::createFromLangcode('de')->save(); $this->drupalLogin($this->drupalCreateUser(['administer site configuration', 'translate configuration'])); PageVariant::create(['variant' => 'http_status_code', 'label' => 'HTTP status code', 'id' => 'http_status_code', 'page' => 'node_view'])->save(); }
/** * Tests whether the page entity config schema is valid. */ public function testValidPageConfigSchema() { $id = 'node_view'; /** @var \Drupal\page_manager\PageInterface $page */ $page = Page::load($id); // Add an access condition. $page->addAccessCondition(['id' => 'node_type', 'bundles' => ['article' => 'article'], 'negate' => TRUE, 'context_mapping' => ['node' => 'node']]); $page->save(); $page_variant_id = 'block_page'; // Add a block variant. $page_variant = PageVariant::create(['variant' => 'block_display', 'id' => $page_variant_id, 'label' => 'Block page', 'page' => $page->id()]); $page_variant->save(); $page->addVariant($page_variant); /** @var \Drupal\page_manager\Plugin\DisplayVariant\PageBlockDisplayVariant $variant_plugin */ $variant_plugin = $page_variant->getVariantPlugin(); // Add a selection condition. $page_variant->addSelectionCondition(['id' => 'node_type', 'bundles' => ['page' => 'page'], 'context_mapping' => ['node' => 'node']]); // Add a block. $variant_plugin->addBlock(['id' => 'entity_view:node', 'label' => 'View the node', 'provider' => 'page_manager', 'label_display' => 'visible', 'view_mode' => 'default']); $page_variant->save(); $page_config = \Drupal::config("page_manager.page.{$id}"); $this->assertSame($page_config->get('id'), $id); $variant_config = \Drupal::config("page_manager.page_variant.{$page_variant_id}"); $this->assertSame($variant_config->get('id'), $page_variant_id); $this->assertConfigSchema(\Drupal::service('config.typed'), $page_config->getName(), $page_config->get()); $this->assertConfigSchema(\Drupal::service('config.typed'), $variant_config->getName(), $variant_config->get()); }
/** * Tests that a node bundle condition controls the node view page. */ public function testAdmin() { // Create two nodes, and view their pages. $node1 = $this->drupalCreateNode(['type' => 'page']); $node2 = $this->drupalCreateNode(['type' => 'article']); $node3 = $this->drupalCreateNode(['type' => 'article']); $this->drupalGet('node/' . $node1->id()); $this->assertResponse(200); $this->assertText($node1->label()); $this->assertTitle($node1->label() . ' | Drupal'); $this->drupalGet('node/' . $node2->id()); $this->assertResponse(200); $this->assertCacheTag('page_manager_route_name:entity.node.canonical'); $this->assertText($node2->label()); $this->assertTitle($node2->label() . ' | Drupal'); // Create a new variant to always return 404, the node_view page exists by // default. $http_status_variant = PageVariant::create(['variant' => 'http_status_code', 'label' => 'HTTP status code', 'id' => 'http_status_code', 'page' => 'node_view']); $http_status_variant->getVariantPlugin()->setConfiguration(['status_code' => 404]); $http_status_variant->save(); $this->triggerRouterRebuild(); $this->drupalGet('node/' . $node1->id()); $this->assertResponse(404); $this->assertCacheTag('page_manager_route_name:entity.node.canonical'); $this->assertNoText($node1->label()); $this->drupalGet('node/' . $node2->id()); $this->assertResponse(404); $this->assertNoText($node2->label()); // Add a new variant. /** @var \Drupal\page_manager\PageVariantInterface $block_page_variant */ $block_page_variant = PageVariant::create(['variant' => 'block_display', 'id' => 'block_page_first', 'label' => 'First', 'page' => 'node_view']); $block_page_plugin = $block_page_variant->getVariantPlugin(); $block_page_plugin->setConfiguration(['page_title' => '[node:title]']); /** @var \Drupal\page_manager\Plugin\DisplayVariant\PageBlockDisplayVariant $block_page_plugin */ $block_page_plugin->addBlock(['id' => 'entity_view:node', 'label' => 'Entity view (Content)', 'label_display' => FALSE, 'view_mode' => 'default', 'region' => 'top', 'context_mapping' => ['entity' => 'node']]); $block_page_variant->addSelectionCondition(['id' => 'node_type', 'bundles' => ['article' => 'article'], 'context_mapping' => ['node' => 'node']]); $block_page_variant->setWeight(-10); $block_page_variant->save(); $this->triggerRouterRebuild(); // The page node will 404, but the article node will display the variant. $this->drupalGet('node/' . $node1->id()); $this->assertResponse(404); $this->assertNoText($node1->label()); $this->drupalGet('node/' . $node2->id()); $this->assertResponse(200); $this->assertTitle($node2->label() . ' | Drupal'); $this->assertText($node2->body->value); // Test cacheability metadata. $this->drupalGet('node/' . $node3->id()); $this->assertNoText($node2->label()); // Ensure this doesn't affect the /node/add page. $this->drupalGet('node/add'); $this->assertResponse(200); }
/** * Tests creating a Panels variant with the IPE. */ public function testPanelsIPE() { // Create new page. $this->drupalGet('admin/structure/page_manager/add'); $edit = ['id' => 'foo', 'label' => 'foo', 'path' => 'testing']; $this->drupalPostForm(NULL, $edit, 'Save'); // Add a Panels variant which uses the IPE. $this->clickLink('Add new variant'); $this->clickLink('Panels'); $edit = ['id' => 'panels_1', 'label' => 'Default', 'variant_settings[builder]' => 'ipe']; $this->drupalPostForm(NULL, $edit, 'Save'); /** @var \Drupal\page_manager\PageVariantInterface $page_variant */ $page_variant = PageVariant::load('panels_1'); /** @var \Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant $panels_display */ $panels_display = $page_variant->getVariantPlugin(); // Make sure the storage type and id were set to the right value. $this->assertEqual($panels_display->getStorageType(), 'page_manager'); $this->assertEqual($panels_display->getStorageId(), 'panels_1'); }
/** * Tests that overriding the node page does not prevent translation. */ public function testNode() { $this->drupalPlaceBlock('local_tasks_block'); $this->drupalPlaceBlock('page_title_block'); $node = $this->drupalCreateNode(['type' => 'article']); $this->drupalGet('node/' . $node->id()); $this->assertResponse(200); $this->assertText($node->label()); $this->clickLink('Translate'); $this->assertResponse(200); // Create a new variant. $http_status_variant = PageVariant::create(['variant' => 'http_status_code', 'label' => 'HTTP status code', 'id' => 'http_status_code', 'page' => 'node_view']); $http_status_variant->getVariantPlugin()->setConfiguration(['status_code' => 200]); $http_status_variant->save(); $this->triggerRouterRebuild(); $this->drupalGet('node/' . $node->id()); $this->assertResponse(200); $this->clickLink('Translate'); $this->assertResponse(200); }
/** * Tests that a node bundle condition controls the node view page. */ public function testPagePlaceHolder() { // Access the page callback and check whether string is printed. $page_string = 'test-page'; $this->drupalGet('page-manager-test/' . $page_string); $this->assertResponse(200); $this->assertCacheTag('page_manager_route_name:page_manager_test.page_view'); $this->assertText('Hello World! Page ' . $page_string); // Create a new page entity with the same path as in the test module. $page = Page::create(['label' => 'Placeholder test', 'id' => 'placeholder', 'path' => '/page-manager-test/%']); $page->save(); // Create a new variant. $http_status_variant = PageVariant::create(['variant' => 'http_status_code', 'label' => 'HTTP status code', 'id' => 'http_status_code', 'page' => 'placeholder']); $http_status_variant->getVariantPlugin()->setConfiguration(['status_code' => 200]); $http_status_variant->save(); $this->triggerRouterRebuild(); // Access the page callback again and check that now the text is not there. $this->drupalGet('page-manager-test/' . $page_string); $this->assertResponse(200); $this->assertCacheTag('page_manager_route_name:page_manager_test.page_view'); $this->assertNoText('Hello World! Page ' . $page_string); }
/** * Tests that a user role condition controls the node view page. */ public function testUserRoleAccessCondition() { $node1 = $this->drupalCreateNode(['type' => 'page']); $node2 = $this->drupalCreateNode(['type' => 'article']); $this->drupalLogin($this->drupalCreateUser(['access content'])); $this->drupalGet('node/' . $node1->id()); $this->assertResponse(200); $this->assertText($node1->label()); $this->assertTitle($node1->label() . ' | Drupal'); // Add a variant and an access condition. /** @var \Drupal\page_manager\Entity\PageVariant $page_variant */ $page_variant = PageVariant::create(['variant' => 'block_display', 'id' => 'block_page', 'label' => 'Block page', 'page' => $this->page->id()]); $page_variant->getVariantPlugin()->setConfiguration(['page_title' => 'The overridden page']); $page_variant->save(); $this->page->addAccessCondition(['id' => 'user_role', 'roles' => [RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID], 'context_mapping' => ['user' => 'current_user']]); $this->page->addAccessCondition(['id' => 'node_type', 'bundles' => ['page' => 'page'], 'context_mapping' => ['node' => 'node']]); $this->page->save(); $this->triggerRouterRebuild(); $this->drupalLogout(); $this->drupalGet('node/' . $node1->id()); $this->assertResponse(403); $this->assertNoText($node1->label()); $this->assertTitle('Access denied | Drupal'); $this->drupalLogin($this->drupalCreateUser()); $this->drupalGet('node/' . $node1->id()); $this->assertResponse(403); $this->assertNoText($node1->label()); $this->assertTitle('Access denied | Drupal'); $this->drupalLogin($this->drupalCreateUser(['access content'])); $this->drupalGet('node/' . $node1->id()); $this->assertResponse(200); $this->assertNoText($node1->label()); $this->assertTitle('The overridden page | Drupal'); $this->drupalGet('node/' . $node2->id()); $this->assertResponse(403); $this->assertNoText($node2->label()); $this->assertTitle('Access denied | Drupal'); }
/** * Finds a block based on its variant and block label. * * @param string $page_variant_id * The ID of the page variant entity. * @param string $block_label * The label of the block. * * @return \Drupal\Core\Block\BlockPluginInterface|null * Either a block plugin, or NULL. */ protected function findBlockByLabel($page_variant_id, $block_label) { if ($page_variant = PageVariant::load($page_variant_id)) { /** @var \Drupal\ctools\Plugin\BlockVariantInterface $variant_plugin */ $variant_plugin = $page_variant->getVariantPlugin(); foreach ($variant_plugin->getRegionAssignments() as $blocks) { /** @var \Drupal\Core\Block\BlockPluginInterface[] $blocks */ foreach ($blocks as $block) { if ($block->label() == $block_label) { return $block; } } } } return NULL; }
/** * {@inheritdoc} */ public function build(array $regions, array $contexts, LayoutInterface $layout = NULL) { // Load our PageVariant. /** @var \Drupal\page_manager\PageVariantInterface $page_variant */ $page_variant = \Drupal::request()->attributes->get('page_manager_page_variant'); // Check to see if the current user has permissions to use the IPE. $has_permission = $this->account->hasPermission('access panels in-place editing'); // Attach the Panels In-place editor library based on permissions. if ($page_variant && $has_permission) { // This flag tracks whether or not there are unsaved changes. $unsaved = FALSE; // If a temporary configuration for this variant exists, use it. $temp_store_key = 'variant.' . $page_variant->id(); if ($variant_config = $this->tempStore->get($temp_store_key)) { // Reload the PageVariant. This is required to set variant plugin // configuration correctly. $page_variant = PageVariant::load($page_variant->id()); /** @var \Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant $variant_plugin */ $variant_plugin = $page_variant->getVariantPlugin(); $variant_plugin->setConfiguration($variant_config); // Override our initial values with what's in TempStore. $layout = $variant_plugin->getLayout(); $regions = $variant_plugin->getRegionAssignments(); // Indicate that the user is viewing un-saved changes. $unsaved = TRUE; } $build = parent::build($regions, $contexts, $layout); foreach ($regions as $region => $blocks) { // Wrap each region with a unique class and data attribute. $region_name = Html::getClass("block-region-{$region}"); $build[$region]['#prefix'] = '<div class="' . $region_name . '" data-region-name="' . $region . '">'; $build[$region]['#suffix'] = '</div>'; if ($blocks) { foreach ($blocks as $block_id => $block) { $build[$region][$block_id]['#attributes']['data-block-id'] = $block_id; } } } // Attach the required settings and IPE. $build['#attached']['library'][] = 'panels_ipe/panels_ipe'; $build['#attached']['drupalSettings']['panels_ipe'] = $this->getDrupalSettings($regions, $layout, $page_variant); // Add our custom elements to the build. $build['#prefix'] = '<div id="panels-ipe-content">'; // Indicate if the current user is viewing temp store. $tray_classes = $unsaved ? 'unsaved' : ''; $build['#suffix'] = '</div><div id="panels-ipe-tray" class="' . $tray_classes . '"></div>'; } else { $build = parent::build($regions, $contexts, $layout); } return $build; }
/** * Loads or creates a Block Plugin instance suitable for rendering or testing. * * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. * * @return \Drupal\Core\Block\BlockBase * The Block Plugin instance. */ protected function getBlockInstance($form_state) { /** @var \Drupal\page_manager\PageVariantInterface $page_variant */ $page_variant = PageVariant::load($form_state->getValue('variant_id')); // If a UUID is provided, the Block should already exist. if ($uuid = $form_state->getValue('uuid')) { /** @var \Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant $variant_plugin */ $variant_plugin = $page_variant->getVariantPlugin(); // If a temporary configuration for this variant exists, use it. $temp_store_key = 'variant.' . $page_variant->id(); if ($variant_config = $this->tempStore->get($temp_store_key)) { $variant_plugin->setConfiguration($variant_config); } // Load the existing Block instance. $block_instance = $variant_plugin->getBlock($uuid); } else { // Create an instance of this Block plugin. /** @var \Drupal\Core\Block\BlockBase $block_instance */ $block_instance = $this->blockManager->createInstance($form_state->getValue('plugin_id')); } // Add context to the block. if ($block_instance instanceof ContextAwarePluginInterface) { $this->contextHandler->applyContextMapping($block_instance, $page_variant->getContexts()); } return $block_instance; }