abstract class WordPressItemMigration in WordPress Migrate 7.2
Same name and namespace in other branches
- 7 wordpress_item.inc \WordPressItemMigration
Intermediate Migration class, implementing behavior common across different types (post_type) of items.
Hierarchy
- class \MigrationBase
- class \Migration
- class \XMLMigration
- class \WordPressMigration
- class \WordPressItemMigration
- class \WordPressMigration
- class \XMLMigration
- class \Migration
Expanded class hierarchy of WordPressItemMigration
1 string reference to 'WordPressItemMigration'
- wordpress_migrate_update_7015 in ./
wordpress_migrate.install - Updates to legacy wordpress migration arguments.
File
- ./
wordpress_item.inc, line 106 - Support for migrating posts and pages from a WordPress blog into Drupal.
View source
abstract class WordPressItemMigration extends WordPressMigration {
/**
* The <wp:post_type> value we're looking for in this migration
* (post/page/attachment).
*
* @var string
*/
protected $postType;
public function getPostType() {
return $this->postType;
}
/**
* Indicates to the complete() method that the nid of this item needs to be
* saved in linksToFix for later processing.
*
* @var boolean
*/
protected $linksNeedFixing = FALSE;
/**
* List of nids which have links needing fixing.
*
* @var array
*/
protected static $linksToFix = array();
/**
* Track the fields for the term references, so we can fix up if necessary
* in prepare().
*
* @var string
*/
protected $tagField = NULL;
protected $categoryField = NULL;
/**
* Set it up
*/
public function __construct(array $arguments = array()) {
parent::__construct($arguments);
// WordPress post type
$this->postType = $this->arguments['post_type'];
// Drupal content type (bundle)
$bundle = $this->arguments['bundle'];
// Save tag/category fields (used in prepare()).
if (isset($arguments['tag_field'])) {
$this->tagField = $arguments['tag_field'];
}
if (isset($arguments['category_field'])) {
$this->categoryField = $arguments['category_field'];
}
// post_id is the unique ID of items in WordPress
$this->map = new MigrateSQLMap($this->machineName, array(
'wp:post_id' => array(
'type' => 'int',
'not null' => TRUE,
'unsigned' => TRUE,
'description' => 'WordPress post ID',
),
), MigrateDestinationNode::getKeySchema());
// Construct the source objects.
$this->source = new WordPressItemSource($this->wxrFile, $this->postType, $this->machineName, $this->arguments['namespaces']);
$this->destination = new MigrateDestinationNode($bundle);
// Default mappings, applying to most or all migrations
$this
->addFieldMapping('title', 'title')
->xpath('title');
$this
->addFieldMapping('created', 'wp:post_date')
->xpath('wp:post_date')
->description('Empty dates handled in prepare()');
$this
->addFieldMapping('changed', 'wp:post_date')
->xpath('wp:post_date')
->description('Empty dates handled in prepare()');
// If we have a separate author migration, use it here
$uid_mapping = $this
->addFieldMapping('uid', 'dc:creator')
->xpath('dc:creator')
->description('Use matching username if any, otherwise current user');
if ($this->blog
->getWxrVersion() != '1.0') {
if (!empty($arguments['author_migration'])) {
$author_migration = $arguments['author_migration'];
}
else {
$author_migration = $this->group
->getName() . 'Author';
}
$uid_mapping
->sourceMigration($author_migration);
}
$this
->addFieldMapping('body', 'content');
$this
->addFieldMapping('body:summary', 'excerpt:encoded')
->xpath('excerpt:encoded');
$this
->addFieldMapping('body:format')
->defaultValue($this->arguments['text_format']);
if (module_exists('comment')) {
$this
->addFieldMapping('comment', 'wp:comment_status')
->xpath('wp:comment_status')
->description('WP "open" mapped to Drupal COMMENT_NODE_OPEN');
}
$this
->addFieldMapping('status', 'status')
->description('Set Drupal status to 1 iff wp:status=publish');
$this
->addFieldMapping(NULL, 'wp:post_parent')
->xpath('wp:post_parent')
->description('Only applies to attachments');
$this
->addFieldMapping('sticky', 'wp:is_sticky')
->xpath('wp:is_sticky');
if (module_exists('path')) {
switch ($this->arguments['path_action']) {
// Do not set path aliases
case 0:
$this
->addFieldMapping('path');
if (!module_exists('redirect')) {
$this
->addFieldMapping(NULL, 'link');
}
if (module_exists('pathauto')) {
$this
->addFieldMapping('pathauto')
->defaultValue(0);
}
break;
// Set path aliases to their original WordPress values
case 1:
$this
->addFieldMapping('path', 'link');
if (module_exists('pathauto')) {
$this
->addFieldMapping('pathauto')
->defaultValue(0);
}
break;
// Have pathauto generate new aliases
case 2:
$this
->addFieldMapping('path');
if (!module_exists('redirect')) {
$this
->addFieldMapping(NULL, 'link');
}
if (module_exists('pathauto')) {
$this
->addFieldMapping('pathauto')
->defaultValue(1);
}
break;
}
}
if (module_exists('redirect')) {
if ($this->arguments['generate_redirects']) {
$this
->addFieldMapping('migrate_redirects', 'link');
}
else {
$this
->addFieldMapping('migrate_redirects');
$this
->addFieldMapping(NULL, 'link');
}
}
if (module_exists('taxonomy')) {
// Map the source fields to the configured vocabularies. Note the nicename
// (WordPress machine name) is used for matching on sourceMigration - we
// pull the actual tag/category separately in case we need to handle it
// in prepare().
if ($this->tagField) {
$this
->addFieldMapping($this->tagField, 'tag')
->sourceMigration($arguments['group_name'] . $arguments['tag_migration'])
->xpath('category[@domain="post_tag"]/@nicename');
$this
->addFieldMapping(NULL, 'tag_value')
->xpath('category[@domain="post_tag"]');
$this
->addFieldMapping($this->tagField . ':source_type')
->defaultValue('tid');
}
else {
$this
->addFieldMapping(NULL, 'tag');
}
if ($this->categoryField) {
$this
->addFieldMapping($this->categoryField, 'category')
->sourceMigration($arguments['group_name'] . $arguments['category_migration'])
->xpath('category[@domain="category"]/@nicename');
$this
->addFieldMapping(NULL, 'category_value')
->xpath('category[@domain="category"]');
$this
->addFieldMapping($this->categoryField . ':source_type')
->defaultValue('tid');
}
else {
$this
->addFieldMapping(NULL, 'category');
}
}
// If podcast migration is requested, add the mapping.
$podcast_field = $this->arguments['podcast_field'];
if ($podcast_field) {
$this
->addFieldMapping($podcast_field, 'enclosure')
->callbacks(array(
$this,
'handleEnclosure',
));
}
// If an attachment field is configured, document the mapping.
$attachment_field = $this->arguments['attachment_field'];
if ($attachment_field) {
$this
->addFieldMapping($attachment_field)
->description('Attachment field populated later by attachment migration');
}
// Unmapped destination fields
$this
->addUnmigratedDestinations(array(
'is_new',
'revision',
'language',
'promote',
'revision_uid',
'log',
'tnid',
'translate',
'body:language',
));
// Unmapped source fields
$this
->addUnmigratedSources(array(
'wp:post_id',
'wp:menu_order',
'wp:post_type',
));
$this
->addFieldMapping(NULL, 'guid')
->description('same as link, plus isPermaLink attribute?')
->issueGroup(t('DNM'));
$this
->addFieldMapping(NULL, 'description')
->description('Always empty?')
->issueGroup(t('DNM'));
$this
->addFieldMapping(NULL, 'pubDate')
->description('Use post_date')
->issueGroup(t('DNM'));
$this
->addFieldMapping(NULL, 'wp:post_date_gmt')
->description('Use post_date')
->issueGroup(t('DNM'));
$this
->addFieldMapping(NULL, 'wp:ping_status')
->description('What does this mean?')
->issueGroup(t('Open issues'))
->issuePriority(MigrateFieldMapping::ISSUE_PRIORITY_MEDIUM);
$this
->addFieldMapping(NULL, 'wp:post_name')
->description('Looks like last component of path')
->issueGroup(t('DNM'));
$this
->addFieldMapping(NULL, 'wp:post_password')
->description('???')
->issueGroup(t('DNM'));
}
/**
* Data manipulations to be performed before the migrate module applies mappings.
*
* @param stdClass $row
* @return string
*/
public function prepareRow($row) {
$wp_row = $row->xml
->children($this->arguments['namespaces']['wp']);
$content_row = $row->xml
->children($this->arguments['namespaces']['content']);
// Skip any of the wrong post type
if ($wp_row->post_type != $this->postType) {
$this->skippedItems[] = $row->{'wp:post_id'};
return FALSE;
}
// Only publish those with wp:status == 'publish'
if (isset($wp_row->status)) {
switch ($wp_row->status) {
case 'publish':
$row->status = NODE_PUBLISHED;
break;
case 'trash':
return FALSE;
default:
$row->status = NODE_NOT_PUBLISHED;
}
}
else {
$row->status = NODE_NOT_PUBLISHED;
}
// If incoming date is zero (indicates unpublished content), use the current time
if ($wp_row->post_date == '0000-00-00 00:00:00') {
$row->{'wp:post_date'} = time();
}
// If the link has a query string, don't produce a path
$row->link = (string) $row->xml->link;
if (strpos($row->link, '?')) {
unset($row->link);
}
else {
// Otherwise, strip the domain portion of the URL
$matches = array();
if (preg_match('|https?://[^/]+/(.*)|', $row->link, $matches)) {
$row->link = $matches[1];
// Strip the last slash off of the URL (the Path module can't handle this)
$row->link = rtrim($row->link, '/');
}
else {
unset($row->link);
}
}
// Translate WordPress comment_status to Drupal values
if (module_exists('comment')) {
if ($wp_row->comment_status == 'open') {
$row->{'wp:comment_status'} = COMMENT_NODE_OPEN;
}
else {
$row->{'wp:comment_status'} = COMMENT_NODE_CLOSED;
}
}
// Pull out teasers out based on <!--more--> tags
$broken = explode('<!--more-->', $row->content);
if (count($broken) == 2) {
$row->excerpt = $broken[0];
}
$row->content = $content_row->encoded;
// Interpret the [caption] tags
$row->content = preg_replace_callback('|(\\[caption.*?\\])(.*?)(\\[/caption\\])|i', array(
$this,
'replaceCaptions',
), $row->content);
// Handle [youtube] tags - convert them to <object> tags. If the media module is
// installed, the next step will then convert them to media tags
$replacement = '<object width="425" height="344">' . '<param name="movie" value="http://www.youtube.com/v/$1&fs=1" />' . '<param name="allowFullScreen" value="true" />' . '<param name="allowscriptaccess" value="always" />' . '<embed src="http://www.youtube.com/v/$1&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344">' . '</embed></object>';
// One form is [youtube dQw4w9WgXcQ]
$row->content = preg_replace('|\\[youtube (.+?)\\]|i', $replacement, $row->content);
// Another form is [youtube=https://www.youtube.com/watch?v=dQw4w9WgXcQ]
$row->content = preg_replace('|\\[youtube=.+?=([a-z0-9_-]+)[^\\]]*\\]|i', $replacement, $row->content);
// Rewrite embedded video references to media tags
if (module_exists('media')) {
$row->content = preg_replace_callback('|<object [^>]*>.*?(<embed [^>]*>).*?</object>|i', array(
$this,
'replaceEmbeds',
), $row->content);
}
// Rewrite (or remember to rewrite) links of the form
// http://example.wordpress.com/?p=19 to local links of the form /node/35
$row->content = $this
->fixLocalLinks($row->content);
// Handle Embedit HTML embed
if (isset($row->HTML1)) {
$row->content = $this
->replaceHTMLEmbeds($row, $row->content);
}
// Replace Kimilli Flash Embed tags with <object>
$row->content = preg_replace_callback('|\\[kml_flashembed *(.*?)/\\]|i', array(
$this,
'replaceFlashEmbeds',
), $row->content);
// Remove [gallery] shortcode tags.
$row->content = preg_replace('|\\[gallery (.+?)\\]|i', '', $row->content);
$row->{'content:encoded'} = $row->content;
return TRUE;
}
/**
* Rewrite [caption] tags into HTML representing a caption.
* [caption] itself ($matches[1]) will become an opening <div>,
* the content within the tag ($matches[2]) will be passed through unchanged,
* and the closing [/caption] ($matches[3]) will become a <p> containing the
* caption followed by a closing </div>.
*
* @param array $matches
*/
protected function replaceCaptions(array $matches) {
$caption_open = $matches[1];
$content = $matches[2];
$caption_close = $matches[3];
preg_match('|width="(.*?)"|i', $caption_open, $matches);
$width = (int) $matches[1] + 10;
$style = "width: {$width}px;";
preg_match('|align="(.*?)"|i', $caption_open, $matches);
$align = $matches[1];
switch ($align) {
case 'aligncenter':
$style .= "display:block;margin:0 auto;";
break;
case 'alignleft':
$style .= "float:left;";
break;
case 'alignright':
$style .= "float:right;";
break;
default:
break;
}
preg_match('|caption="(.*?)"|i', $caption_open, $matches);
$caption = $matches[1];
$result = '<div style="' . $style . '">';
$result .= $content;
$result .= "<p>{$caption}</p></div>";
return $result;
}
/**
* If we have a YouTube or other media reference, replace it with media tags.
*
* @param array $matches
*/
protected function replaceEmbeds(array $matches) {
// Default to the original <object> tag.
$result = $matches[0];
// If an <embed> tag is present, attempt to parse it.
if ($matches[1]) {
if (preg_match('|src=[\'"](.*?)[\'"]|i', $matches[1], $src_matches)) {
$src = $src_matches[1];
}
else {
return $result;
}
// Attempt to parse embedded media automatically through the media module.
try {
$uri = media_parse_to_uri($src);
if ($uri) {
// Sometimes, at least with oembed, it doesn't like the /v/ form
$uri = str_replace('youtube.com/v/', 'youtube.com/watch?v=', $uri);
}
} catch (Exception $e) {
return $result;
}
if (empty($uri)) {
return $result;
}
// Extract the width & height for the media tag.
if (preg_match('|width=[\'"](.*?)[\'"]|i', $matches[1], $width_matches)) {
$width = $width_matches[1];
}
else {
return $result;
}
if (preg_match('|height=[\'"](.*?)[\'"]|i', $matches[1], $height_matches)) {
$height = $height_matches[1];
}
else {
return $result;
}
// Build a file object suitable for saving.
if (function_exists('file_uri_to_object')) {
$file = file_uri_to_object($uri, TRUE);
if (!isset($file->fid)) {
// Save the media.
file_save($file);
}
}
else {
// We shouldn't get here. But just in case...
return $result;
}
// Build the media tag
$video_info = array(
'type' => 'media',
'view_mode' => 'media_large',
'fid' => $file->fid,
'attributes' => array(
'class' => 'media-image',
'typeof' => 'foaf:Image',
'height' => $height,
'width' => $width,
'style' => '',
),
);
$result = '[[' . drupal_json_encode($video_info) . ']]';
}
return $result;
}
/**
* Replace a kml_flashembed tag with an HTML <object> tag.
*
[kml_flashembed movie="http://example.com/video/soundslider.swf"
FVARS="size=0" height="368" width="420" /]
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="fm_soundslider_1640275925"
class="flashmovie"
width="420"
height="368">
<param name="movie" value="http://example.com/video/soundslider.swf"" />
<param name="flashvars" value="size=0" />
<!--[if !IE]>-->
<object type="application/x-shockwave-flash"
data="http://example.com/video/soundslider.swf""
name="fm_soundslider_1640275925"
width="420"
height="368">
<param name="flashvars" value="size=0" />
<!--<![endif]-->
<!--[if !IE]>-->
</object>
<!--<![endif]-->
</object>
* @param array $matches
*/
protected function replaceFlashEmbeds(array $matches) {
$attribute_matches = array();
$attribute_string = '';
preg_match_all('|(?P<name>\\w+)="(?P<value>.*?)"|', $matches[0], $attribute_matches);
foreach ($attribute_matches['name'] as $delta => $name) {
$value = $attribute_matches['value'][$delta];
switch (drupal_strtolower($name)) {
case 'movie':
// Sometimes they've got their own player in their ahead of the movie,
// strip it out
$url_position = strpos($value, 'http://');
if ($url_position) {
$movie = substr($value, $url_position);
// Strip parameters
$movie = substr($movie, 0, strpos($movie, '&'));
}
else {
$movie = $value;
}
break;
case 'fvars':
$flashvars = $value;
break;
default:
$attribute_string .= ' ' . $name . '="' . $value . '"';
break;
}
}
$result = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" class="flashmovie"' . $attribute_string . ">\n";
$result .= '<param name="movie" value="' . $movie . "\" />\n";
if (isset($flashvars)) {
$result .= '<param name="flashvars" value="' . $flashvars . "\" />\n";
}
$result .= "<!--[if !IE]>-->\n";
$result .= '<object type="application/x-shockwave-flash" data="' . $movie . '"' . $attribute_string . ">\n";
if (isset($flashvars)) {
$result .= '<param name="flashvars" value="' . $flashvars . "\" />\n";
}
$result .= "<!--<![endif]-->\n";
$result .= "<!--[if !IE]>--></object><!--<![endif]-->\n";
$result .= "</object>\n";
return $result;
}
/**
* Replace any hrefs to links of the form http://example.wordpress.com/?=23
* to local links to a node.
*
* @param string $body
*/
protected function fixLocalLinks($body) {
$this->linksNeedFixing = FALSE;
$site_url = $this->blog
->getLink();
$pattern = '|href="' . $site_url . '/\\?p=([0-9]+)"|i';
$body = preg_replace_callback($pattern, array(
$this,
'replaceLinks',
), $body);
return $body;
}
/**
* If we have a local link of the form ?p=34, translate the WordPress ID into
* a Drupal nid, and rewrite the link.
*
* @param array $matches
*/
protected function replaceLinks(array $matches) {
// Default to the existing string
$return = $matches[0];
$wordpress_id = (int) $matches[1];
// Check the blog entry and page maps to see if we can map this to a nid
static $maps = array();
if (empty($maps)) {
$machines = array(
$this
->generateMachineName('WordPressBlogEntry'),
$this
->generateMachineName('WordPressPage'),
);
foreach ($machines as $machine) {
$maps[] = MigrationBase::getInstance($machine)
->getMap();
}
}
foreach ($maps as $map) {
$destination_id = $map
->lookupDestinationID(array(
$wordpress_id,
), $this);
if (!empty($destination_id)) {
// Got a hit! Stop looking...
$destination_id = reset($destination_id);
break;
}
}
// Remember if we didn't get a hit, complete() will set up for later review
if (empty($destination_id)) {
$this->linksNeedFixing = TRUE;
}
else {
$return = 'href="/node/' . $destination_id . '"';
}
return $return;
}
protected function replaceHTMLEmbeds($row, $text) {
for ($i = 1; $i <= 9; $i++) {
$field = "HTML{$i}";
if (isset($row->{$field})) {
$text = str_replace("[{$field}]", $row->{$field}, $text);
}
}
return $text;
}
/**
* Blubrry PowerPress podcast values are of the form
* http://www.example.com/audio/example.mp3
* 7662957
* audio/mpeg
* a:1:{s:8:"duration";s:8:"00:05:19";}
* We will extract and return the first line, the URL of the audio file.
*
* @param $value
* @return string
*/
protected function handleEnclosure($value) {
$value_array = explode("\n", $value);
return reset($value_array);
}
/**
* Prepare node - called just before node_save().
*
* @param stdClass $node
* @param stdClass $row
*/
public function prepare(stdClass $node, stdClass $row) {
// With WXR version 1.0, match creator username to Drupal username if
// possible; otherwise, use the user that initiated the import. With later
// versions, we've already got the right uid via the author migration.
if ($this->blog
->getWxrVersion() == '1.0') {
static $drupal_static_fast;
if (!isset($drupal_static_fast)) {
$drupal_static_fast['user_map'] =& drupal_static(__FUNCTION__);
$drupal_static_fast['default_user'] =& drupal_static(__FUNCTION__ . 'DefaultUser');
}
$user_map =& $drupal_static_fast['user_map'];
if (!isset($user_map[$row->creator])) {
$user_map[$row->creator] = db_select('users', 'u')
->fields('u', array(
'uid',
))
->condition('name', $row->creator)
->execute()
->fetchField();
if (!$user_map[$row->creator]) {
$default_user =& $drupal_static_fast['default_user'];
if (!isset($default_user)) {
$default_user = db_select('wordpress_migrate', 'wpm')
->fields('wpm', array(
'uid',
))
->condition('filename', $this->wxrFile)
->execute()
->fetchField();
}
$user_map[$row->creator] = $default_user;
}
}
$node->uid = $user_map[$row->creator];
}
// If any term relationships were unresolved, create them the hard way
foreach (array(
'tag',
'category',
) as $term_type) {
$meta_field_name = $term_type . 'Field';
if ($this->{$meta_field_name}) {
$field_name = $this->{$meta_field_name};
$value_name = $term_type . '_value';
// Shortcut - if the counts match, don't need to dig deeper
$field_values = field_get_items('node', $node, $field_name);
if (!empty($field_values)) {
$node_count = count($field_values);
}
else {
$node_count = 0;
}
if (isset($row->{$term_type})) {
$row_count = count($row->{$term_type});
}
else {
$row_count = 0;
}
if ($node_count != $row_count) {
$field_info = field_info_field($field_name);
$vocabulary_name = $field_info['settings']['allowed_values'][0]['vocabulary'];
$vocabulary = taxonomy_vocabulary_machine_name_load($vocabulary_name);
$vid = $vocabulary->vid;
// Get any terms already in the field
$done_terms = array();
if (is_array($field_values)) {
foreach ($field_values as $value_array) {
$terms = taxonomy_term_load_multiple($value_array);
foreach ($terms as $term) {
$done_terms[] = $term->name;
}
}
}
if (isset($row->{$value_name})) {
if (!is_array($row->{$value_name})) {
$row->{$value_name} = array(
$row->{$value_name},
);
}
$values = array();
foreach ($row->{$value_name} as $value) {
$values[] = html_entity_decode($value);
}
$diff = array_diff($values, $done_terms);
$field_language = field_language('node', $node, $field_name);
foreach ($diff as $new_term_name) {
// Let's see if the term already exists
$matches = taxonomy_term_load_multiple(array(), array(
'name' => trim($new_term_name),
'vid' => $vid,
));
if ($matches) {
$node->{$field_name}[$field_language][] = array(
'tid' => key($matches),
);
}
else {
$term = new stdClass();
$term->name = $new_term_name;
$term->vid = $vid;
taxonomy_term_save($term);
$node->{$field_name}[$field_language][] = array(
'tid' => $term->tid,
);
}
}
}
}
}
}
// If we have an attached podcast, replace [powerpress] in the body with
// a link to the audio file.
$podcast_field = $this->arguments['podcast_field'];
if ($podcast_field && isset($node->{$podcast_field})) {
$podcast_fid = $node->{$podcast_field}[LANGUAGE_NONE][0]['fid'];
if ($podcast_fid) {
$podcast = file_load($podcast_fid);
if ($podcast) {
// file_create_url() gives us a full URL, which when running from
// drush will often start with http://default/, which is not what we
// want. Strip the prefix for a relative link.
$url = file_create_url($podcast->uri);
$url = str_replace($GLOBALS['base_url'] . '/', '/', $url);
$link = '<p><a href="' . $url . '"><img src="/modules/file/icons/audio-x-generic.png" /></a></p>';
$body_language = field_language('node', $node, 'body');
$node->body[$body_language][0]['value'] = str_replace('[powerpress]', $link, $node->body[$body_language][0]['value']);
}
}
}
}
/**
* Complete node - called just after node_save().
*
* @param stdClass $node
* @param stdClass $row
*/
public function complete(stdClass $node, stdClass $row) {
// Remember the nid of any node where we weren't able to resolve ?p=23
// links yet - by the time the page migration's postImport() is called, we
// should have resolved all references.
if ($this->linksNeedFixing) {
self::$linksToFix[] = $node->nid;
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Migration:: |
protected | property | All field mappings, with those retrieved from the database overriding those defined in code. | |
Migration:: |
protected | property | Field mappings retrieved from storage. | |
Migration:: |
protected | property | An array of counts. Initially used for cache hit/miss tracking. | |
Migration:: |
protected | property | The default rollback action for this migration. Can be overridden on a per-row basis by setting $row->rollbackAction in prepareRow(). | |
Migration:: |
protected | property | Destination object for the migration, derived from MigrateDestination. | |
Migration:: |
protected | property | The object currently being constructed | |
Migration:: |
protected | property | If present, an array with keys name and alias (optional). Name refers to the source columns used for tracking highwater marks. alias is an optional table alias. | |
Migration:: |
protected | property | Map object tracking relationships between source and destination data | |
Migration:: |
public | property | Specify value of needs_update for current map row. Usually set by MigrateFieldHandler implementations. | |
Migration:: |
protected | property | Queue up messages that can't be safely saved (in particular, if they're generated in prepareRow(). | |
Migration:: |
public | property | The rollback action to be saved for the current row. | |
Migration:: |
protected | property | When performing a bulkRollback(), the maximum number of items to pass in a single call. Can be overridden in derived class constructor. | |
Migration:: |
protected | property | Source object for the migration, derived from MigrateSource. | |
Migration:: |
protected | property | The current data row retrieved from the source. | |
Migration:: |
protected | property | Field mappings defined in code. | |
Migration:: |
protected | property | ||
Migration:: |
protected | property | ||
Migration:: |
protected | property | ||
Migration:: |
public | function | Shortcut for adding several fields which have the same name on both source and destination sides. | |
Migration:: |
public | function | Shortcut for adding several destination fields which are to be explicitly not migrated. | |
Migration:: |
public | function | Shortcut for adding several source fields which are to be explicitly not migrated. | |
Migration:: |
public | function | Perform an analysis operation - report on field values in the source. | |
Migration:: |
protected | function |
Override MigrationBase::beginProcess, to make sure the map/message tables
are present. Overrides MigrationBase:: |
|
Migration:: |
protected | function | Standard top-of-loop stuff, common between rollback and import - check for exceptional conditions, and display feedback. | |
Migration:: |
protected | function | If stub creation is enabled, try to create a stub and save the mapping. | |
Migration:: |
protected | function | Fetch the key array for the current source record. | |
Migration:: |
public static | function |
Deregister a migration - remove all traces of it from the database (without
touching any content which was created by this migration). Overrides MigrationBase:: |
|
Migration:: |
constant | |||
Migration:: |
public | function |
Override MigrationBase::endProcess, to call post hooks. Note that it must
be public to be callable as the shutdown function. Overrides MigrationBase:: |
|
Migration:: |
public | function | Get the number of source records which failed to import. TODO: Doesn't yet account for informationals, or multiple errors for a source record. | |
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
protected | function | For fields which require uniqueness, assign a new unique value if necessary. | |
Migration:: |
protected | function | Look up a value migrated in another migration. | |
Migration:: |
protected | function | Perform an import operation - migrate items from source to destination. | |
Migration:: |
public | function | Get the number of records successfully imported. | |
Migration:: |
public | function |
Reports whether this migration process is complete (i.e., all available
source rows have been processed). Overrides MigrationBase:: |
|
Migration:: |
protected | function | Test whether we've exceeded the designated item limit. | |
Migration:: |
public | function | Load any stored field mappings from the database. | |
Migration:: |
public | function | Get the number of messages associated with this migration | |
Migration:: |
protected | function | React when migration didn't failed but destination ids are empty. | |
Migration:: |
protected | function | React when there is an exception | |
Migration:: |
protected | function | React when there is a migrate exception | |
Migration:: |
protected | function | React when the migration has been successful. | |
Migration:: |
protected | function | ||
Migration:: |
protected | function | Default implementations of pre/post import/rollback methods. These call the destination methods (if they exist) - when overriding, always call parent::preImport() etc. | |
Migration:: |
public | function | Default implementation of prepareKey. This method is called from the source plugin immediately after retrieving the raw data from the source - by default, it simply assigns the key values based on the field names passed to MigrateSQLMap(). Override… | |
Migration:: |
public | function | Prepares this migration to run as an update - that is, in addition to unmigrated content (source records not in the map table) being imported, previously-migrated content will also be updated in place. | |
Migration:: |
protected | function | ||
Migration:: |
public | function | Get the number of source records processed. | |
Migration:: |
public | function | Queue messages to be later saved through the map class. | |
Migration:: |
public static | function |
Register a new migration process in the migrate_status table. This will
generally be used in two contexts - by the class detection code for
static (one instance per class) migrations, and by the module implementing
dynamic (parameterized class)… Overrides MigrationBase:: |
|
Migration:: |
public | function | Remove any existing coded mappings for a given destination or source field. | |
Migration:: |
protected | function | Perform a rollback operation - remove migrated items from the destination. | |
Migration:: |
public static | function | Record an array of field mappings to the database. | |
Migration:: |
public | function |
Pass messages through to the map class. Overrides MigrationBase:: |
|
Migration:: |
public | function | Save any messages we've queued up to the message table. | |
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | ||
Migration:: |
public | function | Set the specified row to be updated, if it exists. | |
Migration:: |
constant | Indicate whether the primary system of record for this migration is the source, or the destination (Drupal). In the source case, migration of an existing object will completely replace the Drupal object with data from the source side. In the… | ||
Migration:: |
public | function | Convenience function to return count of total source records | |
Migration:: |
public | function | Get the number of records marked as needing update. | |
MigrationBase:: |
protected | property | Arguments configuring a migration. | |
MigrationBase:: |
protected | property | A time limit in seconds appropriate to be used in a batch import. Defaults to 240. | |
MigrationBase:: |
protected static | property | Track the migration currently running, so handlers can easily determine it without having to pass a Migration object everywhere. | |
MigrationBase:: |
protected | property | List of other Migration classes which should be imported before this one. E.g., a comment migration class would typically have node and user migrations as dependencies. | |
MigrationBase:: |
protected | property | Detailed information describing the migration. | |
MigrationBase:: |
protected | property | Any module hooks which should be disabled during migration processes. | |
MigrationBase:: |
protected static | property | Name of a function for displaying feedback. It must take the message to display as its first argument, and a (string) message type as its second argument (see drush_log()). | |
MigrationBase:: |
protected static | property | ||
MigrationBase:: |
protected | property | Disabling a migration prevents it from running with --all, or individually without --force | |
MigrationBase:: |
protected | property | A migration group object, used to collect related migrations. | |
MigrationBase:: |
protected static | property | Have we already warned about obsolete constructor argumentss on this request? | |
MigrationBase:: |
protected | property | If provided, an URL for an issue tracking system containing :id where the issue number will go (e.g., 'http://example.com/project/ticket/:id'). | |
MigrationBase:: |
protected | property | Whether to maintain a history of migration processes in migrate_log | |
MigrationBase:: |
protected | property | Primary key of the current history record (inserted at the beginning of a process, to be updated at the end) | |
MigrationBase:: |
protected | property | The machine name of this Migration object, derived by removing the 'Migration' suffix from the class name. Used to construct default map/message table names, displayed in drush migrate-status, key to migrate_status table... | |
MigrationBase:: |
protected | property | An array to track 'mail_system' variable if disabled. | |
MigrationBase:: |
protected | property | The PHP memory_limit expressed in bytes. | |
MigrationBase:: |
protected | property | The fraction of the memory limit at which an operation will be interrupted. Can be overridden by a Migration subclass if one would like to push the envelope. Defaults to 85%. | |
MigrationBase:: |
protected | property | Save options passed to current operation | |
MigrationBase:: |
protected | property | If we set an error handler (during import), remember the previous one so it can be restored. | |
MigrationBase:: |
protected | property | Indicates that we are processing a rollback or import - used to avoid excess writes in endProcess() | |
MigrationBase:: |
protected static | property | Track whether or not we've already displayed an encryption warning | |
MigrationBase:: |
protected | property | When the current operation started. | |
MigrationBase:: |
protected | property | Are we importing, rolling back, or doing nothing? | |
MigrationBase:: |
protected | property | MigrateTeamMember objects representing people involved with this migration. | |
MigrationBase:: |
protected | property | The PHP max_execution_time. | |
MigrationBase:: |
protected | property | The fraction of the time limit at which an operation will be interrupted. Can be overridden by a Migration subclass if one would like to push the envelope. Defaults to 90%. | |
MigrationBase:: |
protected | property | Number of "items" processed in the current migration process (whatever that means for the type of process) | |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public static | function | ||
MigrationBase:: |
public static | function | Decrypt an incoming value. | |
MigrationBase:: |
public static | function | Make sure any arguments we want to be decrypted get decrypted. | |
MigrationBase:: |
protected | function | Reports whether all (hard) dependencies have completed migration | |
MigrationBase:: |
public | function | Disables mail system to prevent emails from being sent during migrations. | |
MigrationBase:: |
public static | function | Output the given message appropriately (drush_print/drupal_set_message/etc.) | |
MigrationBase:: |
public static | function | Encrypt an incoming value. Detects for existence of the Drupal 'Encrypt' module. | |
MigrationBase:: |
public static | function | Make sure any arguments we want to be encrypted get encrypted. | |
MigrationBase:: |
public | function | Custom PHP error handler. TODO: Redundant with hook_watchdog? | |
MigrationBase:: |
protected | function | The migration machine name is stored in the arguments. | 1 |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | Fetch the current highwater mark for updated content. | |
MigrationBase:: |
public static | function | Return the single instance of the given migration. | |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | Retrieve the last time an import operation completed successfully. | |
MigrationBase:: |
public | function | Retrieve the last throughput for current Migration (items / minute). | |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | Get human readable name for a message constant. | |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | Check the current status of a migration. | |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | Takes an Exception object and both saves and displays it, pulling additional information on the location triggering the exception. | |
MigrationBase:: |
public | function | Returns an array of the migration's dependencies that are incomplete. | |
MigrationBase:: |
public static | function | 1 | |
MigrationBase:: |
protected static | function | Given only a class name, derive a machine name (the class name with the "Migration" suffix, if any, removed). | |
MigrationBase:: |
protected | function | Test whether we've exceeded the desired memory threshold. If so, output a message. | |
MigrationBase:: |
constant | Message types to be passed to saveMessage() and saved in message tables. MESSAGE_INFORMATIONAL represents a condition that did not prevent the operation from succeeding - all others represent different severities of conditions resulting in a source… | ||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
public | function | Perform an operation during the import phase | |
MigrationBase:: |
public | function | Perform an operation during the rollback phase. | |
MigrationBase:: |
public | function | Reset the status of the migration to IDLE (to be used when the status gets stuck, e.g. if a process core-dumped) | |
MigrationBase:: |
public | function | Restores the original saved mail system for migrations that require it. | |
MigrationBase:: |
constant | Codes representing the result of a rollback or import process. | ||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
protected | function | Save the highwater mark for this migration (but not when using an idlist). | |
MigrationBase:: |
public | function | Saves the current mail system, or set a system default if there is none. | |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | Set the PHP time limit. This method may be called from batch callbacks before calling the processImport method. | |
MigrationBase:: |
public | function | ||
MigrationBase:: |
public static | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public | function | ||
MigrationBase:: |
public static | function | Initialize static members, before any class instances are created. | |
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | Codes representing the current status of a migration, and stored in the migrate_status table. | ||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
constant | |||
MigrationBase:: |
public | function | Signal that any current import or rollback process should end itself at the earliest opportunity | |
MigrationBase:: |
protected | function | Test whether we're approaching the PHP time limit. | |
MigrationBase:: |
protected | function | Test whether we've exceeded the designated time limit. | |
MigrationBase:: |
public static | function | Convert an incoming string (which may be a UNIX timestamp, or an arbitrarily-formatted date/time string) to a UNIX timestamp. | |
WordPressItemMigration:: |
protected | property | ||
WordPressItemMigration:: |
protected | property | Indicates to the complete() method that the nid of this item needs to be saved in linksToFix for later processing. | |
WordPressItemMigration:: |
protected static | property | List of nids which have links needing fixing. | |
WordPressItemMigration:: |
protected | property | The <wp:post_type> value we're looking for in this migration (post/page/attachment). | |
WordPressItemMigration:: |
protected | property | Track the fields for the term references, so we can fix up if necessary in prepare(). | |
WordPressItemMigration:: |
public | function | Complete node - called just after node_save(). | |
WordPressItemMigration:: |
protected | function | Replace any hrefs to links of the form http://example.wordpress.com/?=23 to local links to a node. | |
WordPressItemMigration:: |
public | function | ||
WordPressItemMigration:: |
protected | function | Blubrry PowerPress podcast values are of the form http://www.example.com/audio/example.mp3 7662957 audio/mpeg a:1:{s:8:"duration";s:8:"00:05:19";} We will extract and return the first line, the URL of the audio file. | |
WordPressItemMigration:: |
public | function | Prepare node - called just before node_save(). | |
WordPressItemMigration:: |
public | function |
Data manipulations to be performed before the migrate module applies mappings. Overrides Migration:: |
|
WordPressItemMigration:: |
protected | function | Rewrite [caption] tags into HTML representing a caption. [caption] itself ($matches[1]) will become an opening <div>, the content within the tag ($matches[2]) will be passed through unchanged, and the closing [/caption] ($matches[3]) will become… | |
WordPressItemMigration:: |
protected | function | If we have a YouTube or other media reference, replace it with media tags. | |
WordPressItemMigration:: |
protected | function | Replace a kml_flashembed tag with an HTML <object> tag. | |
WordPressItemMigration:: |
protected | function | ||
WordPressItemMigration:: |
protected | function | If we have a local link of the form ?p=34, translate the WordPress ID into a Drupal nid, and rewrite the link. | |
WordPressItemMigration:: |
public | function |
Set it up Overrides WordPressMigration:: |
2 |
WordPressMigration:: |
protected | property | The blog object representing a set of migrations. | |
WordPressMigration:: |
protected | property | List of items skipped because they don't belong in the migration at all (e.g., wrong post type). | |
WordPressMigration:: |
protected | property | The filespec of the WXR file this migration is based on. | |
WordPressMigration:: |
protected | function | Work-around for http://drupal.org/node/936222 - make sure our node_save() calls not governed by the node destination class do not overwrite aliases. | |
WordPressMigration:: |
protected | function |
Called after completion of each migration. Overrides Migration:: |
2 |
WordPressMigration:: |
protected | function |
Outputs a progress message, reflecting the current status of a migration process. Overrides Migration:: |
|
XMLMigration:: |
public | function |
So we can create our special field mapping class. Overrides Migration:: |
|
XMLMigration:: |
protected | function |
A normal $data_row has all the input data as top-level fields - in this
case, however, the data is embedded within a SimpleXMLElement object in
$data_row->xml. Explode that out to the normal form, and pass on to the
normal implementation. Overrides Migration:: |
|
XMLMigration:: |
public | function | Gets item from XML using the xpath. |