Upload
pavel-makhrinsky
View
214
Download
2
Embed Size (px)
DESCRIPTION
Drupal 8 migration process description. Common tasks, API description, tips and possible solutions.
Citation preview
Мигрируем на Drupal 8!
#dckiev14
About us
Andy Postnikov http://dgo.to/@andypost
Pavel Makhrinsky http://dgo.to/@gumanist
More then 2% of all sites
How many sites are running Drupal 6 and 7?
Latest stats
10 Drupal myths
● Box product
● Lego
● Contrib - themes, modules, libraries
● Multilingual
● Platform
● Support
● Community
● Evolution
Go Drupal 8
● PHP 5.4 - 5.5, 5.6.2
● HTML 5
● Libraries - jQuery 2.1 (3.0)
● Modules
● CDN - REST
● Database
Common migration tasks
● Planningo Data mapping
o Dependencies management
o Data cleanup
● Chicken 'n Egg handling
● Continuous content lifecycle
● Progress monitoring
● Rollback results
What is the migrate module?
Source => Process => Destination
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
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
Processing
Mapping
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
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
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
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();
}
}
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
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;
}
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;
}
Process plugins
● Keys are destination properties
● Values are process pipelines
● Each pipeline is a series of process plugins
+ configuration
● There are shorthands
MigrateProcessInterface::transform()
Process pipelines
process:
id:
-
plugin: machine_name
source: name
-
plugin: dedupe_entity
entity_type: user_role
field: id
-
plugin: user_update_8002 #custom
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
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);
}
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
Destination plugins shipped
● Config
● Entity
● Null
● for custom tables: url_alias, user_data…
destination:
plugin: config
config_name: user.mail
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']);
}
Demo
● Drush
● UI sandbox
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;
}
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
Links
https://www.drupal.org/upgrade/migrate
https://www.drupal.org/node/2127611
https://groups.drupal.org/imp
IRC: Freenode #drupal-migrate
Questions & Discussions
Andy Postnikov http://dgo.to/@andypost
Pavel Makhrinsky http://dgo.to/@gumanist
Kiev 2014
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