| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <!-- $Id: api.html,v 1.1.2.7 2009/08/23 23:40:46 mikeryan Exp $ --> 2 3 <h2 id="destinationtypes">Destination types</h2> 4 5 <p>The migrate module supports the definition of different destination types - kinds of objects 6 to be created in a migration. There is built-in support for nodes, users, comments, roles, and 7 taxonomy terms - hooks can be defined for additional destination types.</p> 8 9 <p>Here are the steps we took to create the Role destination type. Your destination types will 10 follow a similar pattern.</p> 11 12 <ul> 13 <li><p>Implement <strong>hook_migrate_types()</strong>, returning an array mapped 14 from the internal name of the type (used to build hook names, in particular) to the user-visible 15 type name:</p> 16 17 <p><pre>function user_migrate_types() { 18 $types = array('user' => t('User'), 'role' => t('Role')); 19 return $types; 20 }</pre></p></li> 21 <li><p>Implement <strong>hook_migrate_fields_<type></strong>, returning an 22 array mapped from the internal field name (within Drupal) to the user-visible name:</p> 23 24 <p><pre>function user_migrate_fields_role($type) { 25 $fields = array( 26 'name' => t('Role name'), 27 ); 28 return $fields; 29 }</pre></p></li> 30 <li><p>Implement <strong>hook_migrate_delete_<type></strong>, which takes the 31 unique identifier of the destination object on the Drupal side and deletes that object and 32 everything that depends on that object:</p> 33 34 <p><pre>function user_migrate_delete_role($rid) { 35 db_query('DELETE FROM {users_roles} WHERE rid = %d', $rid); 36 db_query('DELETE FROM {permission} WHERE rid = %d', $rid); 37 db_query('DELETE FROM {role} WHERE rid = %d', $rid); 38 }</pre></p></li> 39 <li><p>Now, here’s the major work: implement <strong>hook_migrate_import_<type></strong> :</p> 40 41 <p><pre> 42 function user_migrate_import_role($tblinfo, $row) { 43 $errors = array(); 44 $newrole = array(); 45 // For each destination field, populate it with the source value if present, and if 46 // if not use the specified default value 47 foreach ($tblinfo->fields as $destfield => $values) { 48 if ($values['srcfield'] && isset($row->$values['srcfield'])) { 49 $newvalue = $row->$values['srcfield']; 50 } else { 51 $newvalue = $values['default_value']; 52 } 53 $newrole[$destfield] = $newvalue; 54 } 55 $role_name = $newrole['name']; 56 if ($role_name) { 57 db_query("INSERT INTO {role} (name) VALUES ('%s')", $role_name); 58 $sql = "SELECT * FROM {role} WHERE name='%s'"; 59 $role = db_fetch_object(db_query($sql, $role_name)); 60 // Call completion hooks, for any additional role-related processing 61 // (such as assigning permissions) 62 timer_start('role completion hooks'); 63 $errors = migrate_invoke_all('complete_role', $role, $tblinfo, $row); 64 timer_stop('role completion hooks'); 65 // Fill in the map table, so the migrate module knows this row is done 66 $sourcekey = $tblinfo->sourcekey; 67 migrate_add_mapping($tblinfo->mcsid, $row->$sourcekey, $role->rid); 68 } 69 return $errors; 70 }</pre></p></li> 71 </ul> 72 73 <p>$tblinfo contains the meta-information on the content set, and $row is the source data for one object. 74 An array of messages is returned - use migrate_message() to generate a message. </p> 75 76 <h2 id="contentsets">Content sets</h2> 77 78 <p>A content set defines the migration from a set of source data (implemented as a view) into 79 a given destination type. Content sets can be defined interactively or programmatically. The 80 typical process to create a content set programmatically would be as follows:</p> 81 82 <ul> 83 <li><p>Add an update function to the .install file for a custom module (this document calls it 84 ec_migrate.install). In the update function, first add any source tables to the Table Wizard. 85 Pass TRUE to prevent immediate full analysis of the table (otherwise, for large tables, the 86 update function risks timing out).</p> 87 88 <p><pre>tw_add_tables('role_o', TRUE);</pre></p></li> 89 <li><p>If these tables need to relate to other tables, add FK flags to any columns used in joins, 90 and add the relationships:</p> 91 92 <p><pre> 93 function tw_add_fk($tablename, $colname) 94 95 } 96 97 /** 98 * Add a relationship between two table columns, making it possible to join them in Views 99 * 100 * @param $leftcol 101 * The left side of a potential join, expressed either as a column ID from 102 * {tw_columns} or as a string in [connection.]table.column format. 103 * @param $rightcol 104 * The right side of a potential join, expressed either as a column ID from 105 * {tw_columns} or as a string in [connection.]table.column format. 106 * @param $automatic 107 * Boolean indicating whether to create views joins (i.e., relate the table 108 * automatically) or relationships. 109 */ 110 function tw_add_relationship($leftcol, $rightcol, $automatic = FALSE) { 111 </pre></p></li> 112 <li><p>If the content set is based only on a single source table with a single primary key, and 113 requires no filtering, the default view instantiated by the Table Wizard for that table can be 114 used in the content set. Otherwise, you need to define a view containing all the necessary data 115 as a default view (create the view interactively, export, and paste the code into 116 ec_migrate.views_default.inc). Naming convention is <destination>_content_set (e.g., 117 role_content_set).</p></li> 118 <li><p>Create the content set in your update function, by building the object and saving it:</p> 119 120 <p><pre>$content_set = new stdClass; 121 $content_set->view_name = 'role_content_set'; 122 $content_set->sourcekey = 'role_id'; 123 $content_set->contenttype = 'role'; 124 $content_set->description = 'Roles'; 125 $content_set->weight = 9; 126 migrate_save_content_set($content_set, array('base_table' => 'role_o')); 127 $mcsid = $content_set->mcsid;</pre></p> 128 129 <p>For each field to automatically be copied from a source field to a destination field, build 130 a mapping object and save it:</p> 131 132 <p><pre>$mapping = new stdClass; 133 $mapping->mcsid = $mcsid; 134 $mapping->srcfield = 'role_o_role_name'; 135 $mapping->destfield = 'name'; 136 migrate_save_content_mapping($mapping);</pre></p></li> 137 <li><p>Usually, simply copying source fields to destination fields are not enough - you need 138 to implement a hook to perform further manipulations. A destination type may support a prepare 139 hook such as <strong>hook_migrate_prepare_OBJECT</strong> (called for each object 140 after the automatic mappings are applied but before the destination is saved) and/or a complete 141 hook (called after the destination is saved). The standard signature is:</p> 142 143 <p><pre> 144 function ec_migrate_migrate_prepare_user(&$account, $tblinfo, $row) 145 // Role assignments 146 timer_start('role assignments'); 147 148 // Everyone's a contributor 149 if (!isset($account['roles'])) { 150 $account['roles'] = array(); 151 } 152 static $contributor_rid; 153 if (!isset($contributor_rid)) { 154 install_include(array('user')); 155 $contributor_rid = install_get_rid('contributor'); 156 } 157 $account['roles'][$contributor_rid] = $contributor_rid; 158 159 $sql = "SELECT map.destid AS rid 160 FROM {customer_role} cr 161 INNER JOIN {role_content_set_map} map ON cr.role_id=map.sourceid 162 WHERE cr.customer_id=%d AND cr.active='Y' AND 163 (cr.expires IS NULL OR cr.expires > NOW())"; 164 $result = db_query($sql, $row->customer_id); 165 while ($row = db_fetch_object($result)) { 166 $account['roles'][$row->rid] = $row->rid; 167 } 168 timer_stop('role assignments'); 169 170 return $errors; 171 } 172 </pre></p> 173 174 <ul> 175 <li>$account - The destination object (in this case, a user account object) 176 <li>$tblinfo - Information on the content set itself 177 <li>$row - The source data 178 </ul> 179 </li>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |