LATEST FROM OUR BLOG

Take your daily dose of (only) relevant news, useful tips and tricks and valuable how to's on using the latest web technologies shaping the digital landscape. We're here to do all the necessary information sifting for you, so you don't have to, to provide you with content that will help you anticipate the emerging trends about to influence the web.

Blog Placeholder
Wordpress to Drupal 8 migration setup Here’s an example of an existing WordPress site, which has registered users with comments, anonymous comments and an archive of previous postings with metadata (tags) that we will import. We’ll finish with this posting displayed in Drupal 8 version of the blog. The following tables in Wordpress are relevant to the migration: wp_posts (contains blog posts and pages) wp_comments (comments) wp_users (users) wp_terms (categories - taxonomy) We will started writing our migration module using Migration API (migrate) that comes packaged with D8 core. As usual in Drupal 8 module development, we had .info.yml, files, which uses the Symfony 2 YAML to map data types into an XML-like schema for easy migration from one environment to another, and traditional Drupal .module files. The only thing worth noting here is a dependency on the migrate module in our info.yml file. For each Entity migration (users, posts, comments) we created 2 more files: A YAML file containing ID, Source, Destination and Mapping (Process). Put this under MODULE_ROOT/config/install/ A Source Plugin used to fetch/process Wordpress data. Put this underMODULE_ROOT/src/Plugin/migrate/source/ Code breakdown Users Let start understanding things by migrating Users first. Here is the complete user YAML file for this migration. Let’s break it down: In this migrate.migration.users.yml file, ID, Source, Destination and Process (field mapping) are important keys.   id: users # Links this file with wordpress.migrate.yaml label: Wordpress Users migration_groups:   - Wordpress ID key is ‘users’ which has been referred in manifest_wordpress.yml and also in Source Plugin (User.php) as part of Annotation.   source:   plugin: users Source key is referring to Source Plugin (User.php) created by us to fetch Wordpress users data, which we will see shortly in detail.   destination:   plugin: entity:user Destination key is user entity as defined by Migration API.   process:   uid: id   name: user_login   pass: user_pass   mail: user_email   status:     -      plugin: default_value      default_value: 1   created:     -      plugin: callback      callable: strtotime      source: user_registered Process is key to mapping source (Wordpress) and destination (Drupal) fields. Some fields are mapped directly like ‘id’ with ‘sid’ while some fields are pre-processed by Migration API before being assigned to a destination field. For instance, ‘user_registered’ will be processed by PHP function strtotime() before it’s value gets assigned to destination field, because the target Drupal site must recognize those users as registered to associate their previous activity in WordPress with their Drupal activity on the new site. We can even write our own process plugins if required. Now let’s look at Source Plugin (Users.php) which has been used to fetch the Wordpress users data,   <?php /** * @file * Contains \Drupal\migrate_wordpress\Plugin\migrate\source\Users. */ namespace Drupal\migrate_wordpress\Plugin\migrate\source; use Drupal\migrate\Row; use Drupal\migrate\Plugin\SourceEntityInterface; use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; /** * Extracts users from Wordpress database. * * @MigrateSource( *   id = "users" * ) */ Remember the id field in the YAML file? The id field tells Drupal that this class should be used to process data for that migration set, taking the results of “users” in WordPress and adding them to a new table in the Drupal database, wp_users.   class Users extends DrupalSqlBase implements SourceEntityInterface {   /**    * {@inheritdoc}    */   public function query() {     return $this->select('wp_users', 'u')       ->fields('u', array_keys($this->userFields()));   } The query() method is used to fetch records from Wordpress database table (wp_users).     /**    * Returns the User fields to be migrated.    *    * @return array    *   Associative array having field name as key and description as value.    */   protected function userFields() {     $fields = array(       'id' => $this->t('User ID'),       'user_login' => $this->t('Username'),       'user_pass' => $this->t('Password'),       'user_email' => $this->t('Email address'),       'user_registered' => $this->t('Created time'),     );     return $fields;   }   /**    * {@inheritdoc}    */   public function fields() {     $fields = $this->userFields();   } userFields() method is called in query() and fields() methods. It contains the list of fields that describe a WordPress user along with their field descriptions.     /**    * {@inheritdoc}    */   public function bundleMigrationRequired() {     return false;   }   /**    * {@inheritdoc}    */   public function entityTypeId() {     return 'users';   }   /**    * {@inheritdoc}    */   public function getIds() {     return array(       'id' => array(         'type' => 'integer',         'alias' => 'u',       ),     );   } As we are also implementing an interface SourceEntityInterface, we need to define 2 more methods namelybundleMigrationRequired() and entityTypeId() to map user-generated content, such as postings and comments, to Drupal. The getIds() method is used to return the key field for this Entity. Posts The Posts Entity migration (YAML, Source Plugin) is quite similar to User Entity migration. There is one additional method prepareRow() defined in post migration source plugin. This method gets called for each row to do an additional processing of the source data.   public function prepareRow(Row $row) { $post_type = $row->getSourceProperty('post_type'); $type = $post_type == 'page' ? 'page' : 'article'; $row->setSourceProperty('type', $type); return parent::prepareRow($row); } In this method, we are first checking the post type of source data and based on that we set the ‘type’ property. As we have two types of posts in Wordpress (Pages, Blogs posts) we want to map them to two content types in Drupal (Basic page, Article). The ‘type’ property is available in the post-migration YAML file Process step, as discussed above, and we have mapped it to the Drupal content type field. Comments The Comments Entity migration is more or less similar to Users and Posts migration. There are some following additions in Comments migration YAML file which are quite interesting to know.   uid: -    plugin: skip_process_on_empty    source: user_id -    plugin: migration    migration: users 'comment_body/value': comment_content 'comment_body/format': 'basic_html' migration_dependencies: required:    - posts    - users Here we are using ‘skip_process_on_empty’ plugin which means skip the process if the source value is empty. As key fields can have different values in source and destination databases so we are using migration plugin to map ‘user_id’ field with ‘uid’ field. This will look for destination id in migration map tables for given source id (user_id). Next, the ‘comment_body’ field is a text field and made up of two fields in Drupal 8, so we must map the Wordpress ‘comment_content’ field to value field and mapping basic html to format field. Next we have defined comment migration dependencies to posts and users which means comments will be migrated once both posts and users are already migrated. Putting it all together Finally you can run the migration using 'migrate-manifest' drush command as below. Make sure to run this command in Drush 7.   drush migrate-manifest manifest_wordpress.yml --legacy-db-url=mysql://{dbuser}:{dbpass}@localhost/{dbname} The manifest_wordpress.yml is a YAML file which contains reference to IDs of each migration (users, posts, comments etc.).   # A Wordpress posts/users/comments migration, with dependencies. - posts - users - comments Finished: WordPress postings shown in Drupal ... Read more
Adrian Ababei / Feb 24'2015