This repository has been archived by the owner on Jan 5, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Media Context and Media Bundle Condition plugins.
- Loading branch information
1 parent
c2eef44
commit 4a8b1df
Showing
7 changed files
with
409 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
namespace Drupal\media_entity\ContextProvider; | ||
|
||
use Drupal\Core\Cache\CacheableMetadata; | ||
use Drupal\Core\Plugin\Context\Context; | ||
use Drupal\Core\Plugin\Context\ContextDefinition; | ||
use Drupal\Core\Plugin\Context\ContextProviderInterface; | ||
use Drupal\Core\Routing\RouteMatchInterface; | ||
use Drupal\Core\StringTranslation\StringTranslationTrait; | ||
use Drupal\media\Entity\Media; | ||
|
||
/** | ||
* Sets the current media as a context on media routes. | ||
*/ | ||
class MediaRouteContext implements ContextProviderInterface { | ||
|
||
use StringTranslationTrait; | ||
|
||
/** | ||
* The route match object. | ||
* | ||
* @var \Drupal\Core\Routing\RouteMatchInterface | ||
*/ | ||
protected $routeMatch; | ||
|
||
/** | ||
* Constructs a new MediaRouteContext. | ||
* | ||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match | ||
* The route match object. | ||
*/ | ||
public function __construct(RouteMatchInterface $route_match) { | ||
$this->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]; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
<?php | ||
|
||
namespace Drupal\media_entity\Plugin\Condition; | ||
|
||
use Drupal\Core\Condition\ConditionPluginBase; | ||
use Drupal\Core\Entity\EntityStorageInterface; | ||
use Drupal\Core\Form\FormStateInterface; | ||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
|
||
/** | ||
* Provides a 'Media bundles' condition. | ||
* | ||
* @Condition( | ||
* id = "media_bundle", | ||
* label = @Translation("Media bundles"), | ||
* context = { | ||
* "media" = @ContextDefinition("entity:media", label = @Translation("Media")) | ||
* } | ||
* ) | ||
*/ | ||
class MediaBundle extends ConditionPluginBase implements ContainerFactoryPluginInterface { | ||
|
||
/** | ||
* The entity storage. | ||
* | ||
* @var \Drupal\Core\Entity\EntityStorageInterface | ||
*/ | ||
protected $entityStorage; | ||
|
||
/** | ||
* Creates a new MediaBundle instance. | ||
* | ||
* @param \Drupal\Core\Entity\EntityStorageInterface $entity_storage | ||
* The entity storage. | ||
* @param array $configuration | ||
* The plugin configuration, i.e. an array with configuration values keyed | ||
* by configuration option name. The special key 'context' may be used to | ||
* initialize the defined contexts by setting it to an array of context | ||
* values keyed by context names. | ||
* @param string $plugin_id | ||
* The plugin_id for the plugin instance. | ||
* @param mixed $plugin_definition | ||
* The plugin implementation definition. | ||
*/ | ||
public function __construct(EntityStorageInterface $entity_storage, array $configuration, $plugin_id, $plugin_definition) { | ||
parent::__construct($configuration, $plugin_id, $plugin_definition); | ||
$this->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(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
<?php | ||
|
||
namespace Drupal\media_entity\Tests; | ||
|
||
use Drupal\Component\Utility\Xss; | ||
use Drupal\simpletest\WebTestBase; | ||
|
||
/** | ||
* Ensures that media context & media bundle condition work correctly. | ||
* | ||
* @group media_entity | ||
*/ | ||
class MediaContextConditionTest extends WebTestBase { | ||
|
||
use MediaTestTrait; | ||
|
||
/** | ||
* The test user. | ||
* | ||
* @var \Drupal\User\UserInterface | ||
*/ | ||
protected $adminUser; | ||
|
||
/** | ||
* A non-admin test user. | ||
* | ||
* @var \Drupal\User\UserInterface | ||
*/ | ||
protected $nonAdminUser; | ||
|
||
/** | ||
* Modules to enable. | ||
* | ||
* @var array | ||
*/ | ||
public static $modules = ['media_entity', 'media_entity_test_context', 'field_ui', 'views_ui', 'node', 'block', 'entity']; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function setUp() { | ||
parent::setUp(); | ||
$this->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; | ||
} | ||
|
||
} |
6 changes: 6 additions & 0 deletions
6
tests/modules/media_entity_test_context/media_entity_test_context.info.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.