diff --git a/config/schema/feeds.schema.yml b/config/schema/feeds.schema.yml index d8841e4..6271af3 100644 --- a/config/schema/feeds.schema.yml +++ b/config/schema/feeds.schema.yml @@ -116,6 +116,8 @@ feeds.processor.entity: type: string update_existing: type: integer + update_non_existent: + type: string skip_hash_check: type: boolean authorize: diff --git a/src/Feeds/Processor/EntityProcessorBase.php b/src/Feeds/Processor/EntityProcessorBase.php index 1467b9b..c204aa2 100644 --- a/src/Feeds/Processor/EntityProcessorBase.php +++ b/src/Feeds/Processor/EntityProcessorBase.php @@ -434,6 +434,7 @@ abstract class EntityProcessorBase extends ProcessorBase implements EntityProces public function defaultConfiguration() { $defaults = [ 'update_existing' => static::SKIP_EXISTING, + 'update_non_existent' => static::KEEP_NON_EXISTENT, 'skip_hash_check' => FALSE, 'values' => [$this->entityType->getKey('bundle') => NULL], 'authorize' => $this->entityType->isSubclassOf('Drupal\user\EntityOwnerInterface'), @@ -730,4 +731,27 @@ abstract class EntityProcessorBase extends ProcessorBase implements EntityProces ->execute(); } + /** + * {@inheritdoc} + */ + public function calculateDependencies() { + $dependencies = parent::calculateDependencies(); + + // Add dependency on entity type. + $entity_type_provider = \Drupal::entityTypeManager() + ->getDefinition($this->entityType()) + ->getProvider(); + $dependencies['module'][$entity_type_provider] = $entity_type_provider; + + // For the 'update_non_existent' setting, add dependency on selected action. + if ($this->getConfiguration('update_non_existent') !== static::KEEP_NON_EXISTENT) { + $definition = \Drupal::service('plugin.manager.action')->getDefinition($this->getConfiguration('update_non_existent')); + if (isset($definition['provider'])) { + $dependencies['module'][$definition['provider']] = $definition['provider']; + } + } + + return $dependencies; + } + } diff --git a/src/Feeds/Processor/Form/DefaultEntityProcessorForm.php b/src/Feeds/Processor/Form/DefaultEntityProcessorForm.php index 425018e..a5d446b 100644 --- a/src/Feeds/Processor/Form/DefaultEntityProcessorForm.php +++ b/src/Feeds/Processor/Form/DefaultEntityProcessorForm.php @@ -2,6 +2,7 @@ namespace Drupal\feeds\Feeds\Processor\Form; +use Drupal\Component\Plugin\ConfigurablePluginInterface; use Drupal\Component\Utility\Unicode; use Drupal\Core\Form\FormStateInterface; use Drupal\feeds\Plugin\Type\ExternalPluginFormBase; @@ -38,6 +39,17 @@ class DefaultEntityProcessorForm extends ExternalPluginFormBase { $times = [ProcessorInterface::EXPIRE_NEVER, 3600, 10800, 21600, 43200, 86400, 259200, 604800, 2592000, 2592000 * 3, 2592000 * 6, 31536000]; $period = array_map([$this, 'formatExpire'], array_combine($times, $times)); + $options = $this->getUpdateNonExistentActions(); + if (!empty($options)) { + $form['update_non_existent'] = [ + '#type' => 'select', + '#title' => $this->t('Previously imported items'), + '#description' => $this->t('Select what to do with items that were previously imported, but are now no longer in the feed.'), + '#options' => $options, + '#default_value' => $this->plugin->getConfiguration('update_non_existent'), + ]; + } + $form['expire'] = [ '#type' => 'select', '#title' => $this->t('Expire @entities', $tokens), @@ -131,4 +143,31 @@ class DefaultEntityProcessorForm extends ExternalPluginFormBase { return $this->t('after @time', ['@time' => \Drupal::service('date.formatter')->formatInterval($timestamp)]); } + /** + * Get available actions to apply on the entity. + * + * @return array + * A list of applyable actions. + */ + protected function getUpdateNonExistentActions() { + $action_definitions = \Drupal::service('plugin.manager.action')->getDefinitionsByType($this->plugin->entityType()); + foreach ($action_definitions as $definition) { + // Filter out configurable actions. + $interfaces = class_implements($definition['class']); + if (isset($interfaces[ConfigurablePluginInterface::class])) { + continue; + } + + $options[$definition['id']] = $definition['label']; + } + + if (empty($options)) { + return []; + } + + return [ + '_keep' => $this->t('Keep'), + ] + $options; + } + } diff --git a/src/Feeds/Processor/NodeProcessor.php b/src/Feeds/Processor/NodeProcessor.php index 2b4b9ca..2275a7a 100644 --- a/src/Feeds/Processor/NodeProcessor.php +++ b/src/Feeds/Processor/NodeProcessor.php @@ -22,13 +22,6 @@ namespace Drupal\feeds\Feeds\Processor; class NodeProcessor extends EntityProcessorBase { /** - * Unpublish items that no longer exist in the feed. - * - * @var string - */ - const UNPUBLISH_NON_EXISTENT = 'unpublish'; - - /** * {@inheritdoc} */ public function entityLabel() { diff --git a/src/Plugin/Type/Processor/ProcessorInterface.php b/src/Plugin/Type/Processor/ProcessorInterface.php index ca0206b..1bba7b9 100644 --- a/src/Plugin/Type/Processor/ProcessorInterface.php +++ b/src/Plugin/Type/Processor/ProcessorInterface.php @@ -41,18 +41,11 @@ interface ProcessorInterface extends FeedsPluginInterface { const EXPIRE_NEVER = -1; /** - * Ignore items that no longer exist in the feed. + * Keep items that no longer exist in the feed. * * @var string */ - const SKIP_NON_EXISTENT = 'skip'; - - /** - * Delete items that no longer exist in the feed. - * - * @var string - */ - const DELETE_NON_EXISTENT = 'delete'; + const KEEP_NON_EXISTENT = '_keep'; /** * Processes the results from a parser. diff --git a/tests/src/Kernel/UpdateNonExistentTest.php b/tests/src/Kernel/UpdateNonExistentTest.php index c8b415f..462e37a 100644 --- a/tests/src/Kernel/UpdateNonExistentTest.php +++ b/tests/src/Kernel/UpdateNonExistentTest.php @@ -5,7 +5,6 @@ namespace Drupal\Tests\feeds\Kernel; use Drupal\Component\Utility\Unicode; use Drupal\feeds\Entity\Feed; use Drupal\feeds\Entity\FeedType; -use Drupal\feeds\Feeds\Processor\NodeProcessor; use Drupal\feeds\FeedInterface; use Drupal\feeds\FeedTypeInterface; use Drupal\node\Entity\Node; @@ -87,7 +86,7 @@ class UpdateNonExistentTest extends FeedsKernelTestBase { public function testUnpublishNonExistentItems() { // Set 'update_non_existent' setting to 'unpublish'. $config = $this->feedType->getProcessor()->getConfiguration(); - $config['update_non_existent'] = NodeProcessor::UNPUBLISH_NON_EXISTENT; + $config['update_non_existent'] = 'node_unpublish_action'; $this->feedType->getProcessor()->setConfiguration($config); // Create a feed and import first file. @@ -151,7 +150,7 @@ class UpdateNonExistentTest extends FeedsKernelTestBase { public function testDeleteNonExistentItems() { // Set 'update_non_existent' setting to 'unpublish'. $config = $this->feedType->getProcessor()->getConfiguration(); - $config['update_non_existent'] = NodeProcessor::DELETE_NON_EXISTENT; + $config['update_non_existent'] = 'node_delete_action'; $this->feedType->getProcessor()->setConfiguration($config); // Create a feed and import first file.