Issue #2195753 by tim.plunkett: Changes to config entities that use plugins are not propagated to the plugins.
parent
e0447089b2
commit
0230aa22a4
|
@ -101,11 +101,7 @@ class DefaultPluginBag extends PluginBag {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the current configuration of all plugins in this bag.
|
||||
*
|
||||
* @return array
|
||||
* An associative array keyed by instance ID, whose values are up-to-date
|
||||
* plugin configurations.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration() {
|
||||
$instances = array();
|
||||
|
@ -129,6 +125,16 @@ class DefaultPluginBag extends PluginBag {
|
|||
return $instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setConfiguration($configuration) {
|
||||
foreach ($configuration as $instance_id => $instance_configuration) {
|
||||
$this->setInstanceConfiguration($instance_id, $instance_configuration);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -149,7 +155,7 @@ class DefaultPluginBag extends PluginBag {
|
|||
* @param array $configuration
|
||||
* The plugin configuration to set.
|
||||
*/
|
||||
public function setConfiguration($instance_id, array $configuration) {
|
||||
public function setInstanceConfiguration($instance_id, array $configuration) {
|
||||
$this->configurations[$instance_id] = $configuration;
|
||||
$instance = $this->get($instance_id);
|
||||
if ($instance instanceof ConfigurablePluginInterface) {
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
namespace Drupal\Component\Plugin;
|
||||
|
||||
use Drupal\Component\Utility\MapArray;
|
||||
|
||||
/**
|
||||
* Provides a default plugin bag for a plugin type.
|
||||
*
|
||||
|
@ -34,19 +32,28 @@ class DefaultSinglePluginBag extends PluginBag {
|
|||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* The instance ID used for this plugin bag.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $instanceId;
|
||||
|
||||
/**
|
||||
* Constructs a new DefaultSinglePluginBag object.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\PluginManagerInterface $manager
|
||||
* The manager to be used for instantiating plugins.
|
||||
* @param array $instance_ids
|
||||
* The IDs of the plugin instances with which we are dealing.
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance.
|
||||
* @param array $configuration
|
||||
* An array of configuration.
|
||||
*/
|
||||
public function __construct(PluginManagerInterface $manager, array $instance_ids, array $configuration) {
|
||||
public function __construct(PluginManagerInterface $manager, $instance_id, array $configuration) {
|
||||
$this->manager = $manager;
|
||||
$this->instanceIDs = MapArray::copyValuesToKeys($instance_ids);
|
||||
$this->instanceId = $instance_id;
|
||||
// This is still needed by the parent PluginBag class.
|
||||
$this->instanceIDs = array($instance_id => $instance_id);
|
||||
$this->configuration = $configuration;
|
||||
}
|
||||
|
||||
|
@ -57,4 +64,29 @@ class DefaultSinglePluginBag extends PluginBag {
|
|||
$this->set($instance_id, $this->manager->createInstance($instance_id, $this->configuration));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration() {
|
||||
$plugin = $this->get($this->instanceId);
|
||||
if ($plugin instanceof ConfigurablePluginInterface) {
|
||||
return $plugin->getConfiguration();
|
||||
}
|
||||
else {
|
||||
return $this->configuration;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setConfiguration($configuration) {
|
||||
$plugin = $this->get($this->instanceId);
|
||||
if ($plugin instanceof ConfigurablePluginInterface) {
|
||||
$plugin->setConfiguration($configuration);
|
||||
}
|
||||
$this->configuration = $configuration;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,24 @@ abstract class PluginBag implements \Iterator, \Countable {
|
|||
*/
|
||||
abstract protected function initializePlugin($instance_id);
|
||||
|
||||
/**
|
||||
* Returns the current configuration of all plugins in this bag.
|
||||
*
|
||||
* @return array
|
||||
* An array of up-to-date plugin configuration.
|
||||
*/
|
||||
abstract public function getConfiguration();
|
||||
|
||||
/**
|
||||
* Sets the configuration for all plugins in this bag.
|
||||
*
|
||||
* @param array $configuration
|
||||
* An array of up-to-date plugin configuration.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
abstract public function setConfiguration($configuration);
|
||||
|
||||
/**
|
||||
* Clears all instantiated plugins.
|
||||
*/
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Action;
|
||||
|
||||
use Drupal\Component\Plugin\PluginInspectionInterface;
|
||||
use Drupal\Core\Executable\ExecutableInterface;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +16,7 @@ use Drupal\Core\Executable\ExecutableInterface;
|
|||
* @see \Drupal\Core\Annotation\Action
|
||||
* @see \Drupal\Core\Action\ActionManager
|
||||
*/
|
||||
interface ActionInterface extends ExecutableInterface {
|
||||
interface ActionInterface extends ExecutableInterface, PluginInspectionInterface {
|
||||
|
||||
/**
|
||||
* Executes the plugin for an array of objects.
|
||||
|
|
|
@ -27,6 +27,20 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
|
|||
*/
|
||||
protected $originalId;
|
||||
|
||||
/**
|
||||
* The name of the property that is used to store plugin configuration.
|
||||
*
|
||||
* This is needed when the entity utilizes a PluginBag, to dictate where the
|
||||
* plugin configuration should be stored.
|
||||
*
|
||||
* @todo Move this to a trait along with
|
||||
* \Drupal\Core\Config\Entity\EntityWithPluginBagInterface, and give it a
|
||||
* default value of 'configuration'.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $pluginConfigKey;
|
||||
|
||||
/**
|
||||
* The enabled/disabled status of the configuration entity.
|
||||
*
|
||||
|
@ -101,6 +115,15 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function set($property_name, $value) {
|
||||
// @todo When \Drupal\Core\Config\Entity\EntityWithPluginBagInterface moves
|
||||
// to a trait, switch to class_uses() instead.
|
||||
if ($this instanceof EntityWithPluginBagInterface) {
|
||||
if ($property_name == $this->pluginConfigKey) {
|
||||
// If external code updates the settings, pass it along to the plugin.
|
||||
$this->getPluginBag()->setConfiguration($value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->{$property_name} = $value;
|
||||
}
|
||||
|
||||
|
@ -192,6 +215,14 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface
|
|||
public function preSave(EntityStorageControllerInterface $storage_controller) {
|
||||
parent::preSave($storage_controller);
|
||||
|
||||
// @todo When \Drupal\Core\Config\Entity\EntityWithPluginBagInterface moves
|
||||
// to a trait, switch to class_uses() instead.
|
||||
if ($this instanceof EntityWithPluginBagInterface) {
|
||||
// Any changes to the plugin configuration must be saved to the entity's
|
||||
// copy as well.
|
||||
$this->set($this->pluginConfigKey, $this->getPluginBag()->getConfiguration());
|
||||
}
|
||||
|
||||
// Ensure this entity's UUID does not exist with a different ID, regardless
|
||||
// of whether it's new or updated.
|
||||
$matching_entities = $storage_controller->getQuery()
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Config\Entity\EntityWithPluginBagInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Config\Entity;
|
||||
|
||||
/**
|
||||
* Provides an interface for an object utilizing a plugin bag.
|
||||
*
|
||||
* @see \Drupal\Component\Plugin\PluginBag
|
||||
*
|
||||
* @todo Turn this into a trait.
|
||||
*/
|
||||
interface EntityWithPluginBagInterface extends ConfigEntityInterface {
|
||||
|
||||
/**
|
||||
* Returns the plugin bag used by this entity.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\PluginBag
|
||||
*
|
||||
* @todo Make this protected.
|
||||
*/
|
||||
public function getPluginBag();
|
||||
|
||||
}
|
|
@ -359,15 +359,7 @@ class EntityFormController extends FormBase implements EntityFormControllerInter
|
|||
// controller of the current request.
|
||||
$form_state['controller'] = $this;
|
||||
|
||||
// Copy top-level form values to entity properties, without changing
|
||||
// existing entity properties that are not being edited by
|
||||
// this form.
|
||||
// @todo: This relies on a method that only exists for config and content
|
||||
// entities, in a different way. Consider moving this logic to a config
|
||||
// entity specific implementation.
|
||||
foreach ($form_state['values'] as $key => $value) {
|
||||
$entity->set($key, $value);
|
||||
}
|
||||
$this->copyFormValuesToEntity($entity, $form_state);
|
||||
|
||||
// Invoke all specified builders for copying form values to entity
|
||||
// properties.
|
||||
|
@ -380,6 +372,26 @@ class EntityFormController extends FormBase implements EntityFormControllerInter
|
|||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies top-level form values to entity properties
|
||||
*
|
||||
* This should not change existing entity properties that are not being edited
|
||||
* by this form.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity the current form should operate upon.
|
||||
* @param array $form_state
|
||||
* An associative array containing the current state of the form.
|
||||
*/
|
||||
protected function copyFormValuesToEntity(EntityInterface $entity, array $form_state) {
|
||||
// @todo: This relies on a method that only exists for config and content
|
||||
// entities, in a different way. Consider moving this logic to a config
|
||||
// entity specific implementation.
|
||||
foreach ($form_state['values'] as $key => $value) {
|
||||
$entity->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -108,6 +108,10 @@ abstract class BlockBase extends PluginBase implements BlockPluginInterface {
|
|||
'#default_value' => ($this->configuration['label_display'] === BlockInterface::BLOCK_LABEL_VISIBLE),
|
||||
'#return_value' => BlockInterface::BLOCK_LABEL_VISIBLE,
|
||||
);
|
||||
$form['cache'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $this->configuration['cache'],
|
||||
);
|
||||
|
||||
// Add plugin-specific settings for this block type.
|
||||
$form += $this->blockForm($form, $form_state);
|
||||
|
|
|
@ -25,10 +25,19 @@ class BlockPluginBag extends DefaultSinglePluginBag {
|
|||
protected $blockId;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Constructs a new BlockPluginBag.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\PluginManagerInterface $manager
|
||||
* The manager to be used for instantiating plugins.
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance.
|
||||
* @param array $configuration
|
||||
* An array of configuration.
|
||||
* @param string $block_id
|
||||
* The unique ID of the block entity using this plugin.
|
||||
*/
|
||||
public function __construct(PluginManagerInterface $manager, array $instance_ids, array $configuration, $block_id) {
|
||||
parent::__construct($manager, $instance_ids, $configuration);
|
||||
public function __construct(PluginManagerInterface $manager, $instance_id, array $configuration, $block_id) {
|
||||
parent::__construct($manager, $instance_id, $configuration);
|
||||
|
||||
$this->blockId = $block_id;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Drupal\block\Entity;
|
|||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\block\BlockPluginBag;
|
||||
use Drupal\block\BlockInterface;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Config\Entity\EntityWithPluginBagInterface;
|
||||
|
||||
/**
|
||||
* Defines a Block configuration entity class.
|
||||
|
@ -40,7 +40,7 @@ use Drupal\Core\Entity\EntityStorageControllerInterface;
|
|||
* }
|
||||
* )
|
||||
*/
|
||||
class Block extends ConfigEntityBase implements BlockInterface {
|
||||
class Block extends ConfigEntityBase implements BlockInterface, EntityWithPluginBagInterface {
|
||||
|
||||
/**
|
||||
* The ID of the block.
|
||||
|
@ -91,6 +91,11 @@ class Block extends ConfigEntityBase implements BlockInterface {
|
|||
*/
|
||||
protected $pluginBag;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $pluginConfigKey = 'settings';
|
||||
|
||||
/**
|
||||
* The visibility settings.
|
||||
*
|
||||
|
@ -99,19 +104,20 @@ class Block extends ConfigEntityBase implements BlockInterface {
|
|||
protected $visibility;
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct();
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $values, $entity_type) {
|
||||
parent::__construct($values, $entity_type);
|
||||
|
||||
$this->pluginBag = new BlockPluginBag(\Drupal::service('plugin.manager.block'), array($this->plugin), $this->get('settings'), $this->id());
|
||||
public function getPlugin() {
|
||||
return $this->getPluginBag()->get($this->plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlugin() {
|
||||
return $this->pluginBag->get($this->plugin);
|
||||
public function getPluginBag() {
|
||||
if (!$this->pluginBag) {
|
||||
$this->pluginBag = new BlockPluginBag(\Drupal::service('plugin.manager.block'), $this->plugin, $this->get('settings'), $this->id());
|
||||
}
|
||||
return $this->pluginBag;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,15 +153,6 @@ class Block extends ConfigEntityBase implements BlockInterface {
|
|||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave(EntityStorageControllerInterface $storage_controller) {
|
||||
parent::preSave($storage_controller);
|
||||
|
||||
$this->set('settings', $this->getPlugin()->getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts active blocks by weight; sorts inactive blocks by name.
|
||||
*/
|
||||
|
|
|
@ -83,6 +83,10 @@ class BlockInterfaceTest extends DrupalUnitTestBase {
|
|||
'#default_value' => TRUE,
|
||||
'#return_value' => 'visible',
|
||||
),
|
||||
'cache' => array(
|
||||
'#type' => 'value',
|
||||
'#value' => DRUPAL_NO_CACHE,
|
||||
),
|
||||
'display_message' => array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Display message'),
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace Drupal\filter\Entity;
|
|||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\Core\Config\Entity\EntityWithPluginBagInterface;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\filter\FilterFormatInterface;
|
||||
use Drupal\filter\FilterBag;
|
||||
|
@ -44,7 +45,7 @@ use Drupal\filter\Plugin\FilterInterface;
|
|||
* }
|
||||
* )
|
||||
*/
|
||||
class FilterFormat extends ConfigEntityBase implements FilterFormatInterface {
|
||||
class FilterFormat extends ConfigEntityBase implements FilterFormatInterface, EntityWithPluginBagInterface {
|
||||
|
||||
/**
|
||||
* Unique machine name of the format.
|
||||
|
@ -133,6 +134,11 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface {
|
|||
*/
|
||||
protected $filterBag;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $pluginConfigKey = 'filters';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -144,12 +150,20 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function filters($instance_id = NULL) {
|
||||
$filter_bag = $this->getPluginBag();
|
||||
if (isset($instance_id)) {
|
||||
return $filter_bag->get($instance_id);
|
||||
}
|
||||
return $filter_bag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPluginBag() {
|
||||
if (!isset($this->filterBag)) {
|
||||
$this->filterBag = new FilterBag(\Drupal::service('plugin.manager.filter'), $this->filters);
|
||||
}
|
||||
if (isset($instance_id)) {
|
||||
return $this->filterBag->get($instance_id);
|
||||
}
|
||||
return $this->filterBag;
|
||||
}
|
||||
|
||||
|
@ -159,7 +173,7 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface {
|
|||
public function setFilterConfig($instance_id, array $configuration) {
|
||||
$this->filters[$instance_id] = $configuration;
|
||||
if (isset($this->filterBag)) {
|
||||
$this->filterBag->setConfiguration($instance_id, $configuration);
|
||||
$this->filterBag->setInstanceConfiguration($instance_id, $configuration);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
@ -169,9 +183,13 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface {
|
|||
*/
|
||||
public function getExportProperties() {
|
||||
$properties = parent::getExportProperties();
|
||||
// Sort and export the configuration of all filters.
|
||||
$properties['filters'] = $this->filters()->sort()->getConfiguration();
|
||||
|
||||
// @todo Make self::$weight and self::$cache protected and add them here.
|
||||
$names = array(
|
||||
'filters',
|
||||
);
|
||||
foreach ($names as $name) {
|
||||
$properties[$name] = $this->get($name);
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
|
@ -195,6 +213,9 @@ class FilterFormat extends ConfigEntityBase implements FilterFormatInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave(EntityStorageControllerInterface $storage_controller) {
|
||||
// Ensure the filters have been sorted before saving.
|
||||
$this->filters()->sort();
|
||||
|
||||
parent::preSave($storage_controller);
|
||||
|
||||
$this->name = trim($this->label());
|
||||
|
|
|
@ -18,8 +18,8 @@ use Drupal\filter\Plugin\FilterBase;
|
|||
* type = Drupal\filter\Plugin\FilterInterface::TYPE_HTML_RESTRICTOR,
|
||||
* settings = {
|
||||
* "allowed_html" = "<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <h4> <h5> <h6>",
|
||||
* "filter_html_help" = 1,
|
||||
* "filter_html_nofollow" = 0
|
||||
* "filter_html_help" = TRUE,
|
||||
* "filter_html_nofollow" = FALSE
|
||||
* },
|
||||
* weight = -10
|
||||
* )
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\image\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\Core\Config\Entity\EntityWithPluginBagInterface;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\image\ImageEffectBag;
|
||||
use Drupal\image\ImageEffectInterface;
|
||||
|
@ -45,7 +46,7 @@ use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
|||
* }
|
||||
* )
|
||||
*/
|
||||
class ImageStyle extends ConfigEntityBase implements ImageStyleInterface {
|
||||
class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, EntityWithPluginBagInterface {
|
||||
|
||||
/**
|
||||
* The name of the image style to use as replacement upon delete.
|
||||
|
@ -89,6 +90,11 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface {
|
|||
*/
|
||||
protected $effectsBag;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $pluginConfigKey = 'effects';
|
||||
|
||||
/**
|
||||
* Overrides Drupal\Core\Entity\Entity::id().
|
||||
*/
|
||||
|
@ -355,6 +361,13 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface {
|
|||
return $this->effectsBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPluginBag() {
|
||||
return $this->getEffects();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -369,7 +382,12 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface {
|
|||
*/
|
||||
public function getExportProperties() {
|
||||
$properties = parent::getExportProperties();
|
||||
$properties['effects'] = $this->getEffects()->getConfiguration();
|
||||
$names = array(
|
||||
'effects',
|
||||
);
|
||||
foreach ($names as $name) {
|
||||
$properties[$name] = $this->get($name);
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
|
@ -394,4 +412,5 @@ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface {
|
|||
$this->set('name', $name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\image\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\image\ConfigurableImageEffectInterface;
|
||||
use Drupal\image\ImageEffectManager;
|
||||
|
@ -248,4 +249,16 @@ class ImageStyleEditForm extends ImageStyleFormBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function copyFormValuesToEntity(EntityInterface $entity, array $form_state) {
|
||||
foreach ($form_state['values'] as $key => $value) {
|
||||
// Do not copy effects here, see self::updateEffectWeights().
|
||||
if ($key != 'effects') {
|
||||
$entity->set($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class ImageEffectBag extends DefaultPluginBag {
|
|||
$configuration['uuid'] = $uuid_generator->generate();
|
||||
}
|
||||
$instance_id = $configuration['uuid'];
|
||||
$this->setConfiguration($instance_id, $configuration);
|
||||
$this->setInstanceConfiguration($instance_id, $configuration);
|
||||
$this->addInstanceId($instance_id);
|
||||
return $instance_id;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\search\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\Core\Config\Entity\EntityWithPluginBagInterface;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
use Drupal\search\Plugin\SearchIndexingInterface;
|
||||
|
@ -49,7 +50,7 @@ use Drupal\search\SearchPageInterface;
|
|||
* }
|
||||
* )
|
||||
*/
|
||||
class SearchPage extends ConfigEntityBase implements SearchPageInterface {
|
||||
class SearchPage extends ConfigEntityBase implements SearchPageInterface, EntityWithPluginBagInterface {
|
||||
|
||||
/**
|
||||
* The name (plugin ID) of the search page entity.
|
||||
|
@ -112,17 +113,23 @@ class SearchPage extends ConfigEntityBase implements SearchPageInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $values, $entity_type) {
|
||||
parent::__construct($values, $entity_type);
|
||||
|
||||
$this->pluginBag = new SearchPluginBag($this->searchPluginManager(), array($this->plugin), $this->configuration, $this->id());
|
||||
}
|
||||
protected $pluginConfigKey = 'configuration';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlugin() {
|
||||
return $this->pluginBag->get($this->plugin);
|
||||
return $this->getPluginBag()->get($this->plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPluginBag() {
|
||||
if (!$this->pluginBag) {
|
||||
$this->pluginBag = new SearchPluginBag($this->searchPluginManager(), $this->plugin, $this->configuration, $this->id());
|
||||
}
|
||||
return $this->pluginBag;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,7 +137,7 @@ class SearchPage extends ConfigEntityBase implements SearchPageInterface {
|
|||
*/
|
||||
public function setPlugin($plugin_id) {
|
||||
$this->plugin = $plugin_id;
|
||||
$this->pluginBag->addInstanceID($plugin_id);
|
||||
$this->getPluginBag()->addInstanceID($plugin_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,19 +198,6 @@ class SearchPage extends ConfigEntityBase implements SearchPageInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave(EntityStorageControllerInterface $storage_controller) {
|
||||
parent::preSave($storage_controller);
|
||||
|
||||
$plugin = $this->getPlugin();
|
||||
// If this plugin has any configuration, ensure that it is set.
|
||||
if ($plugin instanceof ConfigurablePluginInterface) {
|
||||
$this->set('configuration', $plugin->getConfiguration());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -23,10 +23,19 @@ class SearchPluginBag extends DefaultSinglePluginBag {
|
|||
protected $searchPageId;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Constructs a new SearchPluginBag.
|
||||
*
|
||||
* @param \Drupal\Component\Plugin\PluginManagerInterface $manager
|
||||
* The manager to be used for instantiating plugins.
|
||||
* @param string $instance_id
|
||||
* The ID of the plugin instance.
|
||||
* @param array $configuration
|
||||
* An array of configuration.
|
||||
* @param string $search_page_id
|
||||
* The unique ID of the search page using this plugin.
|
||||
*/
|
||||
public function __construct(PluginManagerInterface $manager, array $instance_ids, array $configuration, $search_page_id) {
|
||||
parent::__construct($manager, $instance_ids, $configuration);
|
||||
public function __construct(PluginManagerInterface $manager, $instance_id, array $configuration, $search_page_id) {
|
||||
parent::__construct($manager, $instance_id, $configuration);
|
||||
|
||||
$this->searchPageId = $search_page_id;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ class SearchPluginBagTest extends UnitTestCase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
$this->pluginManager = $this->getMock('Drupal\Component\Plugin\PluginManagerInterface');
|
||||
$this->searchPluginBag = new SearchPluginBag($this->pluginManager, array('banana'), array('id' => 'banana', 'color' => 'yellow'), 'fruit_stand');
|
||||
$this->searchPluginBag = new SearchPluginBag($this->pluginManager, 'banana', array('id' => 'banana', 'color' => 'yellow'), 'fruit_stand');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\system\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageControllerInterface;
|
||||
use Drupal\Core\Config\Entity\EntityWithPluginBagInterface;
|
||||
use Drupal\system\ActionConfigEntityInterface;
|
||||
use Drupal\Core\Action\ActionBag;
|
||||
use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
|
@ -27,7 +27,7 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
|||
* }
|
||||
* )
|
||||
*/
|
||||
class Action extends ConfigEntityBase implements ActionConfigEntityInterface {
|
||||
class Action extends ConfigEntityBase implements ActionConfigEntityInterface, EntityWithPluginBagInterface {
|
||||
|
||||
/**
|
||||
* The name (plugin ID) of the action.
|
||||
|
@ -81,17 +81,23 @@ class Action extends ConfigEntityBase implements ActionConfigEntityInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $values, $entity_type) {
|
||||
parent::__construct($values, $entity_type);
|
||||
protected $pluginConfigKey = 'configuration';
|
||||
|
||||
$this->pluginBag = new ActionBag(\Drupal::service('plugin.manager.action'), array($this->plugin), $this->configuration);
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPluginBag() {
|
||||
if (!$this->pluginBag) {
|
||||
$this->pluginBag = new ActionBag(\Drupal::service('plugin.manager.action'), $this->plugin, $this->configuration);
|
||||
}
|
||||
return $this->pluginBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPlugin() {
|
||||
return $this->pluginBag->get($this->plugin);
|
||||
return $this->getPluginBag()->get($this->plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +105,7 @@ class Action extends ConfigEntityBase implements ActionConfigEntityInterface {
|
|||
*/
|
||||
public function setPlugin($plugin_id) {
|
||||
$this->plugin = $plugin_id;
|
||||
$this->pluginBag->addInstanceId($plugin_id);
|
||||
$this->getPluginBag()->addInstanceId($plugin_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,17 +164,4 @@ class Action extends ConfigEntityBase implements ActionConfigEntityInterface {
|
|||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave(EntityStorageControllerInterface $storage_controller) {
|
||||
parent::preSave($storage_controller);
|
||||
|
||||
$plugin = $this->getPlugin();
|
||||
// If this plugin has any configuration, ensure that it is set.
|
||||
if ($plugin instanceof ConfigurablePluginInterface) {
|
||||
$this->set('configuration', $plugin->getConfiguration());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Tests\Entity\ConfigEntityImportTestBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Tests\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\EntityWithPluginBagInterface;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests importing config entities.
|
||||
*/
|
||||
class ConfigEntityImportTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('action', 'block', 'filter', 'image', 'search', 'search_extra_type');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Configuration entity import',
|
||||
'description' => 'Tests ConfigEntity importing.',
|
||||
'group' => 'Configuration',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs test methods for each module within a single test run.
|
||||
*/
|
||||
public function testConfigUpdateImport() {
|
||||
$this->doActionUpdate();
|
||||
$this->doBlockUpdate();
|
||||
$this->doFilterFormatUpdate();
|
||||
$this->doImageStyleUpdate();
|
||||
$this->doSearchPageUpdate();
|
||||
}
|
||||
/**
|
||||
* Tests updating a action during import.
|
||||
*/
|
||||
protected function doActionUpdate() {
|
||||
// Create a test action with a known label.
|
||||
$name = 'system.action.apple';
|
||||
$entity = entity_create('action', array(
|
||||
'id' => 'apple',
|
||||
'plugin' => 'action_message_action',
|
||||
));
|
||||
$entity->save();
|
||||
|
||||
$this->checkSinglePluginConfigSync($entity, 'configuration', 'message', '');
|
||||
|
||||
// Read the existing data, and prepare an altered version in staging.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['configuration']['message'] = 'Granny Smith';
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating a block during import.
|
||||
*/
|
||||
protected function doBlockUpdate() {
|
||||
// Create a test block with a known label.
|
||||
$name = 'block.block.apple';
|
||||
$block = $this->drupalPlaceBlock('system_powered_by_block', array(
|
||||
'id' => 'apple',
|
||||
'label' => 'Red Delicious',
|
||||
));
|
||||
|
||||
$this->checkSinglePluginConfigSync($block, 'settings', 'label', 'Red Delicious');
|
||||
|
||||
// Read the existing data, and prepare an altered version in staging.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['settings']['label'] = 'Granny Smith';
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating a filter format during import.
|
||||
*/
|
||||
protected function doFilterFormatUpdate() {
|
||||
// Create a test filter format with a known label.
|
||||
$name = 'filter.format.plain_text';
|
||||
|
||||
/** @var $entity \Drupal\filter\Entity\FilterFormat */
|
||||
$entity = entity_load('filter_format', 'plain_text');
|
||||
$plugin_bag = $entity->getPluginBag();
|
||||
|
||||
$filters = $entity->get('filters');
|
||||
$this->assertIdentical(72, $filters['filter_url']['settings']['filter_url_length']);
|
||||
|
||||
$filters['filter_url']['settings']['filter_url_length'] = 100;
|
||||
$entity->set('filters', $filters);
|
||||
$entity->save();
|
||||
$this->assertIdentical($filters, $entity->get('filters'));
|
||||
$this->assertIdentical($filters, $plugin_bag->getConfiguration());
|
||||
|
||||
$filters['filter_url']['settings']['filter_url_length'] = -100;
|
||||
$entity->getPluginBag()->setConfiguration($filters);
|
||||
$entity->save();
|
||||
$this->assertIdentical($filters, $entity->get('filters'));
|
||||
$this->assertIdentical($filters, $plugin_bag->getConfiguration());
|
||||
|
||||
// Read the existing data, and prepare an altered version in staging.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['filters']['filter_url']['settings']['filter_url_length'] = 100;
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating an image style during import.
|
||||
*/
|
||||
protected function doImageStyleUpdate() {
|
||||
// Create a test image style with a known label.
|
||||
$name = 'image.style.thumbnail';
|
||||
|
||||
/** @var $entity \Drupal\image\Entity\ImageStyle */
|
||||
$entity = entity_load('image_style', 'thumbnail');
|
||||
$plugin_bag = $entity->getPluginBag();
|
||||
|
||||
$effects = $entity->get('effects');
|
||||
$effect_id = key($effects);
|
||||
$this->assertIdentical(100, $effects[$effect_id]['data']['height']);
|
||||
|
||||
$effects[$effect_id]['data']['height'] = 50;
|
||||
$entity->set('effects', $effects);
|
||||
$entity->save();
|
||||
// Ensure the entity and plugin have the correct configuration.
|
||||
$this->assertIdentical($effects, $entity->get('effects'));
|
||||
$this->assertIdentical($effects, $plugin_bag->getConfiguration());
|
||||
|
||||
$effects[$effect_id]['data']['height'] = -50;
|
||||
$entity->getPluginBag()->setConfiguration($effects);
|
||||
$entity->save();
|
||||
// Ensure the entity and plugin have the correct configuration.
|
||||
$this->assertIdentical($effects, $entity->get('effects'));
|
||||
$this->assertIdentical($effects, $plugin_bag->getConfiguration());
|
||||
|
||||
// Read the existing data, and prepare an altered version in staging.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$effect_name = key($original_data['effects']);
|
||||
|
||||
$custom_data['effects'][$effect_name]['data']['upscale'] = FALSE;
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating a search page during import.
|
||||
*/
|
||||
protected function doSearchPageUpdate() {
|
||||
// Create a test search page with a known label.
|
||||
$name = 'search.page.apple';
|
||||
$entity = entity_create('search_page', array(
|
||||
'id' => 'apple',
|
||||
'plugin' => 'search_extra_type_search',
|
||||
));
|
||||
$entity->save();
|
||||
|
||||
$this->checkSinglePluginConfigSync($entity, 'configuration', 'boost', 'bi');
|
||||
|
||||
// Read the existing data, and prepare an altered version in staging.
|
||||
$custom_data = $original_data = $this->container->get('config.storage')->read($name);
|
||||
$custom_data['configuration']['boost'] = 'asdf';
|
||||
$this->assertConfigUpdateImport($name, $original_data, $custom_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that a single set of plugin config stays in sync.
|
||||
*
|
||||
* @param \Drupal\Core\Config\Entity\EntityWithPluginBagInterface $entity
|
||||
* The entity.
|
||||
* @param string $config_key
|
||||
* Where the plugin config is stored.
|
||||
* @param string $setting_key
|
||||
* The setting within the plugin config to change.
|
||||
* @param mixed $expected
|
||||
* The expected default value of the plugin config setting.
|
||||
*/
|
||||
protected function checkSinglePluginConfigSync(EntityWithPluginBagInterface $entity, $config_key, $setting_key, $expected) {
|
||||
$plugin_bag = $entity->getPluginBag();
|
||||
$settings = $entity->get($config_key);
|
||||
|
||||
// Ensure the default config exists.
|
||||
$this->assertIdentical($expected, $settings[$setting_key]);
|
||||
|
||||
// Change the plugin config by setting it on the entity.
|
||||
$settings[$setting_key] = $this->randomString();
|
||||
$entity->set($config_key, $settings);
|
||||
$entity->save();
|
||||
$this->assertIdentical($settings, $entity->get($config_key));
|
||||
$this->assertIdentical($settings, $plugin_bag->getConfiguration());
|
||||
|
||||
// Change the plugin config by setting it on the plugin.
|
||||
$settings[$setting_key] = $this->randomString();
|
||||
$plugin_bag->setConfiguration($settings);
|
||||
$entity->save();
|
||||
$this->assertIdentical($settings, $entity->get($config_key));
|
||||
$this->assertIdentical($settings, $plugin_bag->getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that config entities are updated during import.
|
||||
*
|
||||
* @param string $name
|
||||
* The name of the config object.
|
||||
* @param array $original_data
|
||||
* The original data stored in the config object.
|
||||
* @param array $custom_data
|
||||
* The new data to store in the config object.
|
||||
*/
|
||||
public function assertConfigUpdateImport($name, $original_data, $custom_data) {
|
||||
$this->container->get('config.storage.staging')->write($name, $custom_data);
|
||||
|
||||
// Verify the active configuration still returns the default values.
|
||||
$config = $this->container->get('config.factory')->get($name);
|
||||
$this->assertIdentical($config->get(), $original_data);
|
||||
|
||||
// Import.
|
||||
$this->configImporter()->import();
|
||||
|
||||
// Verify the values were updated.
|
||||
$this->container->get('config.factory')->reset($name);
|
||||
$config = $this->container->get('config.factory')->get($name);
|
||||
$this->assertIdentical($config->get(), $custom_data);
|
||||
}
|
||||
|
||||
}
|
|
@ -42,4 +42,18 @@ class TestPluginBag extends PluginBag {
|
|||
$this->pluginInstances[$instance_id] = $this->manager->createInstance($instance_id, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setConfiguration($configuration) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ class ConfigurablePluginBagTest extends PluginBagTestBase {
|
|||
public function testConfigurableSetConfiguration() {
|
||||
$this->setupPluginBag($this->exactly(3));
|
||||
$this->defaultPluginBag->getConfiguration();
|
||||
$this->defaultPluginBag->setConfiguration('apple', array('value' => 'pineapple'));
|
||||
$this->defaultPluginBag->setInstanceConfiguration('apple', array('value' => 'pineapple'));
|
||||
|
||||
$expected = $this->config;
|
||||
$expected['apple'] = array('value' => 'pineapple');
|
||||
|
|
|
@ -140,18 +140,18 @@ class DefaultPluginBagTest extends PluginBagTestBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Tests the setConfiguration() method.
|
||||
* Tests the setInstanceConfiguration() method.
|
||||
*
|
||||
* @see \Drupal\Component\Plugin\DefaultPluginBag::setConfiguration()
|
||||
* @see \Drupal\Component\Plugin\DefaultPluginBag::setInstanceConfiguration()
|
||||
*/
|
||||
public function testSetConfiguration() {
|
||||
public function testSetInstanceConfiguration() {
|
||||
$this->setupPluginBag($this->exactly(3));
|
||||
$expected = array(
|
||||
'id' => 'cherry',
|
||||
'key' => 'value',
|
||||
'custom' => 'bananas',
|
||||
);
|
||||
$this->defaultPluginBag->setConfiguration('cherry', $expected);
|
||||
$this->defaultPluginBag->setInstanceConfiguration('cherry', $expected);
|
||||
$config = $this->defaultPluginBag->getConfiguration();
|
||||
$this->assertSame($expected, $config['cherry']);
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ class DefaultPluginBagTest extends PluginBagTestBase {
|
|||
$this->setupPluginBag($this->exactly(4));
|
||||
$instance = $this->pluginManager->createInstance('cherry', $this->config['cherry']);
|
||||
$this->defaultPluginBag->set('cherry2', $instance);
|
||||
$this->defaultPluginBag->setConfiguration('cherry2', $this->config['cherry']);
|
||||
$this->defaultPluginBag->setInstanceConfiguration('cherry2', $this->config['cherry']);
|
||||
|
||||
$expected = array(
|
||||
'banana',
|
||||
|
|
|
@ -41,7 +41,7 @@ class DefaultSinglePluginBagTest extends PluginBagTestBase {
|
|||
->method('createInstance')
|
||||
->will($this->returnValue($this->pluginInstances['apple']));
|
||||
|
||||
$this->defaultPluginBag = new DefaultSinglePluginBag($this->pluginManager, array_keys($this->pluginInstances), array('id' => 'apple', 'key' => 'value'));
|
||||
$this->defaultPluginBag = new DefaultSinglePluginBag($this->pluginManager, 'apple', array('id' => 'apple', 'key' => 'value'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue