ฉันจะโอนย้ายเอนทิตีไฟล์ไปยังเอนทิตีสื่อได้อย่างไร


10

ฉันกำลังใช้โมดูลโยกย้ายสำหรับการโยกย้าย D7 ถึง D8 และฉันกำลังเขียนการโยกย้ายทั้งหมดด้วยตนเองในรหัส (แทนที่จะใช้โมดูลการโยกย้าย D7 ในตัวเนื่องจากฉันต้องการการควบคุมการย้ายที่ละเอียดยิ่งขึ้น)

ฉันมีโครงสร้างต่อไปนี้: ไซต์ D7 มีฟิลด์รูปภาพที่เก็บรูปภาพเป็นเอนทิตีไฟล์ บนไซต์ D8 เขตข้อมูลรูปภาพเป็นการอ้างอิงเอนทิตีไปยังเอนทิตีสื่อ (และเอนทิตีสื่อจะมีเขตข้อมูลรูปภาพ)

เดิมทีฉันมีสิ่งต่อไปนี้สำหรับการโยกย้ายรูปภาพของฉัน:

id: image_files

source:
  plugin: legacy_images
  constants:
    source_base_path: http://example.com/

destination:
  plugin: 'entity:file'

process:
  fid: fid
  filename: filename
  source_full_path:
    -
      plugin: concat
      delimiter: /
      source:
    -     constants/source_base_path
    -     uri
    -
      plugin: urlencode
  uri:
    plugin: file_copy
    source:
      - '@source_full_path'
      - uri
  filemime: filemime
  status: status

ภายในไฟล์การย้ายข้อมูลโหนดบทความของฉันฉันมีต่อไปนี้:

'field_article_image/target_id':
plugin: migration
migration: image_files
source: field_article_image 

แต่ฉันรู้ว่ามันจะไม่ทำงาน target_id ที่มาจากการโยกย้าย image_files เป็น ID ของเอนทิตีของไฟล์ไม่ใช่ ID เอนทิตีของสื่อ ในโลกอุดมคติฉันต้องการค้นหาวิธีในการสร้างการย้ายข้อมูลครั้งที่สามซึ่งจะสร้างขั้นตอนกลางนี้และโอนย้ายเอนทิตีไฟล์ไปยังหน่วยงานสื่อแล้วแมปการโยกย้ายนั้นไปยังการโยกย้ายบทความ อย่างไรก็ตามฉันไม่สามารถหาวิธีที่ดีในการทำเช่นนี้

แผน B จะเป็นการสร้างปลั๊กอินกระบวนการสำหรับการย้ายรูปภาพซึ่งจะสร้างเอนทิตีไฟล์ด้วยตนเองแนบกับเอนทิตีสื่อและผ่านการโยกย้ายนั้นไปยังบทความ (ซึ่งจะเป็นการลบขั้นตอนกลาง) แม้ว่าจะสามารถย้อนกลับเอนทิตีสื่อได้ แต่ไฟล์เอนทิตีไม่สามารถทำได้

คำตอบ:


4

ฉันสิ้นสุดการเลือกที่จะทำแตกต่างกันเล็กน้อย - ฉันสร้างการนำเข้าไฟล์ปกติตั้งค่าการโยกย้ายนั้นเป็นแหล่งข้อมูลสำหรับฟิลด์อ้างอิงเอนทิตีสื่อของฉันแล้วใช้ปลั๊กอินกระบวนการที่สอง 'MediaGenerate' เพื่อแปล FID เป็นสื่อใหม่ target_id

<?php

namespace Drupal\my_migration\Plugin\migrate\process;

use Drupal\media_entity\Entity\Media;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Row;
use Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate;

/**
 * Generate a media entity with specified metadata.
 *
 * This plugin is to be used by migrations which have media entity reference
 * fields.
 *
 * Available configuration keys:
 * - destinationField: the name of the file field on the media entity.
 *
 * @code
 * process:
 *   'field_files/target_id':
 *     -
 *       plugin: migration
 *       source: files
 *     -
 *       plugin: media_generate
 *       destinationField: image
 *
 * @endcode
 *
 * @MigrateProcessPlugin(
 *   id = "media_generate"
 * )
 */
