32
Мигрируем на Drupal 8! #dckiev14

Drupal 8 migrate!

Embed Size (px)

DESCRIPTION

Drupal 8 migration process description. Common tasks, API description, tips and possible solutions.

Citation preview

Page 1: Drupal 8 migrate!

Мигрируем на Drupal 8!

#dckiev14

Page 2: Drupal 8 migrate!

About us

Andy Postnikov http://dgo.to/@andypost

Pavel Makhrinsky http://dgo.to/@gumanist

Page 3: Drupal 8 migrate!

More then 2% of all sites

How many sites are running Drupal 6 and 7?

Page 4: Drupal 8 migrate!

Latest stats

Page 5: Drupal 8 migrate!

10 Drupal myths

● Box product

● Lego

● Contrib - themes, modules, libraries

● Multilingual

● Platform

● Support

● Community

● Evolution

Page 6: Drupal 8 migrate!

Go Drupal 8

● PHP 5.4 - 5.5, 5.6.2

● HTML 5

● Libraries - jQuery 2.1 (3.0)

● Modules

● CDN - REST

● Database

Page 7: Drupal 8 migrate!

Common migration tasks

● Planningo Data mapping

o Dependencies management

o Data cleanup

● Chicken 'n Egg handling

● Continuous content lifecycle

● Progress monitoring

● Rollback results

Page 8: Drupal 8 migrate!

What is the migrate module?

Source => Process => Destination

Page 9: Drupal 8 migrate!

Migrate vs Feeds

Mostly indentical feature set:

● Since 2009 but FeedAPI 2007

● feeds is UI-oriented

● feeds_tamper vs custom code

● feeds has a lot of satelite modules

Page 10: Drupal 8 migrate!

Migrate in Drupal 8 retrospective

Signed after 6 weeks away from feature freezehttps://www.drupal.org/node/1052692#comment-6620570

Initial patch was commited November 21, 2013https://www.drupal.org/node/2125717#comment-8197259

Drupal 6 to Drupal 8 patch April 23, 2014https://www.drupal.org/node/2121299#comment-8710315

Still in progress of polishinghttps://groups.drupal.org/imp - weekly call

Page 11: Drupal 8 migrate!

Processing

Page 12: Drupal 8 migrate!

Mapping

Page 13: Drupal 8 migrate!

Definition (yml-file)

id: migrate_example_people

source:

plugin: migrate_example_people

destination:

plugin: entity:user

md5_passwords: true

process:

name:

-

plugin: concat

delimiter: .

source:

- first_name

- last_name

-

plugin: callback

callable:

- '\Drupal\Component\Utility\Unicode'

- strtolower

-

plugin: callback

callable: trim

-

plugin: dedupe_entity

entity_type: user

field: name

mail: email

pass: pass

roles:

-

plugin: explode

delimiter: ';'

source: groups

Page 14: Drupal 8 migrate!

Chicken and egg

process:

tid: tid

vid:

plugin: migration

migration: d6_taxonomy_vocabulary

source: vid

parent:

-

plugin: skip_process_on_empty

source: parent

-

plugin: migration

migration: d6_taxonomy_term

Page 15: Drupal 8 migrate!

Dependencies

migration_dependencies:

required:

- d6_filter_format

- d6_user_role

- d6_user_picture_entity_display

- d6_user_picture_entity_form_display

optional:

- d6_user_picture_file

Page 16: Drupal 8 migrate!

Execution flow

