Drupal7 feeds 导入时需要多个源才能确定唯一值的处理


<?php


namespace Drupal\ew_cargo_plan\Plugins;


use Drupal\ew_cargo_plan\Entity\EwCargoPlan;
use Drupal\ew_channel\Entity\EwChannel;
use Drupal\ew_product\Entity\EwProduct;
use Drupal\ew_product_stock\Entity\EwProductStock;
use FeedsParserResult;
use FeedsProcessor;
use FeedsSource;

class EwCargoPlanFeedsProcessor extends FeedsProcessor {

  protected $channel_id = '';

  protected $product_id = '';

  public function getMappingTargets() {
    $targets = parent::getMappingTargets();
    $targets['id'] = [
      'name' => t('ID'),
      'optional_unique' => TRUE,
    ];
    $targets['channel_id'] = [
      'name' => t('渠道'),
      'optional_unique' => TRUE,
    ];
    $targets['p_sku'] = [
      'name' => t('编码'),
      'optional_unique' => TRUE,
    ];
    $targets['p_product'] = [
      'name' => t('产品'),
    ];
    $targets['p_standard'] = [
      'name' => t('规格'),
    ];

    $targets['company_stock'] = [
      'name' => t('公司库存'),
    ];
    $targets['production_stock'] = [
      'name' => t('在产库存'),
    ];

    $targets['note'] = [
      'name' => t('备注'),
    ];
    for ($i = 1; $i <= 12; $i++) {
      $targets["number{$i}"] = [
        'name' => t('@i周', ['@i' => $i]),
      ];
    }
    $this->getHookTargets($targets);
    return $targets;
  }

  public function setTargetElement(FeedsSource $source, $entity, $target_element, $value) {
    if ($entity instanceof EwCargoPlan) {
      switch ($target_element) {
        case 'channel_id':
          $value = trim($value);
          $es = ew_channel_load_multiple(FALSE, ['title' => $value]);
          if (!empty($es)) {
            $e = reset($es);
            if ($e instanceof EwChannel) {
              $entity->channel_id = $e->id;
            }
          }
          break;
        case 'p_sku':
          $value = trim($value);
          $es = ew_product_load_multiple(FALSE, ['sku' => $value]);
          if (!empty($es)) {
            $e = reset($es);
            if ($e instanceof EwProduct) {
              $entity->product_id = $e->id;
            }
          }
          break;
        case 'company_stock':
          $es = ew_product_stock_load_multiple(FALSE, [
            'product_id' => $entity->product_id,
          ]);
          if (!empty($es)) {
            $e = reset($es);
          }
          else {
            $e = new EwProductStock();
            $e->product_id = $entity->product_id;
          }
          if ($e instanceof EwProductStock) {
            $e->company_stock = $value;
            $e->save();
          }
          break;
        case 'production_stock':
          $es = ew_product_stock_load_multiple(FALSE, [
            'product_id' => $entity->product_id,
          ]);
          if (!empty($es)) {
            $e = reset($es);
          }
          else {
            $e = new EwProductStock();
            $e->product_id = $entity->product_id;
          }
          if ($e instanceof EwProductStock) {
            $e->production_stock = $value;
            $e->save();
          }
          break;
        default:
          parent::setTargetElement($source, $entity, $target_element, $value);
          break;
      }
    }
  }

  /**
   * Implements parent::entityInfo().
   */
  protected function entityInfo() {
    $info = parent::entityInfo();
    $info['label plural'] = t('要货计划');
    return $info;
  }

  protected function existingEntityId(FeedsSource $source, FeedsParserResult $result) {
    $entity_id = parent::existingEntityId($source, $result);
    if ($entity_id) {
      return $entity_id;
    }
    foreach ($this->uniqueTargets($source, $result) as $target => $value) {
      switch ($target) {
        case 'id':
          $value = trim($value);
          $e = ew_cargo_plan_load($value);
          if ($e instanceof EwCargoPlan) {
            return $e->id;
          }
          break;
        case 'channel_id':
          $value = trim($value);
          $es = ew_channel_load_multiple(FALSE, ['title' => $value]);
          if (!empty($es)) {
            $e = reset($es);
            if ($e instanceof EwChannel) {
              $this->channel_id = $e->id;
            }
          }
          if (!empty($this->channel_id) && !empty($this->product_id)) {
            $plans = ew_cargo_plan_load_multiple(FALSE, [
              'channel_id' => $this->channel_id,
              'product_id' => $this->product_id,
            ]);
            if (!empty($plans)) {
              $plan = reset($plans);
            }
            else {
              $plan = new EwCargoPlan();
              $plan->channel_id = $this->channel_id;
              $plan->product_id = $this->product_id;
            }
            if ($plan instanceof EwCargoPlan && $plan->id > 0) {
              $this->channel_id = '';
              $this->product_id = '';
              return $plan->id;
            }
          }
          break;
        case 'p_sku':
          $value = trim($value);
          $es = ew_product_load_multiple(FALSE, ['sku' => $value]);
          if (!empty($es)) {
            $e = reset($es);
            if ($e instanceof EwProduct) {
              $this->product_id = $e->id;
            }
          }
          if (!empty($this->channel_id) && !empty($this->product_id)) {
            $plans = ew_cargo_plan_load_multiple(FALSE, [
              'channel_id' => $this->channel_id,
              'product_id' => $this->product_id,
            ]);
            if (!empty($plans)) {
              $plan = reset($plans);
            }
            else {
              $plan = new EwCargoPlan();
              $plan->channel_id = $this->channel_id;
              $plan->product_id = $this->product_id;
            }
            if ($plan instanceof EwCargoPlan && $plan->id > 0) {
              $this->channel_id = '';
              $this->product_id = '';
              return $plan->id;
            }
          }
          break;
      }
    }
    return 0;
  }

  protected function entitySave($entity) {
    if ($entity instanceof EwCargoPlan) {
      if ($entity->channel_id > 0 && $entity->product_id > 0) {
        $entity->save();
      }
    }
  }

  protected function newEntity(FeedsSource $source) {
    $entity = new EwCargoPlan();
    return $entity;
  }

  protected function entityDeleteMultiple($entity_ids) {
    entity_delete_multiple($this->entityType(), $entity_ids);
  }

  public function entityType() {
    return 'ew_cargo_plan';
  }
}

feeds插件编写如上

核心在于需要参与计算唯一的都进行唯一标记

后台全部勾选参与计算

然后在代码处理时使用class传递,当全部值收集完毕后才获取唯一

tip

也可以在entity层面save时进行处理.

Image: