Support from Acquia helps fund testing for Drupal Acquia logo

Comments

veronicaSeveryn created an issue. See original summary.

MegaChriz’s picture

Issue tags: +feeds tamper

In the D7 version of Feeds, you would do this with the "Keyword filter" plugin from Feeds Tamper, but that module hasn't been ported to D8 yet. Not sure how to accomplish the same in the D8 version.

In the D7 version you could also accomplish this by implementing hook_feeds_after_parse() (Feeds Tamper implemented this hook also). Not sure if this hook has been ported to the D8 version of Feeds. Some hooks were converted to events. See feeds/src/Event. If you know how the event system works in D8, perhaps you could make use of that.

veronicaSeveryn’s picture

We could have used Feeds Event:: PROCESS to set some value to indicate that the row should be skipped, or similar to EmptyFeedException throw some kind of SkipRowProcessingException that could be caught/handled later in the processing workflow, but looks like none of these options are available yet..

veronicaSeveryn’s picture

Here's a version of what I came up with - I added a BOOL variable on Feed Item ($process_current_row) that will indicate whether the row should be processed further.

This variable will checked inside the process() function of EntityProcessorBase class.

This way, I can check the values I need on the Feed Item during Process Event, and if I decide to skip row processing based on some parameters, I can use
$item->skipRowProcessing(TRUE);

I believe I updated all dependent classes... Worked for me. Need someone else take a look at it.

Status: Needs review » Needs work

The last submitted patch, 4: skip_feed_item_processing_2772601_4_d8.patch, failed testing.

veronicaSeveryn’s picture

Uploaded a wrong file. Here's the patch again.

veronicaSeveryn’s picture

Status: Needs work » Needs review
twistor’s picture

Component: Feeds Import (feature) » Code
Status: Needs review » Needs work
  1. +++ b/src/Feeds/Item/BaseItem.php
    @@ -8,6 +8,13 @@ namespace Drupal\feeds\Feeds\Item;
    +  protected $process_current_row = TRUE;
    

    This should be camel case.

  2. +++ b/src/Feeds/Item/DynamicItem.php
    @@ -31,4 +38,20 @@ class DynamicItem implements ItemInterface {
    +  public function skipRowProcessing($skip) {
    +    if ($skip) {
    +      $this->process_current_row = FALSE;
    +    }
    +    return $this;
    +  }
    

    Why are we returning $this?

veronicaSeveryn’s picture

Updated a patch - fixed based on the comment above - and re-based it for the current DEV version status.

Status: Needs review » Needs work

The last submitted patch, 9: skip_feed_item_processing_2772601_9_d8.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

vijay.mayilsamy’s picture

- Updated a patch by applying the coding standards recommended from the previous test results.

MegaChriz’s picture

Category: Support request » Feature request
Status: Needs work » Needs review
FileSize
2.65 KB

This use case is going to be implemented with Feeds Tamper. See also #2937721: Create 'SkipException' classes..

It could perhaps be useful though to make skipping rows easier without Tamper. Attached is a patch for that idea.
Basically you would extend the AfterParseBase class, implement alterItem() and throw a \Drupal\feeds\Exception\SkipItemException when the item to import should be skipped.

selva.swamy@gmail.com’s picture

Hi,
Can someone review and mark this as RTBC if it is fine? We need to do some validations before the excel is accepted for upload. I believe the latest patch should allow us to achieve that. Or is there some other module in D8 which allows to add custom validations for the fields uploaded via feeds?

artematem’s picture

Status: Needs review » Reviewed & tested by the community

Using patch #12 on our live project. Works as expected.

MegaChriz’s picture

Issue tags: -feeds tamper +Needs tests

@artematem
Thanks for trying! I'm using this patch also with success on a few sites, but it would be useful to have an automated test for this feature.

The last submitted patch, 11: skip_feed_item_processing_2772601_11_d8.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

MegaChriz’s picture

Now with a unit test. Also fixes some coding standard issues.

MegaChriz’s picture

  • MegaChriz committed 65afa04 on 8.x-3.x
    Issue #2772601 by MegaChriz, veronicaSeveryn, vijay.mayilsamy, artematem...
MegaChriz’s picture

Status: Reviewed & tested by the community » Fixed

Committed #18.

Status: Fixed » Closed (fixed)

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

tbatzakas’s picture

Hello, I managed to use SkipItemException for my dataset, but since I need to assign my data to different categories using Tamper's Find/Replace I end up unable to match the source data I want to skip. As far as I understand, this is because Tamper also works with FeedEvents::PARSE stage. Is there a way to access the source info instead of the tampered one?

MegaChriz’s picture

@tbatzakas
Yes, you can change the order in which event subscribers are called. Both Feeds Tamper and the AfterParseBase class have set the same priority, which is FeedsEvents::AFTER. This constant equals -10000, see feeds/src/Event/FeedsEvents:

/**
 * After plugin executes priority.
 */
const AFTER = -10000;

For event subscribers, subscribers with a higher value are called first. So to have your subscriber called first before Feeds Tamper's one, you could simply increase the value with one: FeedsEvents::AFTER + 1.

Override the static method getSubscribedEvents() in your custom subscriber class to change the priority:

use Drupal\feeds\Event\FeedsEvents;

/**
 * {@inheritdoc}
 */
public static function getSubscribedEvents() {
  $events = [];
  $events[FeedsEvents::PARSE][] = ['afterParse', FeedsEvents::AFTER + 1];
  return $events;
}
webdrips’s picture

Can someone share their implementation of #12?

@MegaChriz?
@artematem?
@tbatzakas?

webdrips’s picture

I found this to be enough to get me where I needed to go: https://www.drupal.org/project/feeds/issues/3128379

I'm happy to provide a code example if someone needs it.