diff --git a/config/install/replication.replication_settings.article.yml b/config/install/replication.replication_settings.article.yml new file mode 100644 index 0000000..b6a07f0 --- /dev/null +++ b/config/install/replication.replication_settings.article.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: { } +id: article +label: Replicate only article entities +filter_id: entity_type +parameters: + entity_type_id: node + bundle: article diff --git a/config/install/replication.replication_settings.entity_type.article.yml b/config/install/replication.replication_settings.entity_type.article.yml deleted file mode 100644 index b6a07f0..0000000 --- a/config/install/replication.replication_settings.entity_type.article.yml +++ /dev/null @@ -1,9 +0,0 @@ -langcode: en -status: true -dependencies: { } -id: article -label: Replicate only article entities -filter_id: entity_type -parameters: - entity_type_id: node - bundle: article diff --git a/config/install/replication.replication_settings.entity_type.page.yml b/config/install/replication.replication_settings.entity_type.page.yml deleted file mode 100644 index a0977a1..0000000 --- a/config/install/replication.replication_settings.entity_type.page.yml +++ /dev/null @@ -1,9 +0,0 @@ -langcode: en -status: true -dependencies: { } -id: page -label: Replicate only page entities -filter_id: entity_type -parameters: - entity_type_id: node - bundle: page diff --git a/config/install/replication.replication_settings.page.yml b/config/install/replication.replication_settings.page.yml new file mode 100644 index 0000000..a0977a1 --- /dev/null +++ b/config/install/replication.replication_settings.page.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: { } +id: page +label: Replicate only page entities +filter_id: entity_type +parameters: + entity_type_id: node + bundle: page diff --git a/config/schema/replication.replication_settings.schema.yml b/config/schema/replication.replication_settings.schema.yml index b3fedc1..caa01d4 100644 --- a/config/schema/replication.replication_settings.schema.yml +++ b/config/schema/replication.replication_settings.schema.yml @@ -10,7 +10,7 @@ replication.replication_settings.*: label: 'Label' filter_id: type: string - label: 'Filter plugin id' + label: 'Filter plugin ID' parameters: type: ignore label: 'Filter parameters' diff --git a/src/Changes/Changes.php b/src/Changes/Changes.php index 2a0372b..98ae886 100644 --- a/src/Changes/Changes.php +++ b/src/Changes/Changes.php @@ -46,7 +46,7 @@ class Changes implements ChangesInterface { /** * @var ParameterBag - * The parameters passed to the filter function. + * The parameters passed to the filter plugin. */ protected $parameters; @@ -121,12 +121,12 @@ class Changes implements ChangesInterface { $parameters = ($this->parameters instanceof ParameterBag) ? $this->parameters : new ParameterBag(); $filter = NULL; if (is_string($this->filterName) && $this->filterName) { - $filter = $this->filterManager->createInstance($this->filterName); + $filter = $this->filterManager->createInstance($this->filterName, $parameters->all()); } // If UUIDs are sent as a parameter, but no filter is set, automatically // select the "uuid" filter. elseif ($parameters->has('uuids')) { - $filter = $this->filterManager->createInstance('uuid'); + $filter = $this->filterManager->createInstance('uuid', $parameters->all()); } // Format the result array. @@ -146,7 +146,7 @@ class Changes implements ChangesInterface { } // Filter the document. - if ($filter !== NULL && !$filter->filter($revision, $parameters)) { + if ($filter !== NULL && !$filter->filter($revision)) { continue; } diff --git a/src/Changes/ChangesInterface.php b/src/Changes/ChangesInterface.php index 1b42b86..c955845 100644 --- a/src/Changes/ChangesInterface.php +++ b/src/Changes/ChangesInterface.php @@ -30,7 +30,7 @@ interface ChangesInterface { * Set the parameters for the filter plugin. * * @param ParameterBag $parameters - * The parameters passed to the filter function. + * The parameters passed to the filter plugin. * * @return \Drupal\replication\Changes\ChangesInterface * Returns $this. diff --git a/src/Plugin/ReplicationFilter/EntityTypeFilter.php b/src/Plugin/ReplicationFilter/EntityTypeFilter.php index 794a012..041847c 100644 --- a/src/Plugin/ReplicationFilter/EntityTypeFilter.php +++ b/src/Plugin/ReplicationFilter/EntityTypeFilter.php @@ -4,12 +4,11 @@ namespace Drupal\replication\Plugin\ReplicationFilter; use Drupal\Core\Entity\EntityInterface; use Drupal\replication\Plugin\ReplicationFilter\ReplicationFilterBase; -use Symfony\Component\HttpFoundation\ParameterBag; /** * Provides a filter based on entity type. * - * Supported parameters: + * Supported configuration: * entity_type_id: a comma delimited list of entity type id's to include * bundle: a comma delimited list of bundles matching the type ids * @@ -24,9 +23,9 @@ class EntityTypeFilter extends ReplicationFilterBase { /** * {@inheritdoc} */ - public function filter(EntityInterface $entity, ParameterBag $parameters) { - $entity_type_ids = $this->parseParameterValues($parameters, 'entity_type_id'); - $bundles = $this->parseParameterValues($parameters, 'bundle'); + public function filter(EntityInterface $entity) { + $entity_type_ids = $this->getDelimitedConfigurationValue(',', 'entity_type_id'); + $bundles = $this->getDelimitedConfigurationValue(',', 'bundle'); // Ensure length of entity_type_ids and bundles are equal. if (count($entity_type_ids) != count($bundles)) { @@ -45,25 +44,4 @@ class EntityTypeFilter extends ReplicationFilterBase { return FALSE; } - /** - * Parse a parameter's comma delimiated values. - * - * @param string $parameter_name - * The name of the parameter to get the values for. - * - * @return array - * The parsed parameter values. - */ - protected function parseParameterValues(ParameterBag $parameters, $parameter_name) { - if ($parameters->has($parameter_name)) { - $values = $parameters->get($parameter_name); - } - else { - $values = ''; - } - $values = explode(',', $values); - $values = array_filter(array_map('trim', $values)); - return $values; - } - } diff --git a/src/Plugin/ReplicationFilter/PublishedFilter.php b/src/Plugin/ReplicationFilter/PublishedFilter.php index d103c7c..b20965a 100644 --- a/src/Plugin/ReplicationFilter/PublishedFilter.php +++ b/src/Plugin/ReplicationFilter/PublishedFilter.php @@ -5,7 +5,6 @@ namespace Drupal\replication\Plugin\ReplicationFilter; use Drupal\Core\Entity\EntityInterface; use Drupal\node\NodeInterface; use Drupal\replication\Plugin\ReplicationFilter\ReplicationFilterBase; -use Symfony\Component\HttpFoundation\ParameterBag; /** * Provides a filter for published entities. @@ -23,9 +22,9 @@ class PublishedFilter extends ReplicationFilterBase { /** * {@inheritdoc} */ - public function filter(EntityInterface $entity, ParameterBag $parameters) { + public function filter(EntityInterface $entity) { if (!$entity instanceof NodeInterface) { - return false; + return FALSE; } return $entity->isPublished(); } diff --git a/src/Plugin/ReplicationFilter/ReplicationFilterBase.php b/src/Plugin/ReplicationFilter/ReplicationFilterBase.php index 4fa7b92..c551bc2 100644 --- a/src/Plugin/ReplicationFilter/ReplicationFilterBase.php +++ b/src/Plugin/ReplicationFilter/ReplicationFilterBase.php @@ -37,4 +37,54 @@ abstract class ReplicationFilterBase extends PluginBase implements ReplicationFi return $this->description; } + /** + * {@inheritdoc} + * + * For replication filters, the plugin configuration contains what would be + * passed as "query_params" to a CouchDB filter function. + */ + public function getConfiguration() { + return $this->configuration; + } + + /** + * {@inheritdoc} + */ + public function setConfiguration(array $configuration) { + $this->configuration = $configuration; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return array(); + } + + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + return array(); + } + + /** + * Parse a configuration as delimited values. + * + * @param string $delimiter + * The delimiter of each value. + * @param string $configuration_key + * The key of the configuration to get the values for. + * + * @return array + * The configuration parsed into an array of values. + */ + protected function getDelimitedConfigurationValue($delimiter, $configuration_key) { + $configuration = $this->getConfiguration(); + $values = (isset($configuration[$configuration_key])) ? $configuration[$configuration_key] : ''; + $values = explode($delimiter, $values); + $values = array_filter(array_map('trim', $values)); + return $values; + } + } diff --git a/src/Plugin/ReplicationFilter/UuidFilter.php b/src/Plugin/ReplicationFilter/UuidFilter.php index 61fdfa0..0ee8fa6 100644 --- a/src/Plugin/ReplicationFilter/UuidFilter.php +++ b/src/Plugin/ReplicationFilter/UuidFilter.php @@ -4,7 +4,6 @@ namespace Drupal\replication\Plugin\ReplicationFilter; use Drupal\Core\Entity\EntityInterface; use Drupal\replication\Plugin\ReplicationFilter\ReplicationFilterBase; -use Symfony\Component\HttpFoundation\ParameterBag; /** * Provides filtering by UUID. @@ -24,10 +23,8 @@ class UuidFilter extends ReplicationFilterBase { /** * {@inheritdoc} */ - public function filter(EntityInterface $entity, ParameterBag $parameters) { - $uuids = $parameters->get('uuids') ?: ''; - $uuids = explode(',', $uuids); - $uuids = array_map('trim', $uuids); + public function filter(EntityInterface $entity) { + $uuids = $this->getDelimitedConfigurationValue(',', 'uuids'); return in_array($entity->uuid(), $uuids); } diff --git a/src/Plugin/ReplicationFilterInterface.php b/src/Plugin/ReplicationFilterInterface.php index dae6556..17c7fa9 100644 --- a/src/Plugin/ReplicationFilterInterface.php +++ b/src/Plugin/ReplicationFilterInterface.php @@ -2,6 +2,7 @@ namespace Drupal\replication\Plugin; +use Drupal\Component\Plugin\ConfigurablePluginInterface; use Drupal\Component\Plugin\PluginInspectionInterface; use Drupal\Core\Entity\EntityInterface; use Symfony\Component\HttpFoundation\ParameterBag; @@ -12,7 +13,7 @@ use Symfony\Component\HttpFoundation\ParameterBag; * Replication filters are used to filter out entities from a changeset during * replication. */ -interface ReplicationFilterInterface extends PluginInspectionInterface { +interface ReplicationFilterInterface extends PluginInspectionInterface, ConfigurablePluginInterface { /** * Get the label for the filter. @@ -39,6 +40,6 @@ interface ReplicationFilterInterface extends PluginInspectionInterface { * @return bool * Return TRUE if it should be included, else FALSE. */ - public function filter(EntityInterface $entity, ParameterBag $parameters); + public function filter(EntityInterface $entity); } diff --git a/tests/src/Unit/Plugin/ReplicationFilter/EntityTypeFilterTest.php b/tests/src/Unit/Plugin/ReplicationFilter/EntityTypeFilterTest.php index 2ed7f16..124579c 100644 --- a/tests/src/Unit/Plugin/ReplicationFilter/EntityTypeFilterTest.php +++ b/tests/src/Unit/Plugin/ReplicationFilter/EntityTypeFilterTest.php @@ -27,20 +27,25 @@ class EntityTypeFilterTest extends \PHPUnit_Framework_TestCase { */ public function testFilter($entity_type_id, $bundle, $expected) { // Use a mock builder for the class under test to eliminate the need to - // mock all the dependencies. This is OK since the method under test is a - // pure function, i.e. does not use the state createdy by the constructor. + // mock all the dependencies. The method under test uses the $configuration + // set by the constructor, but is retrieved via a get method we can stub. $filter = $this->getMockBuilder(EntityTypeFilter::class) ->disableOriginalConstructor() - ->setMethods(NULL) + ->setMethods(['getConfiguration']) ->getMock(); + $configuration = [ + 'entity_type_id' => $entity_type_id, + 'bundle' => $bundle, + ]; + $filter->method('getConfiguration') + ->willReturn($configuration); $entity = $this->getMock(EntityInterface::class); $entity->method('getEntityTypeId') ->willReturn('node'); $entity->method('bundle') ->willReturn('article'); - $parameters = new ParameterBag(['entity_type_id' => $entity_type_id, 'bundle' => $bundle]); - $value = $filter->filter($entity, $parameters); + $value = $filter->filter($entity); $this->assertEquals($expected, $value); } diff --git a/tests/src/Unit/Plugin/ReplicationFilter/UuidFilterTest.php b/tests/src/Unit/Plugin/ReplicationFilter/UuidFilterTest.php index a16be60..1e8f42b 100644 --- a/tests/src/Unit/Plugin/ReplicationFilter/UuidFilterTest.php +++ b/tests/src/Unit/Plugin/ReplicationFilter/UuidFilterTest.php @@ -20,18 +20,22 @@ class UuidFilterTest extends \PHPUnit_Framework_TestCase { */ public function testFilter($uuid, $parameter_value, $expected) { // Use a mock builder for the class under test to eliminate the need to - // mock all the dependencies. This is OK since the method under test is a - // pure function, i.e. does not use the state createdy by the constructor. + // mock all the dependencies. The method under test uses the $configuration + // set by the constructor, but is retrieved via a get method we can stub. $filter = $this->getMockBuilder(UuidFilter::class) ->disableOriginalConstructor() - ->setMethods(NULL) + ->setMethods(['getConfiguration']) ->getMock(); + $configuration = [ + 'uuids' => $parameter_value, + ]; + $filter->method('getConfiguration') + ->willReturn($configuration); $entity = $this->getMock(EntityInterface::class); $entity->method('uuid') ->willReturn($uuid); - $parameters = new ParameterBag(['uuids' => $parameter_value]); - $value = $filter->filter($entity, $parameters); + $value = $filter->filter($entity); $this->assertEquals($expected, $value); }