Loading config/schema/feeds.schema.yml +2 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ feeds.feed_type.*: unique: type: ignore action.configuration.feeds_feed_delete_action: type: action_configuration_default label: 'Delete feeds configuration' Loading Loading @@ -188,6 +187,8 @@ feeds.processor.entity: type: boolean authorize: type: boolean revision: type: boolean expire: type: integer owner_feed_author: Loading src/Feeds/Processor/EntityProcessorBase.php +7 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,12 @@ abstract class EntityProcessorBase extends ProcessorBase implements EntityProces $feeds_item = $entity->get('feeds_item')->getItemByFeed($feed, TRUE); $feeds_item->hash = $hash; // Set new revision if needed. if ($this->configuration['revision']) { $entity->setNewRevision(TRUE); $entity->setRevisionCreationTime($this->dateTime->getRequestTime()); } // Set field values. $this->map($feed, $entity, $item); Loading Loading @@ -748,6 +754,7 @@ abstract class EntityProcessorBase extends ProcessorBase implements EntityProces 'skip_hash_check' => FALSE, 'values' => [], 'authorize' => $this->entityType->entityClassImplements('Drupal\user\EntityOwnerInterface'), 'revision' => FALSE, 'expire' => static::EXPIRE_NEVER, 'owner_id' => 0, 'owner_feed_author' => 0, Loading src/Feeds/Processor/Form/DefaultEntityProcessorForm.php +10 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,16 @@ class DefaultEntityProcessorForm extends ExternalPluginFormBase implements Conta ]; } if ($entity_type->entityClassImplements('\Drupal\Core\Entity\RevisionableInterface')) { $form['advanced']['revision'] = [ '#type' => 'checkbox', '#title' => $this->t('New revision'), '#description' => $this->t('Save as new revision.'), '#default_value' => $this->plugin->getConfiguration('revision'), '#parents' => ['processor_configuration', 'revision'], ]; } $form['advanced']['skip_hash_check'] = [ '#type' => 'checkbox', '#title' => $this->t('Force update'), Loading tests/src/Kernel/RevisionableEntityTest.php 0 → 100644 +206 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\feeds\Kernel; use Drupal\feeds\Plugin\Type\Processor\ProcessorInterface; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; /** * Tests the feature of save a new revision. * * @group feeds */ class RevisionableEntityTest extends FeedsKernelTestBase { /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->setUpBodyField(); } /** * {@inheritdoc} */ protected function setUpNodeType() { // Create a content type. $this->nodeType = NodeType::create([ 'type' => 'article', 'name' => 'Article', // Ensure that this node type is revisionable. 'new_revision' => TRUE, ]); $this->nodeType->save(); } /** * Tests the revision toggle configuration. * * @dataProvider provideToggleRevision */ public function testRevisionToggle($is_enabled) { $feed_type = $this->createFeedType([ 'fetcher' => 'directory', 'fetcher_configuration' => [ 'allowed_extensions' => 'csv', ], 'parser' => 'csv', 'processor_configuration' => [ 'update_existing' => ProcessorInterface::UPDATE_EXISTING, 'authorize' => FALSE, // Using the data provider, enable or disable the revision accordingly. 'revision' => $is_enabled, 'values' => [ 'type' => 'article', ], ], 'custom_sources' => [ 'title' => [ 'label' => 'title', 'value' => 'title', 'machine_name' => 'title', ], 'body' => [ 'label' => 'body', 'value' => 'body', 'machine_name' => 'body', ], ], 'mappings' => [ [ 'target' => 'title', 'map' => ['value' => 'title'], 'unique' => ['value' => TRUE], 'settings' => [ 'language' => NULL, ], ], [ 'target' => 'body', 'map' => ['value' => 'body', 'summary' => ''], 'settings' => ['format' => 'plain_text'], ], ], ]); // Import first feed to create the first revision. $feed = $this->createFeed($feed_type->id(), [ 'source' => $this->resourcesPath() . '/csv/content.csv', ]); $feed->import(); $node = Node::load(1); $first_revision_id = $node->getRevisionId(); // Now import updated feed to trigger a second revision to be created. $feed->setSource($this->resourcesPath() . '/csv/content_updated.csv'); $feed->save(); $feed->import(); $node = Node::load(1); $second_revision_id = $node->getRevisionId(); if ($is_enabled) { // When revision is enabled the first revision should not be the same as // the second one. $this->assertNotSame($first_revision_id, $second_revision_id); } else { // When revision is disabled the first revision should be the same as // second one. $this->assertSame($first_revision_id, $second_revision_id); } } /** * Data provider for ::testRevisionToggle(). */ public function provideToggleRevision() { return [ 'enable revision' => [TRUE], 'disable revision' => [FALSE], ]; } /** * Tests importing new revisions with mapping to revision fields. */ public function testWithMappingToRevisionFields() { // Create a user with ID 42. $this->createUser([ 'uid' => 42, ]); // Create a feed type, map to body field. Set it to update existing items // and enable revision setting. $feed_type = $this->createFeedTypeForCsv([ 'guid' => 'guid', 'title' => 'title', 'created' => 'created', 'alpha' => 'alpha', 'beta' => 'beta', 'body' => 'body', ], [ 'processor_configuration' => [ 'update_existing' => ProcessorInterface::UPDATE_EXISTING, 'authorize' => FALSE, 'revision' => TRUE, 'values' => [ 'type' => 'article', ], ], 'mappings' => array_merge($this->getDefaultMappings(), [ [ 'target' => 'body', 'map' => ['value' => 'body'], 'settings' => ['format' => 'plain_text'], ], ]), ]); // Import first feed to create the first revision. $feed = $this->createFeed($feed_type->id(), [ 'source' => $this->resourcesPath() . '/csv/content.csv', ]); $feed->import(); // Now map to certain fields related to the revision. $feed_type->addMapping([ 'target' => 'revision_timestamp', 'map' => ['value' => 'created'], ])->addMapping([ 'target' => 'revision_log', 'map' => ['value' => 'alpha'], ])->addMapping([ 'target' => 'revision_uid', 'map' => ['target_id' => 'beta'], 'settings' => [ 'reference_by' => 'uid', 'autocreate' => FALSE, ], ])->save(); // Reload feed and import again. Mapping has changed, so an update should // happen. $feed = $this->reloadEntity($feed); $feed->import(); // Assert values of revision 2. $node = Node::load(1); $this->assertEquals(3, $node->getRevisionId()); $this->assertEquals(1251936720, $node->revision_timestamp->value); $this->assertEquals('Lorem', $node->revision_log->value); $this->assertEquals(42, $node->revision_uid->target_id); // And assert values of revision 1. $revision1 = $this->container->get('entity_type.manager') ->getStorage('node') ->loadRevision(1); $this->assertNotEquals(1251936720, $revision1->revision_timestamp->value); $this->assertEquals('', $revision1->revision_log->value); $this->assertEquals(0, $revision1->revision_uid->target_id); } } Loading
config/schema/feeds.schema.yml +2 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ feeds.feed_type.*: unique: type: ignore action.configuration.feeds_feed_delete_action: type: action_configuration_default label: 'Delete feeds configuration' Loading Loading @@ -188,6 +187,8 @@ feeds.processor.entity: type: boolean authorize: type: boolean revision: type: boolean expire: type: integer owner_feed_author: Loading
src/Feeds/Processor/EntityProcessorBase.php +7 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,12 @@ abstract class EntityProcessorBase extends ProcessorBase implements EntityProces $feeds_item = $entity->get('feeds_item')->getItemByFeed($feed, TRUE); $feeds_item->hash = $hash; // Set new revision if needed. if ($this->configuration['revision']) { $entity->setNewRevision(TRUE); $entity->setRevisionCreationTime($this->dateTime->getRequestTime()); } // Set field values. $this->map($feed, $entity, $item); Loading Loading @@ -748,6 +754,7 @@ abstract class EntityProcessorBase extends ProcessorBase implements EntityProces 'skip_hash_check' => FALSE, 'values' => [], 'authorize' => $this->entityType->entityClassImplements('Drupal\user\EntityOwnerInterface'), 'revision' => FALSE, 'expire' => static::EXPIRE_NEVER, 'owner_id' => 0, 'owner_feed_author' => 0, Loading
src/Feeds/Processor/Form/DefaultEntityProcessorForm.php +10 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,16 @@ class DefaultEntityProcessorForm extends ExternalPluginFormBase implements Conta ]; } if ($entity_type->entityClassImplements('\Drupal\Core\Entity\RevisionableInterface')) { $form['advanced']['revision'] = [ '#type' => 'checkbox', '#title' => $this->t('New revision'), '#description' => $this->t('Save as new revision.'), '#default_value' => $this->plugin->getConfiguration('revision'), '#parents' => ['processor_configuration', 'revision'], ]; } $form['advanced']['skip_hash_check'] = [ '#type' => 'checkbox', '#title' => $this->t('Force update'), Loading
tests/src/Kernel/RevisionableEntityTest.php 0 → 100644 +206 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\feeds\Kernel; use Drupal\feeds\Plugin\Type\Processor\ProcessorInterface; use Drupal\node\Entity\Node; use Drupal\node\Entity\NodeType; /** * Tests the feature of save a new revision. * * @group feeds */ class RevisionableEntityTest extends FeedsKernelTestBase { /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->setUpBodyField(); } /** * {@inheritdoc} */ protected function setUpNodeType() { // Create a content type. $this->nodeType = NodeType::create([ 'type' => 'article', 'name' => 'Article', // Ensure that this node type is revisionable. 'new_revision' => TRUE, ]); $this->nodeType->save(); } /** * Tests the revision toggle configuration. * * @dataProvider provideToggleRevision */ public function testRevisionToggle($is_enabled) { $feed_type = $this->createFeedType([ 'fetcher' => 'directory', 'fetcher_configuration' => [ 'allowed_extensions' => 'csv', ], 'parser' => 'csv', 'processor_configuration' => [ 'update_existing' => ProcessorInterface::UPDATE_EXISTING, 'authorize' => FALSE, // Using the data provider, enable or disable the revision accordingly. 'revision' => $is_enabled, 'values' => [ 'type' => 'article', ], ], 'custom_sources' => [ 'title' => [ 'label' => 'title', 'value' => 'title', 'machine_name' => 'title', ], 'body' => [ 'label' => 'body', 'value' => 'body', 'machine_name' => 'body', ], ], 'mappings' => [ [ 'target' => 'title', 'map' => ['value' => 'title'], 'unique' => ['value' => TRUE], 'settings' => [ 'language' => NULL, ], ], [ 'target' => 'body', 'map' => ['value' => 'body', 'summary' => ''], 'settings' => ['format' => 'plain_text'], ], ], ]); // Import first feed to create the first revision. $feed = $this->createFeed($feed_type->id(), [ 'source' => $this->resourcesPath() . '/csv/content.csv', ]); $feed->import(); $node = Node::load(1); $first_revision_id = $node->getRevisionId(); // Now import updated feed to trigger a second revision to be created. $feed->setSource($this->resourcesPath() . '/csv/content_updated.csv'); $feed->save(); $feed->import(); $node = Node::load(1); $second_revision_id = $node->getRevisionId(); if ($is_enabled) { // When revision is enabled the first revision should not be the same as // the second one. $this->assertNotSame($first_revision_id, $second_revision_id); } else { // When revision is disabled the first revision should be the same as // second one. $this->assertSame($first_revision_id, $second_revision_id); } } /** * Data provider for ::testRevisionToggle(). */ public function provideToggleRevision() { return [ 'enable revision' => [TRUE], 'disable revision' => [FALSE], ]; } /** * Tests importing new revisions with mapping to revision fields. */ public function testWithMappingToRevisionFields() { // Create a user with ID 42. $this->createUser([ 'uid' => 42, ]); // Create a feed type, map to body field. Set it to update existing items // and enable revision setting. $feed_type = $this->createFeedTypeForCsv([ 'guid' => 'guid', 'title' => 'title', 'created' => 'created', 'alpha' => 'alpha', 'beta' => 'beta', 'body' => 'body', ], [ 'processor_configuration' => [ 'update_existing' => ProcessorInterface::UPDATE_EXISTING, 'authorize' => FALSE, 'revision' => TRUE, 'values' => [ 'type' => 'article', ], ], 'mappings' => array_merge($this->getDefaultMappings(), [ [ 'target' => 'body', 'map' => ['value' => 'body'], 'settings' => ['format' => 'plain_text'], ], ]), ]); // Import first feed to create the first revision. $feed = $this->createFeed($feed_type->id(), [ 'source' => $this->resourcesPath() . '/csv/content.csv', ]); $feed->import(); // Now map to certain fields related to the revision. $feed_type->addMapping([ 'target' => 'revision_timestamp', 'map' => ['value' => 'created'], ])->addMapping([ 'target' => 'revision_log', 'map' => ['value' => 'alpha'], ])->addMapping([ 'target' => 'revision_uid', 'map' => ['target_id' => 'beta'], 'settings' => [ 'reference_by' => 'uid', 'autocreate' => FALSE, ], ])->save(); // Reload feed and import again. Mapping has changed, so an update should // happen. $feed = $this->reloadEntity($feed); $feed->import(); // Assert values of revision 2. $node = Node::load(1); $this->assertEquals(3, $node->getRevisionId()); $this->assertEquals(1251936720, $node->revision_timestamp->value); $this->assertEquals('Lorem', $node->revision_log->value); $this->assertEquals(42, $node->revision_uid->target_id); // And assert values of revision 1. $revision1 = $this->container->get('entity_type.manager') ->getStorage('node') ->loadRevision(1); $this->assertNotEquals(1251936720, $revision1->revision_timestamp->value); $this->assertEquals('', $revision1->revision_log->value); $this->assertEquals(0, $revision1->revision_uid->target_id); } }