Làm cách nào để di chuyển các thực thể tệp vào các thực thể truyền thông?


10

Tôi đang sử dụng mô-đun Di chuyển cho việc di chuyển D7 sang D8 và tôi đang viết toàn bộ quá trình di chuyển theo mã (thay vì sử dụng mô-đun di chuyển D7 tích hợp, vì tôi muốn kiểm soát chi tiết hơn khi di chuyển.)

Tôi có cấu trúc như sau: trang web D7 có trường hình ảnh nơi hình ảnh được lưu trữ dưới dạng thực thể Tệp. Trên trang D8, trường hình ảnh là tham chiếu thực thể đến thực thể Phương tiện (và thực thể Phương tiện lần lượt có trường Hình ảnh.)

Ban đầu, tôi đã có những điều sau đây cho việc di chuyển Hình ảnh của mình:

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

Trong tập tin di chuyển nút bài viết của tôi, tôi đã có những điều sau đây:

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

nhưng tôi nhận ra rằng điều này sẽ không hoạt động. Target_id đến từ quá trình di chuyển image_files thực sự là ID thực thể tệp chứ không phải ID thực thể phương tiện. Trong thế giới lý tưởng, tôi muốn tìm cách tạo di chuyển thứ ba, bước này sẽ tạo bước giữa này và di chuyển các thực thể tệp vào Thực thể truyền thông và sau đó ánh xạ di chuyển sang di chuyển Bài viết. Tuy nhiên, tôi không thể tìm ra một cách tốt để làm điều này.

Kế hoạch B đơn giản sẽ là tạo một plugin quy trình cho việc di chuyển hình ảnh, nó sẽ tự tạo các thực thể tệp, đính kèm chúng vào các thực thể phương tiện và chuyển việc di chuyển đó sang Bài viết (việc này sẽ loại bỏ bước giữa). Tuy nhiên, điều này có nghĩa là trong khi các thực thể Media có thể được khôi phục, thì các Thực thể Tệp không thể.

Câu trả lời:


4

Cuối cùng tôi đã chọn cách thực hiện hơi khác một chút - Tôi tạo một tệp nhập thông thường, đặt di chuyển đó làm nguồn cho trường tham chiếu thực thể phương tiện của mình và sau đó áp dụng plugin quy trình thứ hai 'MediaGenerate' để dịch FID sang phương tiện truyền thông mới đích_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
Cấu hình DestinationField là gì?
dba

Ok tôi đã tự mình tìm ra nó, đó là lĩnh vực cho tài sản trong loại phương tiện, cho hình ảnh này là field_media_image.
dba

Làm thế nào để bạn xử lý các thuộc tính alt / title tập tin?
mpp

Đã thử nghiệm và nó hoạt động độc đáo, tuy nhiên bạn có thể sẽ cần sử dụng plugin "Mig_lookup" vì plugin "di chuyển" không được dùng nữa và đã không hoạt động trên các phiên bản mới nhất của tôi. Sau đây làm việc cho tôi để hình ảnh người sử dụng nhập khẩu: plugin: di cư migration_lookup: nguồn my_file_migration: picture Ngoài ra, nếu bạn di chuyển các đối tượng mà không bó (như hình ảnh người sử dụng), bạn có thể sẽ cần các bản vá từ đây: drupal.org/project/migrate_plus/issues / 2787219 , nếu không, bạn sẽ gặp lỗi "Plugin entity_lookup yêu cầu value_key, không có vị trí nào." về di cư.
Mirsoft

Bất cứ ai có thể giải thích làm thế nào $ entityId được tìm thấy trong này?
dibs

2

Tôi đánh giá cao câu trả lời được chấp nhận rất nhiều, tuy nhiên nó đã có một số định nghĩa không dùng nữa và không hỗ trợ đăng các thuộc tính hình ảnh alt và tiêu đề. Do đó, tôi đã tăng cường nó một chút để hỗ trợ điều đó và hoạt động trơn tru với Drupal 8.6.x mới nhất. Đây là mã của MediaGenerate.php (cú pháp Yaml thích hợp nằm trong phần bình luận 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

Vì Media là một loại thực thể, bạn nên tạo di chuyển của riêng nó. Bạn có thể tạo một nguồn mới từ bảng tệp. Đây là một ví dụ

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

Sau đó, với migration_lookupbạn có thể ánh xạ các lĩnh vực như thế này.

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

0

Nếu bạn muốn di chuyển tệp trong Drupal 8 sang các thực thể phương tiện, bạn có thể sử dụng mô-đun này: https://www.drupal.org/project/migrate_file_to_media

Nó có một kịch bản drush, tự động tạo ra các trường tham chiếu phương tiện. Ngoài ra, nó phát hiện các hình ảnh trùng lặp bằng cách sử dụng hàm băm nhị phân. Và nó hỗ trợ dịch.


1
Mô-đun đó chỉ giải quyết di chuyển giữa các phiên bản D8 theo mặc định. Câu hỏi giống như về việc di chuyển từ D7 sang D8, do đó mô-đun không thể dễ dàng sử dụng (một plugin nguồn bổ sung cho MediaEntityGenerator.php có thể đọc dữ liệu từ các tệp đính kèm trong D7 có thể cần phải được tạo). Ngoài ra còn có một điểm khác biệt cơ bản: mô-đun Migrate_file_to_media chỉ chuyển đổi các tệp được đính kèm với một thực thể nhất định (= entity_type và gói được yêu cầu trong bước 1), trong khi giải pháp được chấp nhận không có yêu cầu này và trước tiên nó di chuyển tất cả các thực thể tệp từ (D7) nguồn.
Mirsoft
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.