From ffa06fb6d42022273ce86d88b675e82a3b8096c0 Mon Sep 17 00:00:00 2001 From: Steve Oliver Date: Mon, 1 Aug 2016 15:53:33 -0700 Subject: [PATCH] Add Media Context and Media Bundle Condition plugins. --- config/schema/media_entity.schema.yml | 9 + media_entity.services.yml | 5 + src/ContextProvider/MediaRouteContext.php | 72 ++++++++ src/Plugin/Condition/MediaBundle.php | 121 +++++++++++++ src/Tests/MediaContextConditionTest.php | 164 ++++++++++++++++++ .../media_entity_test_context.info.yml | 6 + .../Block/TestMediaContextAwareBlock.php | 33 ++++ 7 files changed, 410 insertions(+) create mode 100644 src/ContextProvider/MediaRouteContext.php create mode 100644 src/Plugin/Condition/MediaBundle.php create mode 100644 src/Tests/MediaContextConditionTest.php create mode 100644 tests/modules/media_entity_test_context/media_entity_test_context.info.yml create mode 100644 tests/modules/media_entity_test_context/src/Plugin/Block/TestMediaContextAwareBlock.php diff --git a/config/schema/media_entity.schema.yml b/config/schema/media_entity.schema.yml index 1c1f720..c67a535 100644 --- a/config/schema/media_entity.schema.yml +++ b/config/schema/media_entity.schema.yml @@ -57,6 +57,14 @@ action.configuration.media_unpublish_action: type: action_configuration_default label: 'Unpublish media configuration' +condition.plugin.media_bundle: + type: condition.plugin + mapping: + bundles: + type: sequence + sequence: + type: string + field.formatter.settings.media_thumbnail: type: mapping label: 'Media thumbnail field display format settings' @@ -67,3 +75,4 @@ field.formatter.settings.media_thumbnail: image_style: type: string label: 'Image style' + diff --git a/media_entity.services.yml b/media_entity.services.yml index a227b73..ba63491 100644 --- a/media_entity.services.yml +++ b/media_entity.services.yml @@ -2,3 +2,8 @@ services: plugin.manager.media_entity.type: class: Drupal\media_entity\MediaTypeManager parent: default_plugin_manager + media_entity.media_bundle_context: + class: Drupal\media_entity\ContextProvider\MediaRouteContext + arguments: ['@current_route_match'] + tags: + - { name: 'context_provider' } diff --git a/src/ContextProvider/MediaRouteContext.php b/src/ContextProvider/MediaRouteContext.php new file mode 100644 index 0000000..f07017c --- /dev/null +++ b/src/ContextProvider/MediaRouteContext.php @@ -0,0 +1,72 @@ +routeMatch = $route_match; + } + + /** + * {@inheritdoc} + */ + public function getRuntimeContexts(array $unqualified_context_ids) { + $result = []; + $context_definition = new ContextDefinition('entity:media', NULL, FALSE); + $value = NULL; + if (($route_object = $this->routeMatch->getRouteObject()) && ($route_contexts = $route_object->getOption('parameters')) && isset($route_contexts['media'])) { + if ($media = $this->routeMatch->getParameter('media')) { + $value = $media; + } + } + elseif ($this->routeMatch->getRouteName() == 'media.add') { + $media_type = $this->routeMatch->getParameter('media_bundle'); + $value = Media::create(array('type' => $media_type->id())); + } + + $cacheability = new CacheableMetadata(); + $cacheability->setCacheContexts(['route']); + + $context = new Context($context_definition, $value); + $context->addCacheableDependency($cacheability); + $result['media'] = $context; + + return $result; + } + + /** + * {@inheritdoc} + */ + public function getAvailableContexts() { + $context = new Context(new ContextDefinition('entity:media', $this->t('Media from URL'))); + return ['media' => $context]; + } + +} diff --git a/src/Plugin/Condition/MediaBundle.php b/src/Plugin/Condition/MediaBundle.php new file mode 100644 index 0000000..4964e17 --- /dev/null +++ b/src/Plugin/Condition/MediaBundle.php @@ -0,0 +1,121 @@ +entityStorage = $entity_storage; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $container->get('entity.manager')->getStorage('media_bundle'), + $configuration, + $plugin_id, + $plugin_definition + ); + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $options = array(); + $media_types = $this->entityStorage->loadMultiple(); + foreach ($media_types as $type) { + $options[$type->id()] = $type->label(); + } + $form['bundles'] = array( + '#title' => $this->t('Media bundles'), + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => $this->configuration['bundles'], + ); + return parent::buildConfigurationForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + $this->configuration['bundles'] = array_filter($form_state->getValue('bundles')); + parent::submitConfigurationForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function summary() { + if (count($this->configuration['bundles']) > 1) { + $bundles = $this->configuration['bundles']; + $last = array_pop($bundles); + $bundles = implode(', ', $bundles); + return $this->t('The media bundle is @bundles or @last', array('@bundles' => $bundles, '@last' => $last)); + } + $bundle = reset($this->configuration['bundles']); + return $this->t('The media bundle is @bundle', array('@bundle' => $bundle)); + } + + /** + * {@inheritdoc} + */ + public function evaluate() { + if (empty($this->configuration['bundles']) && !$this->isNegated()) { + return TRUE; + } + $media = $this->getContextValue('media'); + return !empty($this->configuration['bundles'][$media->bundle()]); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return array('bundles' => array()) + parent::defaultConfiguration(); + } + +} diff --git a/src/Tests/MediaContextConditionTest.php b/src/Tests/MediaContextConditionTest.php new file mode 100644 index 0000000..08d8536 --- /dev/null +++ b/src/Tests/MediaContextConditionTest.php @@ -0,0 +1,164 @@ +drupalPlaceBlock('local_actions_block'); + $this->drupalPlaceBlock('local_tasks_block'); + $this->adminUser = $this->drupalCreateUser([ + 'administer media', + 'administer media fields', + 'administer media form display', + 'administer media display', + 'administer media bundles', + // Media entity permissions. + 'view media', + 'create media', + 'update media', + 'update any media', + 'delete media', + 'delete any media', + 'access media overview', + // Other permissions. + 'access administration pages', + 'administer blocks', + 'administer views', + 'access content overview', + 'view all revisions', + ]); + $this->drupalLogin($this->adminUser); + } + + /** + * Tests the behavior of media context-aware blocks. + */ + public function testMediaContextAwareBlocks() { + $bundle = $this->createMediaBundle(); + $media = $this->createMediaItem($bundle); + $expected_text = 'Media ID: ' . $media['id']; + + $this->drupalGet(''); + $this->assertNoText('Test media context aware block'); + $this->assertNoRaw($expected_text); + + $block_url = 'admin/structure/block/add/test_media_context_block/classy'; + $arguments = array( + ':title' => 'Test media context aware block', + ':category' => 'Media entity test context', + ':href' => $block_url, + ); + $pattern = '//tr[.//td/div[text()=:title] and .//td[text()=:category] and .//td//a[contains(@href, :href)]]'; + + $this->drupalGet('admin/structure/block'); + $this->clickLinkPartialName('Place block'); + $elements = $this->xpath($pattern, $arguments); + $this->assertTrue(!empty($elements), 'The media context-aware test block appears.'); + $definition = \Drupal::service('plugin.manager.block')->getDefinition('test_media_context_block'); + $this->assertTrue(!empty($definition), 'The media context-aware test block definition exists.'); + $edit = [ + 'region' => 'content', + 'visibility[media_bundle][bundles][' . $bundle['id'] . ']' => TRUE + ]; + $this->drupalPostForm($block_url, $edit, 'Save block'); + + $this->drupalGet(''); + $this->assertNoText('Test media context aware block', 'Block not found because condition not met (bundle: ' . $bundle['id'] . ').'); + + $this->drupalGet('media/' . $media['id']); + $this->assertText('Test media context aware block'); + $this->assertRaw($expected_text, 'Block found, with media context (condition met).'); + + } + + /** + * Creates and tests a new media bundle. + * + * @return array + * Returns the media bundle fields. + */ + public function createMediaBundle() { + // Generates and holds all media bundle fields. + $name = $this->randomMachineName(); + $edit = [ + 'id' => strtolower($name), + 'label' => $name, + 'type' => 'generic', + 'description' => $this->randomMachineName(), + ]; + + // Create new media bundle. + $this->drupalPostForm('admin/structure/media/add', $edit, t('Save media bundle')); + $this->assertText('The media bundle ' . $name . ' has been added.'); + + // Check if media bundle is successfully created. + $this->drupalGet('admin/structure/media'); + $this->assertResponse(200); + $this->assertRaw($edit['label']); + $this->assertRaw(Xss::filterAdmin($edit['description'])); + + return $edit; + } + + /** + * Creates a media item in the media bundle that is passed along. + * + * @param array $media_bundle + * The media bundle the media item should be assigned to. + * + * @return array + * Returns the + */ + public function createMediaItem($media_bundle) { + // Define the media item name. + $name = $this->randomMachineName(); + $edit = [ + 'name[0][value]' => $name, + ]; + // Save it and retrieve new media item ID, then return all information. + $this->drupalPostForm('media/add/' . $media_bundle['id'], $edit, t('Save and publish')); + $this->assertTitle($edit['name[0][value]'] . ' | Drupal'); + $media_id = \Drupal::entityQuery('media')->execute(); + $media_id = reset($media_id); + $edit['id'] = $media_id; + + return $edit; + } + +} diff --git a/tests/modules/media_entity_test_context/media_entity_test_context.info.yml b/tests/modules/media_entity_test_context/media_entity_test_context.info.yml new file mode 100644 index 0000000..0247510 --- /dev/null +++ b/tests/modules/media_entity_test_context/media_entity_test_context.info.yml @@ -0,0 +1,6 @@ +name: 'Media entity test context' +type: module +description: 'Provides test media context plugin to test context.' +core: 8.x +package: Testing +version: VERSION diff --git a/tests/modules/media_entity_test_context/src/Plugin/Block/TestMediaContextAwareBlock.php b/tests/modules/media_entity_test_context/src/Plugin/Block/TestMediaContextAwareBlock.php new file mode 100644 index 0000000..544e76b --- /dev/null +++ b/tests/modules/media_entity_test_context/src/Plugin/Block/TestMediaContextAwareBlock.php @@ -0,0 +1,33 @@ +getContextValue('media'); + $build = []; + // No media context found when not using a condition. + $build['media_id']['#markup'] = $media ? 'Media ID: ' . $media->id() : 'No media context found.'; + return $build; + } + +}