Drupal 7 feeds 导入插件编写


在drupal中使用feeds导入数据。

如果需要导入的数据是自定义的 entity 就需要写导入插件。

使用下面的 hook 定义解析器

/**
 * Implements hook_feeds_plugins().
 */
function history_import_feeds_plugins() {
  $info = [];
  $info['HistoryImportProcessor'] = [
    'name' => '历史导入解析器',
    'description' => '历史导入解析器.',
    'help' => '历史导入解析器.',
    'handler' => [
      'parent' => 'FeedsProcessor',
      'class' => HistoryImportProcessor::class,
    ],
  ];
  return $info;
}

下面是解析实现类

<?php


namespace Drupal\history_import\plugins;


use Drupal\history_import\Entity\HistoryImport;
use FeedsParserResult;
use FeedsProcessor;
use FeedsSource;

class HistoryImportProcessor extends FeedsProcessor {


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

  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 'phone':
          {
            $jHistoryImports = entity_load('history_import', FALSE, ['phone' => $value]);
            if (!empty($jHistoryImports)) {
              $jHistoryImport = reset($jHistoryImports);
              if ($jHistoryImport instanceof HistoryImport) {
                return $jHistoryImport->id;
              }
            }
            break;
          }
      }
    }
    return 0;
  }


  protected function entitySave($entity) {
    $entity->save();
  }

  protected function newEntity(FeedsSource $source) {
    $jHistoryImport = new HistoryImport();
    $jHistoryImport->uid = 0;
    $jHistoryImport->status = 0;
    return $jHistoryImport;
  }

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


  public function getMappingTargets() {
    $targets = parent::getMappingTargets();
    $targets['id'] = [
      'name' => t('ID'),
      'optional_unique' => TRUE,
    ];
    $targets['phone'] = [
      'name' => t('手机号'),
      'optional_unique' => TRUE,
    ];
    $targets['parent'] = [
      'name' => t('上家手机号'),
    ];
    $targets['recharge'] = [
      'name' => t('剩余未消费(未治疗)'),
    ];
    $targets['balance'] = [
      'name' => t('剩余待提现金额(账户余额)'),
    ];
    $targets['is_staff'] = [
      'name' => t('是否是员工'),
    ];
    $targets['staff'] = [
      'name' => t('员工编号'),
    ];
    $targets['is_quit'] = [
      'name' => t('是否离职'),
    ];
    $targets['in_store'] = [
      'name' => t('所属门店'),
    ];
    $this->getHookTargets($targets);
    return $targets;
  }

  public function setTargetElement(FeedsSource $source, $jHistoryImport, $target_element, $value) {
    switch ($target_element) {
      case 'recharge':
        $this->setAmount($source, $jHistoryImport, $target_element, $value);
        break;
      case 'balance':
        $this->setAmount($source, $jHistoryImport, $target_element, $value);
        break;
      case 'phone':
        $this->setPhone($source, $jHistoryImport, $target_element, $value);
        break;
      default:
        parent::setTargetElement($source, $jHistoryImport, $target_element, $value);
        break;
    }
  }

  function setAmount(FeedsSource $source, HistoryImport $jHistoryImport, $target_element, $value) {
    switch ($target_element) {
      case 'recharge':
        $jHistoryImport->recharge = $value * 100;
        break;
      case 'balance':
        $jHistoryImport->balance = $value * 100;
        break;
    }
  }

  function setPhone(FeedsSource $source, HistoryImport $jHistoryImport, $target_element, $value) {
    $jHistoryImport->phone = $value;
    //检查是否已注册
    $account = $this->checkPhoneRegister($value);
    if ($account) {
      $jHistoryImport->uid = $account->uid;
      $jHistoryImport->status = 1;
    }
  }

  protected function checkPhoneRegister($phone) {
    $query = new \EntityFieldQuery();
    $query->entityCondition('entity_type', 'profile2');
    $query->entityCondition('bundle', 'official');
    $query->fieldCondition('phone', 'value', $phone);
    $query->range(0, 1);
    $result = $query->execute();
    if (!empty($result)) {
      $entities = entity_load('profile2', array_keys($result['profile2']));
      if (!empty($entities)) {
        $profile = reset($entities);
        if ($profile instanceof \Profile) {
          $account = user_load($profile->uid);
          if (!empty($account)) {
            return $account;
          }
        }
      }
    }
    return FALSE;
  }
}

然后在 feeds 中配置即可

Image: