back

Knowlegde

Knowledge Centre

Cum să migrezi Paragraphs de la Drupal 7 la Drupal 8

by editor | 25.02.2025

Cum să migrezi Paragraphs de la Drupal 7 la Drupal 8

Cu câteva zile în urmă, ne-am confruntat cu o provocare interesantă: migrarea paragrafelor de pe o platformă Drupal 7 la Drupal 8. În timp ce căutam soluția potrivită, am căutat pe web, dar nu am găsit nimic care să se potrivească perfect nevoilor noastre. Ca rezultat, dezvoltatorii noștri backend au creat o soluție personalizată. Mulțumiri speciale către mtech-llc.com și Ada Hernández, a căror muncă privind migrarea colecțiilor de câmpuri a inspirat această soluție.

În timp ce articolul original al Adei descrie migrarea colecțiilor de câmpuri, noi am adaptat abordarea pentru migrarea paragrafelor. Perspectivele ei s-au dovedit inestimabile pentru procesul nostru.

Înainte de a continua, asigurați-vă că aveți:

1. O instalare funcțională Drupal 8

2. Următoarele module instalate:

  • migrate_drupal
  • migrate_plus
  • migrate_tools
  • migrate_drupal_ui

Alternativ, puteți adăuga acestea ca dependențe la modulul dvs. personalizat.

După instalarea modulelor necesare, creați un paragraf cu bundle-ul "contact" care conține aceste câmpuri:

  • Text simplu (nume mașină: field_name)
  • Email (nume mașină: field_email)
  • Număr (Integer) (nume mașină: field_phone)

Apoi creați un tip de conținut numit Organizație (nume mașină: organization) cu:

  • Câmpul body implicit
  • Câmp de tip paragraf (nume mașină: field_contact)

Această procedură este complexă și necesită atenție deosebită la detalii. Dacă apar erori în timpul oricărui pas, este posibil să fie nevoie să începeți de la zero. Vă rugăm să citiți fiecare pas cu atenție înainte de a continua.

1. Specificați conexiunea la baza de date în settings.php

Adăugați a doua conexiune la Drupal 7 în fișierul dvs. settings.php. În acest exemplu, numele bazei de date este "drupal_7_56":

$databases['migrate']['default'] = array(
   'database' => 'drupal_7_56',
   'username' => 'root',
   'password' => '',
   'prefix' => '',
   'host' => '127.0.0.1',
   'port' => '33067',
   'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
   'driver' => 'mysql',
);

2. Creați un modul personalizat

Creați un modul personalizat cu numele mașină "custom".

3. Creați șabloane YML

Plasați următoarele șabloane YML în folderul config/install:

Mai întâi, creați șablonul de migrare pentru paragraf (numele fișierului: migrate_plus.migration.d7_paragraph_contact.yml):

langcode: en
status: true
dependencies: {}
id: d7_paragraph_contact
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags:
 - 'Drupal 7'
migration_group: migrate_drupal_7
label: Contacts
source:
 plugin: d7_paragraph_item
 key: migrate
 field_name: field_contact
process:
 field_name:
   plugin: iterator
   source: field_name
   process:
     value: value
   revision_id: revision_id
 field_email:
   plugin: iterator
   source: field_email
   process:
     value: email
   revision_id: revision_id
 field_phone:
   plugin: iterator
   source: field_phone
   process:
     value: value
   revision_id: revision_id
destination:
 plugin: 'entity_reference_revisions:paragraph'
 default_bundle: contact
migration_dependencies:
 required: {}
 optional: {}

Apoi creați șablonul de migrare pentru nod (numele fișierului: migrate_plus.migration.d7_node_organization.yml):

langcode: en
status: true
dependencies: {}
id: d7_node_organization
class: null
field_plugin_method: null
cck_plugin_method: null
migration_tags:
 - 'Drupal 7'
 - Content
migration_group: migrate_drupal_7
label: 'Nodes (Organization)'
source:
 plugin: d7_node
 node_type: organization
process:
 nid: nid
 vid: vid
 langcode:
   plugin: default_value
   source: language
   default_value: und
 title: title
 uid: node_uid
 status: status
 created: created
 changed: changed
 promote: promote
 sticky: sticky
 revision_uid: revision_uid
 revision_log: log
 revision_timestamp: timestamp
 body:
   plugin: iterator
   source: body
   process:
     value: value
     format:
       - plugin: static_map
         bypass: true
         source: format
         map:
           - null
       - plugin: skip_on_empty
         method: process
       - plugin: migration
         migration:
           - d6_filter_format
           - d7_filter_format
         source: format
 field_contact:
   - plugin: skip_on_empty
     method: process
     source: field_contact
   - plugin: migration_lookup
     migration: d7_paragraph_contact
     no_stub: true
   - plugin: iterator
     process:
       target_id: '0'
       target_revision_id: '1'