class MediaGenerate extends EntityGenerate {

/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) {
if (!isset($this->configuration['destinationField'])) {
  throw new MigrateException('Destination field must be set.');
}
// First load the target_id of the file referenced via the migration.
/* @var /Drupal/file/entity/File $file */
$file = $this->entityManager->getStorage('file')->load($value);

if (empty($file)) {
  throw new MigrateException('Referenced file does not exist');
}

// Creates a media entity if the lookup determines it doesn't exist.
$fileName = $file->label();
if (!($entityId = parent::transform($fileName, $migrateExecutable, $row, $destinationProperty))) {
  return NULL;
}
$entity = Media::load($entityId);

$fileId = $file->id();
$entity->{$this->configuration['destinationField']}->setValue($fileId);
$entity->save();

return $entityId;
}

}

1
การกำหนดค่าปลายทางของฟิลด์คืออะไร
dba

field_media_imageโอเคฉันคิดว่ามันออกมาด้วยตัวเองมันเป็นสนามสำหรับสินทรัพย์ประเภทสื่อสำหรับภาพนี้คือ
dba

คุณจะจัดการกับคุณสมบัติไฟล์ alt / title ได้อย่างไร
mpp

ผ่านการทดสอบและใช้งานได้เป็นอย่างดีอย่างไรก็ตามคุณอาจจะต้องใช้ปลั๊กอิน "migration_lookup" เพราะปลั๊กอิน "การโอนย้ายข้อมูล" ถูกคัดค้านและไม่สามารถใช้งานกับเวอร์ชันล่าสุดของฉันได้ ต่อไปนี้ทำงานเพื่อให้ฉันนำเข้ารูปภาพผู้ใช้: ปลั๊กอิน: migration_lookup การโยกย้าย: my_file_migration แหล่งที่มา: รูปภาพนอกจากนี้หากคุณโอนย้ายเอนทิตีที่ไม่มีบันเดิล (เช่นรูปภาพผู้ใช้) คุณอาจต้องแก้ไขจากที่นี่: drupal.org/project/migrate_plus/issues / 2787219มิฉะนั้นคุณจะได้รับข้อผิดพลาด "ปลั๊กอินเอนทิตีค้นหาต้องการค่า value ไม่มีอยู่" ในการโยกย้าย
Mirsoft

ใครช่วยกรุณาอธิบายได้ว่า $ entityId พบได้ในเรื่องนี้อย่างไร?
หมากเก็บ

2

ฉันชื่นชมคำตอบที่ได้รับการยอมรับมากมาย แต่มีคำจำกัดความที่เลิกใช้แล้วและไม่สนับสนุนการโพสต์คุณสมบัติ alt และชื่อภาพ ดังนั้นฉันจึงปรับปรุงเล็กน้อยเพื่อรองรับสิ่งนั้นและทำงานอย่างราบรื่นด้วย Drupal รุ่นล่าสุด 8.6.x นี่คือรหัสของ MediaGenerate.php (ไวยากรณ์ Yaml ที่เหมาะสมอยู่ในความคิดเห็นของ doc):

<?php

namespace Drupal\my_migration\Plugin\migrate\process;

use Drupal\media\Entity\Media;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Row;
use Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate;

/**
 * Generate a media entity with specified metadata.
 *
 * This plugin is to be used by migrations which have media entity reference
 * fields.
 *
 * Available configuration keys:
 * - destinationField: the name of the file field on the media entity.
 *
 * @code
 * process:
 *   'field_files/target_id':
 *     -
 *       plugin: migration_lookup
 *       migration: my_file_migration
 *       source: field_image/0/fid
 *     -
 *       plugin: media_generate
 *       destinationField: image
 *       imageAltSource: field_image/0/alt
 *       imageTitleSource: field_image/0/title
 *
 * @endcode
 *
 * If image_alt_source and/or image_title_source configuration parameters
 * are provided, alt and/or title image properties will be fetched from provided
 * source fields (if available) and pushed into media entity
 *
 * @MigrateProcessPlugin(
 *   id = "media_generate"
 * )
 */
