Move clearing the target from the processor to the target plugin

Created on 25 April 2023, over 1 year ago
Updated 27 April 2023, over 1 year ago

Problem/Motivation

In \Drupal\feeds\Feeds\Processor\EntityProcessorBase::clearTarget() a field on the entity is cleared in the following way:

unset($entity_target->{$target_name});

This implies that the field name is always equal to the target name. This is not true when you have multiple FeedsTarget plugins for the same field.

For example, in my sandbox project " Feeds DEV " there is FeedsTarget plugin called "file_base64" that provides an alternative file target and converts a base64 string to a file. The target name is then for example "field_file:base64".
In this case Feeds tries to clear $entity->field_file:base64 which makes no sense. It should clear $entity->field_file instead.

Steps to reproduce

Implement a FeedsTarget plugin where the target name is different from the field name.

Proposed resolution

Keep EntityProcessorBase::clearTarget(), but move the task from clearing the actual field on the entity to the target plugin.

Remaining tasks

  • Review.
  • Commit.

User interface changes

More than one target for a particular field can become visible in the UI, depending if multiple FeedsTarget plugins for the same field are implemented. Feeds itself doesn't have this.

API changes

  • \Drupal\feeds\Plugin\Type\Target\TargetInterface will get a new method called clearTarget():
    /**
     * Clears the target on an object.
     *
     * @param \Drupal\feeds\FeedInterface $feed
     *   The feed object.
     * @param \Drupal\Core\Entity\EntityInterface $entity
     *   The target object.
     * @param string $target
     *   The name of the target to unset.
     */
    public function clearTarget(FeedInterface $feed, EntityInterface $entity, string $target);
    
  • The signature for EntityProcessorBase::clearTarget() changes so the feed can be passed to the target:
    /**
     * Clears the target on the entity.
     *
     * @param \Drupal\feeds\FeedInterface $feed
     *   The feed object.
     * @param \Drupal\Core\Entity\EntityInterface $entity
     *   The entity to clear the target on.
     * @param \Drupal\feeds\Plugin\Type\Target\TargetInterface $target
     *   The target plugin.
     * @param string $target_name
     *   The property to clear on the entity.
     */
    protected function clearTarget(FeedInterface $feed, EntityInterface $entity, TargetInterface $target, $target_name) {
    

Data model changes

None.

Patch will follow.

📌 Task
Status

Fixed

Version

3.0

Component

Code

Created by

🇳🇱Netherlands megachriz

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @megachriz
  • Issue was unassigned.
  • Status changed to Needs review over 1 year ago
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.5 + Environment: PHP 7.4 & MySQL 5.7
    last update over 1 year ago
    701 pass
  • 🇳🇱Netherlands megachriz

    Let's see if this breaks any tests.

  • 🇫🇷France andypost
    +++ b/src/Feeds/Processor/EntityProcessorBase.php
    @@ -1322,7 +1324,7 @@ abstract class EntityProcessorBase extends ProcessorBase implements EntityProces
    -    unset($entity_target->{$target_name});
    +    $target->clearTarget($feed, $entity_target, $target_name);
    
    +++ b/src/Plugin/Type/Target/TargetBase.php
    @@ -57,6 +59,13 @@ abstract class TargetBase extends PluginBase implements TargetInterface, PluginF
    +  public function clearTarget(FeedInterface $feed, EntityInterface $entity, string $target) {
    +    unset($entity->{$target});
    

    Any reason to pass a feed object if it's unused?

  • 🇳🇱Netherlands megachriz

    Yes, it is for consistency with other methods in \Drupal\feeds\Plugin\Type\Target\TargetInterface, most notably setTarget() and isEmpty():

    /**
     * Sets the values on an object.
     *
     * @param \Drupal\feeds\FeedInterface $feed
     *   The feed object.
     * @param \Drupal\Core\Entity\EntityInterface $entity
     *   The target object.
     * @param string $target
     *   The name of the target to set.
     * @param array $values
     *   A list of values to set on the target.
     */
    public function setTarget(FeedInterface $feed, EntityInterface $entity, $target, array $values);
    
    /**
     * Returns if the value for the target is empty.
     *
     * @param \Drupal\feeds\FeedInterface $feed
     *   The feed object.
     * @param \Drupal\Core\Entity\EntityInterface $entity
     *   The target object.
     * @param string $target
     *   The name of the target to set.
     *
     * @return bool
     *   True if the value on the entity is empty. False otherwise.
     */
    public function isEmpty(FeedInterface $feed, EntityInterface $entity, $target);
    
  • Status changed to RTBC over 1 year ago
  • 🇫🇷France andypost

    then it look great)

    • MegaChriz committed e0ad4a42 on 8.x-3.x
      Issue #3356227 by MegaChriz, andypost: Moved clearing the target (aka...
  • Status changed to Fixed over 1 year ago
  • 🇳🇱Netherlands megachriz

    Thanks for looking, @andypost!

    Committed #2.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024