class MigrateExecutable {

/** Performs an import operation - migrate items from source to destination. */

public function import() {

$source = $this->getSource();

$id_map = $this->migration->getIdMap();

$source->rewind();

while ($source->valid()) {

$row = $source->current();

$this->processRow($row);

$destination_id_values = $destination->import($row, $id_map-

>lookupDestinationId($this->sourceIdValues));

$id_map->saveIdMapping($row, $destination_id_values, $this-

>sourceRowStatus, $this->rollbackAction);

$source->next();

}

}

Page 17: Drupal 8 migrate!

Source plugins

Provides source rows - mostly custom

1. getIterator(): iterator producing rows

2. prepareRow(): add more data to a row

3. There are hooks for prepareRow()

MigrateSourceInterface

Page 18: Drupal 8 migrate!

Source example - core

/**

* Drupal 6 menu source from database.

*

* @MigrateSource(

* id = "d6_menu",

* source_provider = "menu"

* )

*/

class Menu extends DrupalSqlBase {

/**

* {@inheritdoc}

*/

public function query() {

$query = $this->select('menu_custom', 'm')

->fields('m', array('menu_name', 'title', 'description'));

return $query;

}

Page 19: Drupal 8 migrate!

Source example - custom

public function count() {

if (is_array($this->getData())) {

return count($this->getData());

}

return 0;

}

public function getIterator() {

return new \ArrayIterator($this->getData());

}

protected function getData() {

if (!isset($this->data)) {

$this->data = array();

foreach ($this->fetchDataFromYandexDirect() as $key => $value) {

$this->data[$key] = (array) $value;

}

}

return $this->data;

}

Page 20: Drupal 8 migrate!

Process plugins

● Keys are destination properties

● Values are process pipelines

● Each pipeline is a series of process plugins

+ configuration

● There are shorthands

MigrateProcessInterface::transform()

Page 21: Drupal 8 migrate!

Process pipelines

process:

id:

-

plugin: machine_name

source: name

-

plugin: dedupe_entity

entity_type: user_role

field: id

-

plugin: user_update_8002 #custom

Page 22: Drupal 8 migrate!

Process plugins shipped

Constant values

Plugins:

get

concat

dedupebase

iterator

skip_row_if_not_set

default_value

extract

flatten

iterator

migration

skip_process_on_empty

skip_row_on_empty

static map

machine_name

dedupe_entity

callback

Page 23: Drupal 8 migrate!

Process plugin example

public function transform($value, MigrateExecutable

$migrate_executable, Row $row, $destination_property) {

$new_value = $this->getTransliteration()-

>transliterate($value,

LanguageInterface::LANGCODE_DEFAULT, '_');

$new_value = strtolower($new_value);

$new_value = preg_replace('/[^a-z0-9_]+/', '_',

$new_value);

return preg_replace('/_+/', '_', $new_value);

}

Page 24: Drupal 8 migrate!

Destination plugins

● Does the actual import

● Almost always provided by migrate module

● Most common is entity:$entity_typeo entity:node

o entity:user

● If you are writing one, you are doing it wrong

MigrateDestinationInterface

Page 25: Drupal 8 migrate!

Destination plugins shipped

● Config

● Entity

● Null

● for custom tables: url_alias, user_data…

destination:

plugin: config

config_name: user.mail

Page 26: Drupal 8 migrate!

Destination plugin example

/**

* {@inheritdoc}

*/

public function import(Row $row, array $old_destination_id_values =

array()) {

$path = $this->aliasStorage->save(

$row->getDestinationProperty('source'),

$row->getDestinationProperty('alias'),

$row->getDestinationProperty('langcode'),

$old_destination_id_values ? $old_destination_id_values[0] : NULL

);

return array($path['pid']);

}

Page 27: Drupal 8 migrate!

Demo

● Drush

● UI sandbox

Page 28: Drupal 8 migrate!

Drush or custom code

Recommended way to execute - DRUSH

Custom code:public function submitForm(array &$form, array &$form_state) {

/** @var $migration \Drupal\migrate\Entity\MigrationInterface */

$migration = entity_load('migration', $form_state['values']['migration']);

$executable = new MigrateExecutable($migration, $this);

$executable->import();

// Display statistics.

$this->getStats($form, $form_state);

$form_state['rebuild'] = TRUE;

}

Page 29: Drupal 8 migrate!

How to help

Document driven development

http://dgo.to/2127611

Open issues of migration system:

http://goo.gl/fmVNQl

Drupal groups http://dgo.to/g/imp

IRC: Freenode #drupal-migrate

Page 30: Drupal 8 migrate!

Links

https://www.drupal.org/upgrade/migrate

https://www.drupal.org/node/2127611

https://groups.drupal.org/imp

IRC: Freenode #drupal-migrate

Page 31: Drupal 8 migrate!

Questions & Discussions

Andy Postnikov http://dgo.to/@andypost

Pavel Makhrinsky http://dgo.to/@gumanist

Kiev 2014

Page 32: Drupal 8 migrate!

Roadmap d8

● миграция только посредством migrate

● текущее состояние (d6->d8, d7 testing)

● drush demo! UI contrib

● под капотомo как работает, сходство с 7

o состоит - сущности и плагины

o кастомные - source, destination, plugins

o stubs, parent migrations

● needs worko d7 test, demo?!

o migration groups, ui