1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Features support to export entities from any Deploy <em>fetch-only</em> plan.
|
6
|
*/
|
7
|
|
8
|
/**
|
9
|
* Implements [component]_features_export_options().
|
10
|
*
|
11
|
* Deploy plans are used as the initial source for an export. Deploy solves
|
12
|
* complex dependency chains for us, so the entities actually can be used as is.
|
13
|
*/
|
14
|
function uuid_entities_features_export_options() {
|
15
|
$options = array();
|
16
|
if (module_exists('deploy')) {
|
17
|
$plans = deploy_plan_load_all(array('fetch_only' => 1));
|
18
|
foreach ($plans as $plan) {
|
19
|
$options[$plan->name] = $plan->title;
|
20
|
}
|
21
|
}
|
22
|
return $options;
|
23
|
}
|
24
|
|
25
|
/**
|
26
|
* Implements [component]_features_export().
|
27
|
*/
|
28
|
function uuid_entities_features_export($components, &$export, $module_name) {
|
29
|
foreach ($components as $plan_name) {
|
30
|
$export['features']['uuid_entities'][$plan_name] = $plan_name;
|
31
|
}
|
32
|
}
|
33
|
|
34
|
/**
|
35
|
* Implements [component]_features_export_render().
|
36
|
*
|
37
|
* Components corresponds to the name of Deploy plans. However, once exported,
|
38
|
* entities can be rendered directly from the default hook without Deploy or the
|
39
|
* initial plan.
|
40
|
*/
|
41
|
function uuid_entities_features_export_render($module_name, $components, $export = NULL) {
|
42
|
$code = array();
|
43
|
$code[] = ' $entities = array();';
|
44
|
$code[] = '';
|
45
|
|
46
|
foreach ($components as $component) {
|
47
|
$entities = array();
|
48
|
if (module_exists('deploy') && $plan = deploy_plan_load($component)) {
|
49
|
$entities = $plan->getIterator();
|
50
|
}
|
51
|
else {
|
52
|
features_include_defaults(array('uuid_entities'));
|
53
|
$default_entities = module_invoke($module_name, 'uuid_default_entities');
|
54
|
foreach ($default_entities[$component] as $entity) {
|
55
|
$metadata = $entity->__metadata;
|
56
|
$entity_type = $metadata['type'];
|
57
|
$entity_info = entity_get_info($entity_type);
|
58
|
$results = entity_uuid_load($entity_type, array($entity->{$entity_info['entity keys']['uuid']}), NULL, TRUE);
|
59
|
if (!empty($results)) {
|
60
|
$entity = reset($results);
|
61
|
// Re-attach the metadata after loading the clean entity.
|
62
|
$entity->__metadata = $metadata;
|
63
|
$entities[] = $entity;
|
64
|
}
|
65
|
}
|
66
|
}
|
67
|
foreach ($entities as $entity) {
|
68
|
$entity_type = $entity->__metadata['type'];
|
69
|
$entity_info = entity_get_info($entity_type);
|
70
|
// We need to remove entity id and revision keys for better consistency.
|
71
|
$id_key = $entity_info['entity keys']['id'];
|
72
|
if (isset($entity->{$id_key})) {
|
73
|
unset($entity->{$id_key});
|
74
|
}
|
75
|
if (!empty($entity_info['entity keys']['revision'])) {
|
76
|
$vid_key = $entity_info['entity keys']['revision'];
|
77
|
if (isset($entity->{$vid_key})) {
|
78
|
unset($entity->{$vid_key});
|
79
|
}
|
80
|
if (!empty($entity_info['entity keys']['revision uuid'])) {
|
81
|
$vuuid_key = $entity_info['entity keys']['revision uuid'];
|
82
|
unset($entity->{$vuuid_key});
|
83
|
}
|
84
|
}
|
85
|
// We unset some common timestamp properties, since those will change and
|
86
|
// constantly leave the feature overidden.
|
87
|
$keys = array(
|
88
|
'created',
|
89
|
'updated',
|
90
|
'changed',
|
91
|
'revision_timestamp',
|
92
|
'timestamp',
|
93
|
'stamp',
|
94
|
'current',
|
95
|
);
|
96
|
foreach ($keys as $key) {
|
97
|
if (isset($entity->{$key})) {
|
98
|
unset($entity->{$key});
|
99
|
}
|
100
|
}
|
101
|
// Let other modules alter exported entities.
|
102
|
drupal_alter('uuid_entities_features_export_entity', $entity, $entity_type);
|
103
|
// Field handling.
|
104
|
list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
|
105
|
$instances = field_info_instances($entity_type, $bundle_name);
|
106
|
foreach ($instances as $field_name => $instance) {
|
107
|
$field = field_info_field($field_name);
|
108
|
if (!empty($entity->{$field_name})) {
|
109
|
foreach ($entity->{$field_name} as $langcode => &$items) {
|
110
|
// Let other modules alter fields on exported entities.
|
111
|
// We are not using drupal_alter() here, because of it's complexity
|
112
|
// dealing with over two alterable arguments.
|
113
|
$hook = 'uuid_entities_features_export_field_alter';
|
114
|
foreach (module_implements($hook) as $module_name) {
|
115
|
$function = $module_name . '_' . $hook;
|
116
|
$function($entity_type, $entity, $field, $instance, $langcode, $items);
|
117
|
}
|
118
|
foreach ($items as &$item) {
|
119
|
// We don't need to export these common field keys.
|
120
|
foreach (array('safe_value', 'safe_summary') as $key) {
|
121
|
if (isset($item[$key])) {
|
122
|
unset($item[$key]);
|
123
|
}
|
124
|
}
|
125
|
uuid_entities_features_clean($item);
|
126
|
}
|
127
|
}
|
128
|
}
|
129
|
}
|
130
|
uuid_entities_features_clean($entity);
|
131
|
|
132
|
/*
|
133
|
* Convert entities to array to avoid having them in JSON, returned
|
134
|
* from standard implementation of $entity->export().
|
135
|
*/
|
136
|
if (is_object($entity) && method_exists($entity, 'export')) {
|
137
|
$entity = get_object_vars($entity);
|
138
|
}
|
139
|
$code[] = ' $entities[\'' . check_plain($component) . '\'][] = (object) ' . features_var_export($entity, ' ') . ';';
|
140
|
}
|
141
|
}
|
142
|
$code[] = '';
|
143
|
$code[] = ' return $entities;';
|
144
|
return array('uuid_default_entities' => implode("\n", $code));
|
145
|
}
|
146
|
|
147
|
/**
|
148
|
* Implements [component]_features_rebuild().
|
149
|
*/
|
150
|
function uuid_entities_features_rebuild($module_name) {
|
151
|
uuid_entities_rebuild($module_name, 'rebuild');
|
152
|
}
|
153
|
|
154
|
/**
|
155
|
* Implements [component]_features_revert().
|
156
|
*/
|
157
|
function uuid_entities_features_revert($module_name) {
|
158
|
uuid_entities_rebuild($module_name, 'revert');
|
159
|
}
|
160
|
|
161
|
/**
|
162
|
* Helper function to rebuild entities from a plan.
|
163
|
*/
|
164
|
function uuid_entities_rebuild($module_name = '', $op = 'rebuild') {
|
165
|
features_include_defaults(array('uuid_entities'));
|
166
|
$entities = module_invoke($module_name, 'uuid_default_entities');
|
167
|
if (!empty($entities)) {
|
168
|
foreach ($entities as $plan_name => $entities) {
|
169
|
// Let other modules do things before default entities are created.
|
170
|
module_invoke_all("uuid_entities_pre_$op", $plan_name);
|
171
|
drupal_alter("uuid_entities_pre_$op", $entities, $plan_name);
|
172
|
foreach ($entities as $entity) {
|
173
|
entity_uuid_save($entity->__metadata['type'], $entity);
|
174
|
}
|
175
|
// Let other modules do things after default entities are created.
|
176
|
module_invoke_all("uuid_entities_post_$op", $plan_name);
|
177
|
}
|
178
|
}
|
179
|
}
|
180
|
|
181
|
/**
|
182
|
* Helper function to sort properties of an object.
|
183
|
*
|
184
|
* This will maintain better consistency. Keys might get shifted order or type
|
185
|
* due to alterations sometimes.
|
186
|
*/
|
187
|
function uuid_entities_features_clean(&$object) {
|
188
|
$properties = array();
|
189
|
foreach ($object as $key => $value) {
|
190
|
$properties[$key] = $value;
|
191
|
if (is_object($object)) {
|
192
|
unset($object->{$key});
|
193
|
}
|
194
|
elseif (is_array($object)) {
|
195
|
unset($object[$key]);
|
196
|
}
|
197
|
}
|
198
|
ksort($properties);
|
199
|
foreach ($properties as $key => $value) {
|
200
|
// Make properties type consistent.
|
201
|
if (is_string($value) || is_numeric($value)) {
|
202
|
if (is_object($object)) {
|
203
|
$object->{$key} = "$value";
|
204
|
}
|
205
|
elseif (is_array($object)) {
|
206
|
$object[$key] = "$value";
|
207
|
}
|
208
|
}
|
209
|
else {
|
210
|
if (is_object($object)) {
|
211
|
$object->{$key} = $value;
|
212
|
}
|
213
|
elseif (is_array($object)) {
|
214
|
$object[$key] = $value;
|
215
|
}
|
216
|
}
|
217
|
}
|
218
|
}
|