I am trying to migrate files to a content type called educational activity. My issue is that some instances of this content type have more than one file attachment. So what I am trying to do is use concatenation to get all the file names in one field and then append them to the node like it's done with multi-value fields. However the migration outputs: "ltrim() expects parameter 1 to be string, array given". It seems that after the concatenation I end up with an array of arrays instead of an array with file names, but I can't figure out why.
This is the code:
class EducationalActivityMigration extends EduMigration {
public function __construct() {
parent::__construct();
#Define variable for the default user id (user="grammateia") wherever it is used (uid, revision_uid, etc.).
$user=36;
# Human-friendly description of your migration process. Be as detailed as you like.
$this->description = t('Migrate the Educational Activity content type along with its fields');
/**
* We create the mapping in the database to be migrated instead of our default db.
* Map Tables issue: http://drupal.org/node/1014558.
*/
$this->map = new MigrateSQLMap($this->machineName,
array(
'nid' => array('type' => 'int',
'not null' => TRUE,
'description' => 'Node ID',
'alias' => 'n'
)
),
MigrateDestinationNode::getKeySchema(), 'migrationDB');
$query = Database::getConnection('default', 'migrationDB')
->select('node', 'n');
$query->leftJoin('content_field_description', 'fd', 'n.nid = fd.nid');
$query->join('node_revisions', 'nrevi', 'nrevi.vid = n.vid');
//$query->leftJoin('node_revisions', 'nrev', 'n.nid = nrev.nid');
$query->leftJoin('content_field_age', 'fa', 'n.nid = fa.nid');
$query->leftJoin('content_field_target_group', 'tg', 'n.nid = tg.nid');
$query->leftJoin('content_field_rights_type', 'rt', 'n.nid = rt.nid');
$query->leftJoin('content_field_rights_holder', 'rh', 'n.nid = rh.nid');
$query->leftJoin('content_field_use_license', 'ul', 'n.nid = ul.nid');
$query->leftJoin('content_field_educational_stage', 'es', 'n.nid = es.nid');
$query->leftJoin('content_field_course', 'co', 'n.nid = co.nid');
$query->leftJoin('content_field_class', 'cl', 'n.nid = cl.nid');
$query->leftJoin('content_field_related_key_competence', 'rkc', 'n.nid = rkc.nid');
$query->leftJoin('content_field_filename', 'fi', 'n.nid = fi.nid');
$query->leftJoin('files', 'fil', 'fil.fid = fi.field_filename_fid');
$query->leftJoin('content_field_images', 'fim', 'n.nid = fim.nid');
$query->leftJoin('files', 'file', 'file.fid = fim.field_images_fid');
$query->addExpression('GROUP_CONCAT(DISTINCT fa.field_age_value)', 'age_list');
$query->addExpression('GROUP_CONCAT(DISTINCT tg.field_target_group_value)', 'target_list');
$query->addExpression('GROUP_CONCAT(rt.field_rights_type_value)', 'rights_list');
$query->addExpression('GROUP_CONCAT(DISTINCT rh.field_rights_holder_value)', 'holder_list');
$query->addExpression('GROUP_CONCAT(ul.field_use_license_value)', 'license_list');
$query->addExpression('GROUP_CONCAT(es.field_educational_stage_value)', 'edustage_list');
$query->addExpression('GROUP_CONCAT(DISTINCT co.field_course_value)', 'course_list');
$query->addExpression('GROUP_CONCAT(DISTINCT cl.field_class_value)', 'class_list');
$query->addExpression('GROUP_CONCAT(DISTINCT rkc.field_related_key_competence_value)', 'competence_list');
$query->addExpression('GROUP_CONCAT(fil.filename)', 'file_list');
//$query->addExpression('GROUP_CONCAT(file.filename)', 'image_list');
$query->fields('n')
->fields('fd', array('field_description_value'))
->fields('nrevi', array('body'))
->fields('fa', array('field_age_value'))
->fields('tg', array('field_target_group_value'))
->fields('rt', array('field_rights_type_value'))
->fields('rh', array('field_rights_holder_value'))
->fields('ul', array('field_use_license_value'))
->fields('es', array('field_educational_stage_value'))
->fields('co', array('field_course_value'))
->fields('cl', array('field_class_value'))
->fields('rkc', array('field_related_key_competence_value'))
->fields('fil', array('fid', 'filename', 'filepath', 'filemime', 'filesize', 'timestamp'))
->fields('file', array('fid', 'filename', 'filepath', 'filemime', 'filesize', 'timestamp'))
->condition('type', "educational_activity",'=')
->groupBy('n.nid');
# Create a MigrateSource object, which manages retrieving the input data.
$this->source = new MigrateSourceSQL($query);
# Set up our destination node as the Educational Activity node
$this->destination = new MigrateDestinationNode('educational_activity');
/**
* FIELDS WITH THE SAME NAME IN BOTH DBs
*
* @nid: The primary identifier for a node.
* @title: General title of the node in plain text.
* @status: Boolean expression stating if the node is published.
* @created: Integer type timestamp of the node's creation.
* @changed: Integer type timestamp of the node's latest change.
* @promote: Boolean expression indicating if the node is present in the front page.
* @sticky: Boolean expression stating if the node should be at the top of the list wherever it appears.
* @comment:Shows whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).
*
*/
$this->addSimpleMappings(array ('title', 'status', 'created', 'changed', 'promote', 'sticky',
'comment'));
/**
* FIELDS WITH DEFAULT VALUES
*
* @uid: value "36" corresponds to "grammateia" user.
* @language: default value set to "Ellinika".
* @translate: default value set to False.
* @tnid:The translation set id for this node, which equals the node id of the source post in each set.
* @revision_uid: The user id that shows which user did the revision.
*/
$this->addFieldMapping('uid')
->defaultValue($user);
$this->addFieldMapping('language', 'language')
->defaultValue('el');
$this->addFieldMapping('translate', 'translate')
->defaultValue('FALSE');
$this->addFieldMapping('tnid', 'tnid')
->defaultValue('0');
$this->addFieldMapping('revision_uid')
->defaultValue($user);
/**
* FIELDS PENDING MIGRATION
*
* @vid: It means 'version id'. For every node in the node table, Drupal can save multiple versions in the node_revisions table.
* The version id is the unique identifier in the node_revisions table.
*/
$this->addFieldMapping('vid', 'vid')
->description(t('Pending Migration Status'))
->issueGroup(t('What are gonna do with these?'));
/**
* SOURCE FIELDS NOT TO BE MIGRATED
*
* @type: Shows the content type, not needed since we input the type in the MigrateDestinationNode constructor.
* @moderate: Boolean expression showing if the node is under moderation. Moderation support has moved out of core.
*/
$this->addUnmigratedSources(array ('type', 'moderate', 'field_programma_ekpaid', 'field_syggrafiki_omada_ekp', 'field_schoolunit_ekp', 'fid','filepath', 'filemime', 'filesize', 'timestamp', 'file_fid', 'file_filepath', 'file_filemime', 'file_filesize', 'file_timestamp'), t('Source fields that we will not be migrating'));
/**
* DESTINATION FIELDS NOT TO BE MIGRATED
*/
$this->addUnmigratedDestinations (array('revision', 'log', 'is_new', 'field_rights_holder:language', 'field_keywords',
'field_keywords:source_type', 'field_keywords:create_term', 'field_keywords:ignore_case', 'field_knowledge_tree_category',
'field_knowledge_tree_category:source_type', 'field_knowledge_tree_category:create_term', 'field_knowledge_tree_category:ignore_case',
'field_tag', 'field_tag:source_type', 'field_tag:create_term', 'field_tag:ignore_case', 'field_related_item:language', 'field_body:summary',
'field_body:format', 'field_body:language', 'field_description:language', 'field_description:format', 'field_attachment:destination_file', 'field_attachment:description', 'field_attachment:display'),t('Destination fields that we will not be migrating'));
/**
* FIELDS TO BE MIGRATED
*/
$this->addFieldMapping('field_body', 'body')
->arguments(array('format' => 'full_html'));
$this->addFieldMapping('field_description', 'field_description_value')
->arguments(array('format' => 'full_html'));
$this->addFieldMapping('field_age', 'age_list')
->separator(',')
->arguments(array('source_type' => 'field_age_value'));
$this->addFieldMapping('field_target_group', 'target_list')
->separator(',')
->arguments(array('source_type' => 'field_target_group_value'));
$this->addFieldMapping('field_rights_type', 'rights_list')
->separator(',')
->arguments(array('source_type' => 'field_rights_type_value'));
$this->addFieldMapping('field_rights_holder', 'holder_list')
->separator('--')
->arguments(array('source_type' => 'field_rights_holder_value'));
$this->addFieldMapping('field_use_license', 'license_list')
->separator(',')
->arguments(array('source_type' => 'field_use_license_value'));
$this->addFieldMapping('field_educational_stage', 'edustage_list')
->separator(',')
->arguments(array('source_type' => 'field_educational_stage_value'));
$this->addFieldMapping('field_course', 'course_list')
->separator(',')
->arguments(array('source_type' => 'field_course_value'));
$this->addFieldMapping('field_class', 'class_list')
->separator(',')
->arguments(array('source_type' => 'field_class_value'));
$this->addFieldMapping('field_related_key_competence', 'competence_list')
->separator(',')
->arguments(array('source_type' => 'field_related_key_competence_value'));
$this->addFieldMapping('field_attachment:file_class')
->defaultValue('MigrateFileUri');
$this->addFieldMapping('field_attachment:language')
->defaultValue('el');
$this->addFieldMapping('field_attachment:destination_dir')
->defaultValue('sites/default/files/educational_activity');
$this->addFieldMapping('field_attachment:file_replace')
->defaultValue('FILE_EXISTS_REUSE');
$this->addFieldMapping('field_attachment:preserve_files')
->defaultValue(TRUE);
$this->addFieldMapping('field_attachment:source_dir')
->defaultValue('C:/xampp/htdocs/protovoulia.org/sites/default/files');
#Copy files (word etc)
$this->addFieldMapping('field_attachment', 'file_list')
->separator(',')
->arguments(array('source_type' => 'filename'));
#Copy Images
//$this->addFieldMapping('field_attachment', 'image_list')
//->separator(',')
//->arguments(array('source_type' => 'filename'));
/**
* We conditionally DNM these fields, so your field mappings will be clean,
* whether or not you have path and or pathauto enabled.
*/
if(module_exists('path')) {
$this->addFieldMapping('path')
->issueGroup(t('DNM'));
if (module_exists('pathauto')) {
$this->addFieldMapping('pathauto')
->issueGroup(t('DNM'));
}
}//if ends
}//construct ends
}//class ends
Unfortunately, I didn't come to a working solution reading all the other questions.