class DrupalVersion5 in Drupal-to-Drupal data migration 7.2
Drupal 5 implementations of functions shared among multiple types of objects.
Hierarchy
- class \DrupalVersion
- class \DrupalVersion5
Expanded class hierarchy of DrupalVersion5
File
- d5/
d5.inc, line 10 - Implementation of DrupalVersion for Drupal 5 sources.
View source
class DrupalVersion5 extends DrupalVersion {
/**
* A list of node types associated with content_profile.
*
* @var array
*/
protected $profileTypes = array();
/**
* Generate default format mappings based on matching names. E.g., if the
* Drupal 5 database has format 5 with name 'Filtered HTML', and the Drupal 7
* databas has format filtered_html with name 'Filtered HTML', the resulting
* array will contain the row '5' => 'filtered_html'.
*/
public function getDefaultFormatMappings() {
migrate_instrument_start('DrupalVersion5::getDefaultFormatMappings');
$format_mappings = array();
$d5_formats = Database::getConnection('default', $this->arguments['source_connection'])
->select('filter_formats', 'f')
->fields('f', array(
'name',
'format',
))
->execute()
->fetchAllKeyed();
$d7_formats = db_select('filter_format', 'f')
->fields('f', array(
'name',
'format',
))
->condition('name', array_keys($d5_formats), 'IN')
->execute()
->fetchAllKeyed();
foreach ($d5_formats as $name => $format) {
if (isset($d7_formats[$name])) {
$format_mappings[$format] = $d7_formats[$name];
}
}
migrate_instrument_stop('DrupalVersion5::getDefaultFormatMappings');
return $format_mappings;
}
/**
* Given a source path (e.g, 'node/123'), return the first alias for that path.
*
* @param $source
* @return string
*/
public function getPath($source) {
migrate_instrument_start('DrupalVersion5::getPath');
if (Database::getConnection('default', $this->arguments['source_connection'])
->schema()
->tableExists('url_alias')) {
$path = Database::getConnection('default', $this->arguments['source_connection'])
->select('url_alias', 'ua')
->fields('ua', array(
'dst',
))
->condition('src', $source)
->orderBy('pid', 'DESC')
->execute()
->fetchField();
}
else {
$path = $source;
}
migrate_instrument_stop('DrupalVersion5::getPath');
return $path;
}
/**
* Retrieve info on all fields attached to the given entity type and bundle.
* Populates $this->sourceFieldInfo.
*
* @param $entity_type
* @param $bundle
* @param $include_body
*/
protected function populateSourceFieldInfo($entity_type, $bundle, $include_body = FALSE) {
if ($entity_type == 'user') {
// Get core profile fields.
$this
->profileFields();
// If there are content profiles, the recursive calls set these to
// the profile type, so reset them.
$this->entityType = $entity_type;
$this->bundle = $bundle;
}
elseif ($entity_type != 'node') {
return;
}
elseif (empty($this->sourceFieldInfo)) {
migrate_instrument_start('DrupalVersion5::sourceFieldInfo');
$this->entityType = $entity_type;
$this->bundle = $bundle;
// Get each field attached to this type.
if (Database::getConnection('default', $this->arguments['source_connection'])
->schema()
->tableExists('node_field_instance')) {
$query = Database::getConnection('default', $this->arguments['source_connection'])
->select('node_field_instance', 'i')
->fields('i', array(
'label',
'type_name',
))
->condition('type_name', $bundle);
$query
->innerJoin('node_field', 'f', 'i.field_name = f.field_name');
$query
->fields('f', array(
'field_name',
'type',
'multiple',
'db_storage',
));
$result = $query
->execute();
foreach ($result as $row) {
$field_name = trim($row->field_name);
$db_columns = $this
->getFieldTypeColumns($row);
$columns = array();
foreach ($db_columns as $column_name) {
$display_name = $field_name . ':' . $column_name;
$column_name = $field_name . '_' . $column_name;
$columns[$display_name] = $column_name;
}
$this->sourceFieldInfo[$field_name] = array(
'label' => $row->label,
'type' => $row->type,
'columns' => $columns,
'multiple' => $row->multiple,
'db_storage' => $row->db_storage,
);
}
}
// Get each vocabulary attached to this type.
$query = Database::getConnection('default', $this->arguments['source_connection'])
->select('vocabulary_node_types', 'vnt')
->fields('vnt', array(
'vid',
));
$query
->innerJoin('vocabulary', 'v', 'vnt.vid=v.vid');
$query
->addField('v', 'name');
$query
->condition('vnt.type', $bundle);
$result = $query
->execute();
foreach ($result as $row) {
$this->sourceFieldInfo[$row->vid] = array(
'label' => $row->name,
'type' => 'taxonomy_term',
);
}
migrate_instrument_stop('DrupalVersion5::sourceFieldInfo');
}
}
/**
* Detect what database columns are available for the given field.
*
* @param $field_info
* Info describing the incoming field. We specifically are looking at the
* field_name, type_name, and db_storage values.
*
* @return array
* List of column suffixes relevant to the field ('value', 'fid', etc.).
*/
protected function getFieldTypeColumns($field_info) {
$field_name = $field_info->field_name;
if ($field_info->db_storage) {
$table_name = 'content_type_' . $field_info->type_name;
}
else {
$table_name = 'content_' . $field_name;
}
$row = Database::getConnection('default', $this->arguments['source_connection'])
->select($table_name, 't')
->fields('t')
->range(0, 1)
->execute()
->fetchObject();
$type_columns = array();
if ($row) {
foreach ($row as $column_name => $column_value) {
if (!strncmp($field_name, $column_name, strlen($field_name))) {
$type_columns[] = substr($column_name, strlen($field_name) + 1);
}
}
}
return $type_columns;
}
/**
* Populate a migration's source row object with field values.
*
* @param $row
* @param $entity_id
*/
public function getSourceValues($row, $entity_id) {
if ($this->entityType == 'user') {
// First get the core profile values.
$this
->getProfileValues($row, $entity_id);
// Next, look for any associated profile nodes, and fall through to
// process them.
$entity_id_list = $revision_id_list = array();
foreach ($this->profileTypes as $type) {
$node = Database::getConnection('default', $this->arguments['source_connection'])
->select('node', 'n')
->fields('n', array(
'nid',
'vid',
))
->condition('uid', $entity_id)
->condition('type', $type)
->execute()
->fetchObject();
if ($node) {
$entity_id_list[] = $node->nid;
$revision_id_list[] = $node->vid;
}
}
}
elseif ($this->entityType == 'node') {
$entity_id_list = array(
$entity_id,
);
$revision_id_list = array(
$row->vid,
);
}
else {
return;
}
$schema = Database::getConnection('default', $this->arguments['source_connection'])
->schema();
foreach ($entity_id_list as $index => $entity_id) {
$revision_id = $revision_id_list[$index];
// Load up field data for dynamically mapped fields
foreach ($this->sourceFieldInfo as $field_name => $field_info) {
if ($field_info['type'] != 'taxonomy_term') {
// Fields in the base (content_type_foo) CCK table will have been
// incorporated into the base query, so just look for the
// shared/multiple field cases
$table = "content_{$field_name}";
if ($schema
->tableExists($table)) {
$query = Database::getConnection('default', $this->arguments['source_connection'])
->select($table, 'f')
->fields('f')
->condition('vid', $revision_id);
// There isn't always a delta,
// @see http://drupal.org/node/1715244
if ($schema
->fieldExists($table, 'delta')) {
$query
->orderBy('delta');
}
$result = $query
->execute();
foreach ($result as $field_row) {
$i = 0;
foreach ($this->sourceFieldInfo[$field_name]['columns'] as $display_name => $column_name) {
if ($i++ == 0) {
$index = $field_name;
}
else {
$index = $display_name;
}
if (isset($row->{$index}) && !is_array($row->{$index})) {
$row->{$index} = array(
$row->{$index},
);
}
$row->{$index}[] = $field_row->{$column_name};
}
}
}
}
}
// Users only (nodes do this via their base query) - get the profile node
// row
if ($this->entityType == 'user') {
foreach ($this->profileTypes as $type) {
$cck_table = 'content_type_' . $type;
$query = Database::getConnection('default', $this->arguments['source_connection'])
->select($cck_table, 'f')
->condition('vid', $revision_id);
// The main column for the field should be rendered with
// the field name, not the column name (e.g., field_foo rather
// than field_foo_value).
$field_found = FALSE;
foreach ($this->sourceFieldInfo as $field_name => $info) {
if (isset($info['columns']) && !$info['multiple'] && $info['db_storage']) {
$i = 0;
foreach ($info['columns'] as $display_name => $column_name) {
if ($i++ == 0) {
$query
->addField('f', $column_name, $field_name);
}
else {
$query
->addField('f', $column_name, $display_name);
}
$field_found = TRUE;
}
}
}
if ($field_found) {
$data_row = $query
->execute()
->fetchObject();
foreach ($data_row as $name => $value) {
$row->{$name} = $value;
}
}
}
}
// And. load up the data for taxonomy terms
$query = Database::getConnection('default', $this->arguments['source_connection'])
->select('term_node', 'tn')
->fields('tn', array(
'tid',
))
->condition('tn.nid', $row->nid);
$query
->innerJoin('term_data', 'td', 'tn.tid=td.tid');
$query
->fields('td', array(
'vid',
));
$result = $query
->execute();
foreach ($result as $term_row) {
$row->{$term_row->vid}[] = $term_row->tid;
}
}
}
/**
* Retrieve any user profile fields from the core profile module or
* content_profile.
*
* @return array
*/
protected function profileFields() {
migrate_instrument_start('DrupalVersion5::profileFields');
// Get any content_profile node types. A variable named content_profile_use_foo
// with a serialized value of 1 means foo is a node type of interest.
$names = Database::getConnection('default', $this->arguments['source_connection'])
->select('variable', 'v')
->fields('v', array(
'name',
))
->condition('name', 'content_profile_use_%', 'LIKE')
->condition('value', 'i:1;')
->execute()
->fetchCol();
$index = strlen('content_profile_use_');
foreach ($names as $name) {
$type_name = substr($name, $index);
$this->profileTypes[] = $type_name;
// Populates sourceFieldInfo directly
$this
->populateSourceFieldInfo('node', $type_name);
}
// Then, check the core profile
if (Database::getConnection('default', $this->arguments['source_connection'])
->schema()
->tableExists('profile_fields')) {
$query = Database::getConnection('default', $this->arguments['source_connection'])
->select('profile_fields', 'f')
->fields('f', array(
'title',
'name',
'type',
));
$result = $query
->execute();
foreach ($result as $row) {
$this->sourceFieldInfo[trim($row->name)] = array(
'label' => $row->title,
'type' => $row->type,
);
}
}
migrate_instrument_stop('DrupalVersion5::profileFields');
}
/**
* Get any core profile values associated with this user.
*
* @param $row
* @param $entity_id
* @param $include_body
*/
public function getProfileValues($row, $entity_id, $include_body = FALSE) {
if (Database::getConnection('default', $this->arguments['source_connection'])
->schema()
->tableExists('profile_values')) {
migrate_instrument_start('DrupalVersion5::getProfileValues');
$row = parent::getProfileValues($row, $entity_id);
migrate_instrument_stop('DrupalVersion5::getProfileValues');
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DrupalVersion5:: |
protected | property | A list of node types associated with content_profile. | |
DrupalVersion5:: |
public | function |
Generate default format mappings based on matching names. E.g., if the
Drupal 5 database has format 5 with name 'Filtered HTML', and the Drupal 7
databas has format filtered_html with name 'Filtered HTML', the resulting
array will… Overrides DrupalVersion:: |
|
DrupalVersion5:: |
protected | function | Detect what database columns are available for the given field. | |
DrupalVersion5:: |
public | function |
Given a source path (e.g, 'node/123'), return the first alias for that path. Overrides DrupalVersion:: |
|
DrupalVersion5:: |
public | function |
Get any core profile values associated with this user. Overrides DrupalVersion:: |
|
DrupalVersion5:: |
public | function |
Populate a migration's source row object with field values. Overrides DrupalVersion:: |
|
DrupalVersion5:: |
protected | function | Retrieve info on all fields attached to the given entity type and bundle. Populates $this->sourceFieldInfo. | |
DrupalVersion5:: |
protected | function | Retrieve any user profile fields from the core profile module or content_profile. | |
DrupalVersion:: |
protected | property | Arguments for the containing migration. Primarily of interest for the source_connection. | |
DrupalVersion:: |
protected | property | The bundle (node type pre-D7) - article, blog, etc. | |
DrupalVersion:: |
protected | property | The entity type (node, user, etc.) | |
DrupalVersion:: |
protected | property | An array of information on CCK/core fields. | |
DrupalVersion:: |
public | function | ||
DrupalVersion:: |
public | function | @abstract Return the names and labels of all custom fields (CCK pre-D7, core fields D7 and later) attached to the given entity type and bundle. | |
DrupalVersion:: |
public | function | Pass the migration class arguments through to the version class. |