-
Notifications
You must be signed in to change notification settings - Fork 7
/
field_collection.migrate.inc
200 lines (178 loc) · 5.66 KB
/
field_collection.migrate.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<?php
/**
* @file
* Support for the Migrate API.
*
* Your field collection migration should be run after the host entity
* migration. For example, if the collection is attached to nodes via a field
* named 'field_attached_data', and if the nodes are being imported by
* ArticleMigration, your collection migration class constructor should look
* like:
*
* @code
* $this->dependencies = array('Article');
*
* $this->destination = new MigrateDestinationFieldCollection(
* 'field_attached_data',
* array('host_entity_type' => 'node')
* );
*
* $this->addFieldMapping('host_entity_id', 'source_article_id')
* ->sourceMigration('Article');
* @endcode
*
* @see http://drupal.org/node/1900640
*/
// Avoid issues when migrate module is disabled.
if (!class_exists('MigrateDestinationEntity')) {
return;
}
/**
* Destination class implementing migration into field_collection.
*/
class MigrateDestinationFieldCollection extends MigrateDestinationEntity {
/**
* The type of entity hosting this collection field (e.g., node).
*
* @var string
*/
protected $hostEntityType;
/**
*
*/
public static function getKeySchema() {
return array(
'item_id' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => 'ID of field collection item',
),
);
}
/**
* Basic initialization.
*
* @param string $bundle
* Bundle name.
* @param array $options
* (optional) Options applied to collections.
*/
public function __construct($bundle, array $options = array()) {
parent::__construct('field_collection_item', $bundle, $options);
$this->hostEntityType = $options['host_entity_type'];
}
/**
* Returns a list of fields available to be mapped for this collection
* (bundle).
*
* @return array
* Keys: machine names of the fields (to be passed to addFieldMapping).
* Values: Human-friendly descriptions of the fields.
*/
public function fields() {
$fields = migrate_handler_invoke_all('Entity', 'fields', $this->entityType(), $this->bundle());
$fields['item_id'] = t('Field collection entity ID');
$fields['host_entity_id'] = t('Field collection host ID');
return $fields;
}
/**
* Import a single field collection item.
*
* @param object $collection
* Collection object to build. Pre-filled with any fields mapped in the
* migration.
* @param object $row
* Raw source data object - passed through to prepare/complete handlers.
*
* @return array|bool
* Array of key fields (item_id only in this case) of the collection that
* was saved or FALSE on failure.
*/
public function import(stdClass $collection, stdClass $row) {
$updating = FALSE;
if (isset($row->migrate_map_destid1)) {
// We're updated an existing entity - start from the previous data.
// entity_load() returns an array, so we get the field collection entity
// with reset().
$result = entity_load('field_collection_item', array($row->migrate_map_destid1), array(), TRUE);
$entity = reset($result);
if ($entity) {
$entity_old = clone $entity;
$updating = TRUE;
}
}
if (!$updating) {
// Skip the collection if it has no host.
if (empty($collection->host_entity_id)) {
throw new MigrateException('Could not find host entity of the field collection to import.');
}
$entity = entity_create('field_collection_item', array('field_name' => $this->bundle));
$updating = FALSE;
$host_entity = entity_load($this->hostEntityType, $collection->host_entity_id);
entity_get_controller($this->hostEntityType)->resetCache();
if (isset($row->language)) {
$entity->setHostEntity($this->hostEntityType, $host_entity, $row->language, TRUE);
}
else {
$entity->setHostEntity($this->hostEntityType, $host_entity);
}
}
unset($collection->host_entity_id);
foreach ((array) $collection as $field => $value) {
$entity->{$field} = $value;
}
$this->prepare($entity, $row);
// Restore fields from original field_collection_item if updating.
if ($updating) {
foreach ($entity as $field => $value) {
if ('field_' != substr($field, 0, 6)) {
continue;
}
if (property_exists($entity_old, $field) && !property_exists($collection, $field)) {
$entity->$field = $entity_old->$field;
}
}
}
migrate_instrument_start('field_collection_save');
$status = entity_save('field_collection_item', $entity);
migrate_instrument_stop('field_collection_save');
if ($status !== FALSE || in_array($this->hostEntityType, array('node', 'field_collection_item'))) {
$this->complete($entity, $row);
if ($updating) {
$this->numUpdated++;
}
else {
$this->numCreated++;
}
return array($entity->item_id);
}
return FALSE;
}
/**
* Delete a migrated collection.
*
* @param $key
* Array of fields representing the key.
*/
public function rollback(array $key) {
$item_id = reset($key);
$this->prepareRollback($item_id);
$field_collection_item = field_collection_item_load($item_id);
// If the collection wasn't imported then we can't roll it back, so check if
// the loaded object is an instance of the FieldCollectionItemEntity class.
if ($field_collection_item instanceof FieldCollectionItemEntity) {
$field_collection_item->delete();
}
$this->completeRollback($item_id);
return TRUE;
}
}
/**
* Implements hook_migrate_api().
*/
function field_collection_migrate_api() {
return array(
'api' => 2,
);
}