diff --git a/feeds.info.yml b/feeds.info.yml index 8d3681b9..568134a7 100644 --- a/feeds.info.yml +++ b/feeds.info.yml @@ -4,3 +4,4 @@ package: Feeds type: module core_version_requirement: ^9.3 || ^10 configure: entity.feeds_feed_type.collection +php: 8.1 diff --git a/feeds.module b/feeds.module index 487d14a2..3a17757f 100644 --- a/feeds.module +++ b/feeds.module @@ -7,6 +7,8 @@ use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\Xss; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\Core\Routing\RouteMatchInterface; @@ -267,3 +269,33 @@ function template_preprocess_feeds_feed(array &$variables) { // Add article ARIA role. $variables['attributes']['role'] = 'article'; } + +/** + * Implements hook_entity_presave(). + */ +function feeds_entity_presave(EntityInterface $entity) { + if ($entity instanceof FieldableEntityInterface && $entity->hasField('feeds_item')) { + /** @var \Drupal\feeds\FeedsItemInterface */ + $feeds_item = $entity->get('feeds_item')->first(); + if ($feeds_item) { + foreach ($feeds_item->getPreSaveOperations() as $callable) { + $callable($entity); + } + } + } +} + +/** + * Implements hook_entity_postsave(). + */ +function feeds_entity_postsave(EntityInterface $entity) { + if ($entity instanceof FieldableEntityInterface && $entity->hasField('feeds_item')) { + /** @var \Drupal\feeds\FeedsItemInterface */ + $feeds_item = $entity->get('feeds_item')->first(); + if ($feeds_item) { + foreach ($feeds_item->getPostSaveOperations() as $callable) { + $callable($entity); + } + } + } +} diff --git a/src/Feeds/Target/Changed.php b/src/Feeds/Target/Changed.php new file mode 100644 index 00000000..3fcfd6d5 --- /dev/null +++ b/src/Feeds/Target/Changed.php @@ -0,0 +1,55 @@ +convertToDate($values['value']); + + if ($date instanceof DateTimePlus) { + $values['value'] = $date->getTimestamp(); + } + else { + $values['value'] = REQUEST_TIME; + } + } + + /** + * {@inheritdoc} + */ + public function setTarget(FeedInterface $feed, EntityInterface $entity, $field_name, array $values) { + parent::setTarget($feed, $entity, $field_name, $values); + + if ($values = $this->prepareValues($values)) { + $entity_target = $this->getEntityTarget($feed, $entity); + if (!empty($entity_target)) { + + $closure = \Closure::fromCallable(function(EntityInterface $entity) use ($field_name, $values) { + $item_list = $entity->get($field_name); + $values = array_merge($item_list->getValue(), $values); + $item_list->setValue($values); + }); + + $entity_target->get('feeds_item')->first()->addPreSaveOperation($closure); + } + } + } +} diff --git a/src/FeedsItemInterface.php b/src/FeedsItemInterface.php index 88d9f715..b2d9e02b 100644 --- a/src/FeedsItemInterface.php +++ b/src/FeedsItemInterface.php @@ -17,4 +17,36 @@ interface FeedsItemInterface extends FieldItemInterface { */ public function getUrl(); + /** + * Add a callable to be invoked during entity pre-save. + * + * @var Callable $c + * The operation to be invoked. + */ + public function addPreSaveOperation(Callable $c) ; + + /** + * Add a callable to be invoked during entity post-save. + * + * @var Callable $c + * The operation to be invoked. + */ + public function addPostSaveOperation(Callable $c); + + /** + * Retrieve all operations to be invoked during entity pre-save. + * + * @return Callable[] + * Array of callables to be invoked. + */ + public function getPreSaveOperations() : array; + + /** + * Retrieve all operations to be invoked during entity post-save. + * + * @return Callable[] + * Array of callables to be invoked. + */ + public function getPostSaveOperations() : array; + } diff --git a/src/Plugin/Field/FieldType/FeedsItem.php b/src/Plugin/Field/FieldType/FeedsItem.php index bd848d32..c9058b5c 100644 --- a/src/Plugin/Field/FieldType/FeedsItem.php +++ b/src/Plugin/Field/FieldType/FeedsItem.php @@ -25,6 +25,48 @@ use Drupal\feeds\FeedsItemInterface; */ class FeedsItem extends EntityReferenceItem implements FeedsItemInterface { + /** + * Entity pre-save operations can be added as a callable. + * + * @var Callable[] + */ + protected $preSave = []; + + /** + * Entity post-save operations can be added as a callable. + * + * @var Callable[] + */ + protected $postSave = []; + + /** + * {@inheritdoc} + */ + public function addPreSaveOperation(Callable $c) { + $this->preSave[] = $c; + } + + /** + * {@inheritdoc} + */ + public function addPostSaveOperation(Callable $c) { + $this->postSave[] = $c; + } + + /** + * {@inheritdoc} + */ + public function getPreSaveOperations() : array { + return $this->preSave; + } + + /** + * {@inheritdoc} + */ + public function getPostSaveOperations() : array { + return $this->postSave; + } + /** * {@inheritdoc} */