class MediaGenerate extends EntityGenerate {

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) {
    if (!isset($this->configuration['destinationField'])) {
      throw new MigrateException('Destination field must be set.');
    }

    // First load the target_id of the file referenced via the migration.
    /* @var /Drupal/file/entity/File $file */
    $file = $this->entityManager->getStorage('file')->load($value);

    if (empty($file)) {
      throw new MigrateException('Referenced file does not exist');
    }

    // Creates a media entity if the lookup determines it doesn't exist.
    $fileName = $file->label();
    if (!($entityId = parent::transform($fileName, $migrateExecutable, $row, $destinationProperty))) {
      return NULL;
    }

    $entity = Media::load($entityId);

    $fileId = $file->id();

    $destinationFieldValues = $entity->{$this->configuration['destinationField']}->getValue();
    $destinationFieldValues[0]['target_id'] = $fileId;

    $this->insertPropertyIntoDestinationField($destinationFieldValues, $row, 'alt', 'imageAltSource');
    $this->insertPropertyIntoDestinationField($destinationFieldValues, $row, 'title', 'imageTitleSource');

    $entity->{$this->configuration['destinationField']}->setValue($destinationFieldValues);
    $entity->save();

    return $entityId;
  }

  protected function insertPropertyIntoDestinationField(array &$destinationFieldValues, Row $row, $propertyKey, $configurationKey) {
    // Set alt and title into media entity if not empty
    if (isset($this->configuration[$configurationKey])) {
      $propertyValue = $row->getSourceProperty($this->configuration[$configurationKey]);
      if (!empty($propertyValue)) {
        $destinationFieldValues[0][$propertyKey] = $propertyValue;
      }
    }
  }
}

2

เนื่องจาก Media เป็นประเภทเอนทิตีคุณควรสร้างการย้ายข้อมูลของตนเอง คุณสามารถสร้างแหล่งใหม่จากตารางไฟล์ นี่คือตัวอย่าง

https://gist.github.com/jibran/8e7cd2319e873858dd49a272227a4fd2

จากนั้นmigration_lookupคุณสามารถแมปฟิลด์เช่นนี้ได้

field_d8_media_image/0/target_id:
  plugin: migration_lookup
  migration: my_media_image
  source: field_d7_image/0/fid

0

หากคุณต้องการโอนย้ายไฟล์ใน Drupal 8 ไปยังเอนทิตีสื่อคุณสามารถใช้โมดูลนี้: https://www.drupal.org/project/migrate_file_to_media

มันมีสคริปต์ drush ที่สร้างฟิลด์อ้างอิงสื่อโดยอัตโนมัติ นอกจากนี้ยังตรวจจับภาพที่ซ้ำกันโดยใช้แฮชแบบไบนารี และรองรับการแปล


1
โมดูลนั้นจะแก้ปัญหาการย้ายข้อมูลระหว่างรุ่น D8 ตามค่าเริ่มต้นเท่านั้น คำถามคล้ายกับการโยกย้ายจาก D7 ถึง D8 ดังนั้นจึงไม่สามารถใช้โมดูลได้ง่าย (ปลั๊กอินต้นทางเพิ่มเติมไปยัง MediaEntityGenerator.php ที่จะอ่านข้อมูลจากไฟล์ที่แนบมาใน D7 น่าจะต้องถูกสร้างขึ้น) นอกจากนี้ยังมีความแตกต่างพื้นฐานอย่างหนึ่ง: โมดูล migrate_file_to_media จะแปลงไฟล์ที่แนบมากับเอนทิตีบางอย่างเท่านั้น (= entity_type และบันเดิลจำเป็นในขั้นตอนที่ 1) ในขณะที่โซลูชันที่ได้รับการยอมรับไม่มีข้อกำหนดนี้ แหล่ง
Mirsoft
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.