destination:
 plugin: 'entity:node'
 default_bundle: organization
migration_dependencies:
 required: {}
 optional: {}

4. Creați clasa plugin-ului sursă

Creați un fișier numit ContactParagraph.php în directorul /src/Plugin/migrate/source:

<?php
namespace Drupal\mparagraf\Plugin\migrate\source;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
/**
* D7_paragraph_item source.
*
* @MigrateSource(
*   id = "d7_paragraph_item"
* )
*/
class ContactParagraph extends FieldableEntity {
 /**
  * {@inheritdoc}
  */
 public function query() {
   // Select node in its last revision.
   $query = $this->select('paragraphs_item', 'fci')
     ->fields('fci', [
       'item_id',
       'field_name',
       'revision_id',
     ]);
   if (isset($this->configuration['field_name'])) {
     $query->innerJoin('field_data_' . $this->configuration['field_name'], 'fd', 'fd.' . $this->configuration['field_name'] . '_value = fci.item_id');
     $query->fields('fd', [
       'entity_type',
       'bundle',
       'entity_id',
       $this->configuration['field_name'] . '_revision_id',
     ]);
     $query->condition('fci.field_name', $this->configuration['field_name']);
   }
   return $query;
 }
 /**
  * {@inheritdoc}
  */
 public function prepareRow(Row $row) {
   // If field specified, get field revision ID so there aren't issues mapping.
   if (isset($this->configuration['field_name'])) {
     $row->setSourceProperty('revision_id', $row->getSourceProperty($this->configuration['field_name'] . '_revision_id'));
   }
   // Get field API field values.
   foreach (array_keys($this->getFields('paragraphs_item', 'contact')) as $field) {
     $item_id = $row->getSourceProperty('item_id');
     $revision_id = $row->getSourceProperty('revision_id');
     $row->setSourceProperty($field, $this->getFieldValues('paragraphs_item', $field, $item_id, $revision_id));
   }
   return parent::prepareRow($row);
 }
 /**
  * {@inheritdoc}
  */
 public function fields() {
   $fields = [
     'item_id' => $this->t('Item ID'),
     'revision_id' => $this->t('Revision ID'),
     'field_name' => $this->t('Name of field'),
   ];
   return $fields;
 }
 /**
  * {@inheritdoc}
  */
 public function getIds() {
   $ids['item_id']['type'] = 'integer';
   $ids['item_id']['alias'] = 'fci';
   return $ids;
 }
}

5. Implementați Hook-ul de Migrare

Adăugați următorul cod în fișierul .module al modulului dvs.:

<?php
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Plugin\MigrateSourceInterface;
use Drupal\migrate\Row;
/**
* Implements hook_migrate_MIGRATION_ID_prepare_row().
*/
function custom_migrate_d7_node_organization_prepare_row(Row $row, MigrateSourceInterface $source, MigrationInterface $migration) {
 $values = $row->getSourceProperty('field_contact');
 $value_new = [];
 if ($values) {
   foreach ($values as $value) {
     $value_new[] = ['item_id' => $value['value']];
   }
   $row->setSourceProperty('field_contact', $value_new);
 }
}

6. Pași finali

Odată ce ați finalizat cu succes toți pașii de mai sus, puteți rula migrarea și urmări cum paragrafele dvs. sunt transferate de la Drupal 7 la Drupal 8. Luați-vă un moment pentru a verifica rezultatele înainte de a continua cu orice sarcini suplimentare legate de paragrafe.

Nu uitați să testați temeinic într-un mediu de dezvoltare înainte de a încerca această migrare pe un site de producție.

migrate
Top
  • Knowlegde
    Knowledge Centre
    Extinde validarea câmpurilor cu expresii regulate
    editor
  • Knowlegde
    Knowledge Centre
    Înțelegerea arhitecturii CMS decuplate complet vs. decuplate progresiv
    editor
  • Knowlegde
    Knowledge Centre
    AngularJS sau Angular: Înțelegerea diferențelor și luarea deciziei corecte
    editor