मैं मीडिया संस्थाओं में फ़ाइल संस्थाओं को कैसे स्थानांतरित करूं?


11

मैं एक डी 7 से डी 8 माइग्रेशन के लिए माइग्रेट मॉड्यूल का उपयोग कर रहा हूं और मैं पूरे माइग्रेशन को कोड में मैन्युअल रूप से लिख रहा हूं (बजाय डी 7 माइग्रेट मॉड्यूल में निर्मित का उपयोग करने के बजाय, क्योंकि मैं माइग्रेशन पर अधिक दानेदार नियंत्रण चाहता था।)

मेरे पास निम्न संरचना है: 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 

लेकिन मुझे एहसास हुआ कि यह काम नहीं करेगा। Image_files माइग्रेशन से आने वाले target_id वास्तव में फ़ाइल एंटिटी आईडी के थे, मीडिया इकाई आईडी के नहीं। आदर्श दुनिया में, मैं तीसरा माइग्रेशन बनाने का एक तरीका खोजना चाहता हूं, जो इस मध्य चरण को बनाए, और मीडिया एंटिटीज में फाइल एंटिटीज को माइग्रेट करें और फिर उस माइग्रेशन को आर्टिकल माइग्रेशन में मैप करें। हालाँकि, मैं यह करने का एक अच्छा तरीका नहीं समझ सकता।

प्लान बी बस छवियों के माइग्रेशन के लिए एक प्रक्रिया प्लगइन बनाने के लिए होगा, जो मैन्युअल रूप से फ़ाइल इकाइयां बनाएगा, उन्हें मीडिया संस्थाओं से संलग्न करेगा, और उस माइग्रेशन को लेखों में पास करेगा (यह मध्य चरण को हटाता है)। हालांकि, इसका मतलब यह होगा कि जब मीडिया संस्थाओं को वापस लाया जा सकता है, फाइल एंटिटीज नहीं कर सकती हैं।

जवाबों:


4

मैंने इसे थोड़ा अलग करने के लिए समाप्त कर दिया - मैं एक नियमित फ़ाइल आयात करता हूं, उस माइग्रेशन को अपने मीडिया इकाई संदर्भ क्षेत्र के लिए स्रोत के रूप में सेट करता हूं, और फिर नए मीडिया लक्ष्य के लिए FID का अनुवाद करने के लिए एक दूसरी प्रक्रिया प्लगइन 'MediaGenerate' लागू किया।

<?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

आप फ़ाइल की ऊंचाई / शीर्षक विशेषताओं को कैसे संभालते हैं?
जुप

परीक्षण किया गया है और यह अच्छी तरह से काम करता है, हालाँकि आपको "माइग्रेशन_गेजअप" प्लगइन का उपयोग करने की आवश्यकता होगी क्योंकि "माइग्रेशन" प्लगइन को हटा दिया गया है और पहले से ही मेरे नवीनतम संस्करणों पर काम नहीं किया है। मेरे बाद उपयोगकर्ता चित्रों को आयात करने के लिए काम किया: प्लगइन: mig_lookup माइग्रेशन: my_file_migration स्रोत: चित्र इसके अलावा, यदि आप बंडलों के बिना संस्थाओं को माइग्रेट करते हैं (जैसे उपयोगकर्ता चित्र), तो आपको संभवतः यहां से पैच की आवश्यकता होगी: drupal.org -project/migrate_plus/issues / 2787219 , अन्यथा आपको एक त्रुटि मिलती है "Unit_lookup प्लगइन को value_key की आवश्यकता है, कोई भी स्थित नहीं है।" प्रवास पर।
मिरसॉफ्ट

किसी को भी बता सकते हैं कि कैसे $ UnitId इस में पाया जाता है?
झलक

2

मैंने स्वीकार किए गए उत्तर की बहुत सराहना की, हालांकि इसकी पहले से ही कुछ परिभाषाएँ थीं और उन्होंने ऊँचाई और शीर्षक छवि गुणों को पोस्ट करने का समर्थन नहीं किया। इस प्रकार, मैंने इसका समर्थन करने के लिए और नवीनतम Drupal 8.6.x के साथ सुचारू रूप से काम करने के लिए इसे थोड़ा बढ़ाया। यहाँ MediaGenerate.php का कोड है (उपयुक्त यम वाक्यविन्यास डॉक्टर टिप्पणी के अंदर है):

<?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

जैसा कि मीडिया एक इकाई प्रकार है, आपको अपना स्वयं का माइग्रेशन बनाना चाहिए। आप फ़ाइल तालिका से एक नया स्रोत उत्पन्न कर सकते हैं। यहाँ एक उदाहरण है

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

इसमें एक ड्रश स्क्रिप्ट है, जो स्वचालित रूप से मीडिया संदर्भ फ़ील्ड बनाती है। इसके अतिरिक्त यह बाइनरी हैश का उपयोग करके डुप्लिकेट छवियों का पता लगाता है। और यह अनुवाद का समर्थन करता है।


1
वह मॉड्यूल केवल डिफ़ॉल्ट रूप से D8 संस्करणों के बीच प्रवास को हल करता है। प्रश्न D7 से D8 तक माइग्रेशन के बारे में अधिक पसंद है, ताकि मॉड्यूल को आसानी से उपयोग नहीं किया जा सके (MediaEntityGenerator.php के लिए एक अतिरिक्त स्रोत प्लगइन जो D7 में संलग्न फ़ाइलों से डेटा पढ़ेगा, संभवतः बनाने की आवश्यकता होगी)। एक मौलिक अंतर यह भी है: migrate_file_to_media मॉड्यूल केवल कुछ निकाय से जुड़ी फ़ाइलों को कनवर्ट करता है ((step_type और बंडल को step1 में आवश्यक है), जबकि स्वीकृत समाधान में यह आवश्यकता नहीं है और यह सबसे पहले (D7) से सभी फ़ाइल संस्थाओं को माइग्रेट करता है स्रोत।
मिरसॉफ्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.