1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Install, update and uninstall functions for the field_collection module.
|
6
|
*/
|
7
|
|
8
|
/**
|
9
|
* Implements hook_schema().
|
10
|
*/
|
11
|
function field_collection_schema() {
|
12
|
|
13
|
$schema['field_collection_item'] = array(
|
14
|
'description' => 'Stores information about field collection items.',
|
15
|
'fields' => array(
|
16
|
'item_id' => array(
|
17
|
'type' => 'serial',
|
18
|
'not null' => TRUE,
|
19
|
'description' => 'Primary Key: Unique field collection item ID.',
|
20
|
),
|
21
|
'revision_id' => array(
|
22
|
'type' => 'int',
|
23
|
'not null' => TRUE,
|
24
|
'description' => 'Default revision ID.',
|
25
|
),
|
26
|
'field_name' => array(
|
27
|
'description' => 'The name of the field on the host entity embedding this entity.',
|
28
|
'type' => 'varchar',
|
29
|
'length' => 32,
|
30
|
'not null' => TRUE,
|
31
|
),
|
32
|
'archived' => array(
|
33
|
'description' => 'Boolean indicating whether the field collection item is archived.',
|
34
|
'type' => 'int',
|
35
|
'not null' => TRUE,
|
36
|
'default' => 0,
|
37
|
),
|
38
|
),
|
39
|
'primary key' => array('item_id'),
|
40
|
);
|
41
|
$schema['field_collection_item_revision'] = array(
|
42
|
'description' => 'Stores revision information about field collection items.',
|
43
|
'fields' => array(
|
44
|
'revision_id' => array(
|
45
|
'type' => 'serial',
|
46
|
'not null' => TRUE,
|
47
|
'description' => 'Primary Key: Unique revision ID.',
|
48
|
),
|
49
|
'item_id' => array(
|
50
|
'type' => 'int',
|
51
|
'not null' => TRUE,
|
52
|
'description' => 'Field collection item ID.',
|
53
|
),
|
54
|
),
|
55
|
'primary key' => array('revision_id'),
|
56
|
'indexes' => array(
|
57
|
'item_id' => array('item_id'),
|
58
|
),
|
59
|
'foreign keys' => array(
|
60
|
'versioned_field_collection_item' => array(
|
61
|
'table' => 'field_collection_item',
|
62
|
'columns' => array('item_id' => 'item_id'),
|
63
|
),
|
64
|
),
|
65
|
);
|
66
|
return $schema;
|
67
|
}
|
68
|
|
69
|
/**
|
70
|
* Implements hook_field_schema().
|
71
|
*/
|
72
|
function field_collection_field_schema($field) {
|
73
|
$columns = array(
|
74
|
'value' => array(
|
75
|
'type' => 'int',
|
76
|
'not null' => FALSE,
|
77
|
'description' => 'The field collection item id.',
|
78
|
),
|
79
|
'revision_id' => array(
|
80
|
'type' => 'int',
|
81
|
'not null' => FALSE,
|
82
|
'description' => 'The field collection item revision id.',
|
83
|
),
|
84
|
);
|
85
|
return array(
|
86
|
'columns' => $columns,
|
87
|
'indexes' => array(
|
88
|
'value' => array('value'),
|
89
|
'revision_id' => array('revision_id'),
|
90
|
),
|
91
|
);
|
92
|
}
|
93
|
|
94
|
/**
|
95
|
* Update the administer field collection permission machine name.
|
96
|
*/
|
97
|
function field_collection_update_7000() {
|
98
|
db_update('role_permission')
|
99
|
->fields(array('permission' => 'administer field collections'))
|
100
|
->condition('permission', 'administer field-collections')
|
101
|
->execute();
|
102
|
}
|
103
|
|
104
|
/**
|
105
|
* Add revision support.
|
106
|
*/
|
107
|
function field_collection_update_7001() {
|
108
|
|
109
|
// Add revision_id column to field_collection_item table.
|
110
|
$revision_id_spec = array(
|
111
|
'type' => 'int',
|
112
|
'not null' => TRUE,
|
113
|
'description' => 'Default revision ID.',
|
114
|
// Set default to 0 temporarily.
|
115
|
'initial' => 0,
|
116
|
);
|
117
|
// Field may already exist due to bug in 7.x-1.0-beta5.
|
118
|
if (!db_field_exists('field_collection_item', 'revision_id')) {
|
119
|
db_add_field('field_collection_item', 'revision_id', $revision_id_spec);
|
120
|
}
|
121
|
|
122
|
// Initialize the revision_id to be the same as the item_id.
|
123
|
db_update('field_collection_item')
|
124
|
->expression('revision_id', 'item_id')
|
125
|
->execute();
|
126
|
|
127
|
// Add the archived column.
|
128
|
$archived_spec = array(
|
129
|
'description' => 'Boolean indicating whether the field collection item is archived.',
|
130
|
'type' => 'int',
|
131
|
'not null' => TRUE,
|
132
|
'default' => 0,
|
133
|
);
|
134
|
// Field may already exist due to bug in 7.x-1.0-beta5.
|
135
|
if (!db_field_exists('field_collection_item', 'archived')) {
|
136
|
db_add_field('field_collection_item', 'archived', $archived_spec);
|
137
|
}
|
138
|
|
139
|
// Create the new table. It is important to explicitly define the schema here
|
140
|
// rather than use the hook_schema definition: http://drupal.org/node/150220.
|
141
|
$schema['field_collection_item_revision'] = array(
|
142
|
'description' => 'Stores revision information about field collection items.',
|
143
|
'fields' => array(
|
144
|
'revision_id' => array(
|
145
|
'type' => 'serial',
|
146
|
'not null' => TRUE,
|
147
|
'description' => 'Primary Key: Unique revision ID.',
|
148
|
),
|
149
|
'item_id' => array(
|
150
|
'type' => 'int',
|
151
|
'not null' => TRUE,
|
152
|
'description' => 'Field collection item ID.',
|
153
|
),
|
154
|
),
|
155
|
'primary key' => array('revision_id'),
|
156
|
'indexes' => array(
|
157
|
'item_id' => array('item_id'),
|
158
|
),
|
159
|
'foreign keys' => array(
|
160
|
'versioned_field_collection_item' => array(
|
161
|
'table' => 'field_collection_item',
|
162
|
'columns' => array('item_id' => 'item_id'),
|
163
|
),
|
164
|
),
|
165
|
);
|
166
|
// Table may already exist due to bug in 7.x-1.0-beta5.
|
167
|
if (db_table_exists('field_collection_item_revision')) {
|
168
|
db_drop_table('field_collection_item_revision');
|
169
|
}
|
170
|
db_create_table('field_collection_item_revision', $schema['field_collection_item_revision']);
|
171
|
|
172
|
// Fill the new table with the correct data.
|
173
|
$items = db_select('field_collection_item', 'fci')
|
174
|
->fields('fci')
|
175
|
->execute();
|
176
|
foreach ($items as $item) {
|
177
|
// Update field_collection_item_revision table.
|
178
|
db_insert('field_collection_item_revision')
|
179
|
->fields(array(
|
180
|
'revision_id' => $item->item_id,
|
181
|
'item_id' => $item->item_id,
|
182
|
))
|
183
|
->execute();
|
184
|
}
|
185
|
|
186
|
// Update the field_collection_field_schema columns for all tables.
|
187
|
// Add a revision_id column.
|
188
|
$revision_id_spec['description'] = 'The field collection item revision id.';
|
189
|
// Because $value_column below can be null, so must $revision_id_column.
|
190
|
$revision_id_spec['not null'] = FALSE;
|
191
|
foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) {
|
192
|
$table_prefixes = array('field_data', 'field_revision');
|
193
|
foreach ($table_prefixes as $table_prefix) {
|
194
|
|
195
|
$table = sprintf('%s_%s', $table_prefix, $field_name);
|
196
|
$value_column = sprintf('%s_value', $field_name);
|
197
|
$revision_id_column = sprintf('%s_revision_id', $field_name);
|
198
|
|
199
|
// Field may already exist due to bug in 7.x-1.0-beta5.
|
200
|
if (!db_field_exists($table, $revision_id_column)) {
|
201
|
db_add_field($table, $revision_id_column, $revision_id_spec);
|
202
|
}
|
203
|
else {
|
204
|
db_change_field($table, $revision_id_column, $revision_id_column, $revision_id_spec);
|
205
|
}
|
206
|
|
207
|
// Initialize the revision_id to be the same as the item_id.
|
208
|
db_update($table)
|
209
|
->expression($revision_id_column, $value_column)
|
210
|
->execute();
|
211
|
}
|
212
|
}
|
213
|
|
214
|
// Need to get the system up-to-date so drupal_schema_fields_sql() will work.
|
215
|
$schema = drupal_get_schema('field_collection_item_revision', TRUE);
|
216
|
}
|
217
|
|
218
|
/**
|
219
|
* Remove orphaned field collection item entities.
|
220
|
*/
|
221
|
function field_collection_update_7002() {
|
222
|
// Loop over all fields and delete any orphaned field collection items.
|
223
|
foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) {
|
224
|
|
225
|
$select = db_select('field_collection_item', 'fci')
|
226
|
->fields('fci', array('item_id'))
|
227
|
->condition('field_name', $field_name)
|
228
|
->condition('archived', 0);
|
229
|
$select->leftJoin('field_data_' . $field_name, 'field', "field.{$field_name}_value = fci.item_id ");
|
230
|
$select->isNull('field.entity_id');
|
231
|
$ids = $select->execute()->fetchCol(0);
|
232
|
|
233
|
entity_delete_multiple('field_collection_item', $ids);
|
234
|
drupal_set_message(t('Deleted @count orphaned field collection items.', array('@count' => count($ids))));
|
235
|
}
|
236
|
}
|
237
|
|
238
|
/**
|
239
|
* Update field_collection_field_schema columns for all tables.
|
240
|
*/
|
241
|
function field_collection_update_7003() {
|
242
|
// Revision_id column.
|
243
|
$revision_id_spec = array(
|
244
|
'type' => 'int',
|
245
|
'not null' => FALSE,
|
246
|
'description' => 'The field collection item revision id.',
|
247
|
'initial' => 0,
|
248
|
);
|
249
|
|
250
|
// Update the field_collection_field_schema columns for all tables,
|
251
|
// in case the buggy beta5 version of field_collection_update_7001()
|
252
|
// completed without complaint.
|
253
|
foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) {
|
254
|
$table_prefixes = array('field_data', 'field_revision');
|
255
|
foreach ($table_prefixes as $table_prefix) {
|
256
|
$table = sprintf('%s_%s', $table_prefix, $field_name);
|
257
|
$value_column = sprintf('%s_value', $field_name);
|
258
|
$revision_id_column = sprintf('%s_revision_id', $field_name);
|
259
|
db_change_field($table, $revision_id_column, $revision_id_column, $revision_id_spec);
|
260
|
}
|
261
|
}
|
262
|
|
263
|
// Need to get the system up-to-date so drupal_schema_fields_sql() will work.
|
264
|
$schema = drupal_get_schema('field_collection_item_revision', TRUE);
|
265
|
}
|
266
|
|
267
|
/**
|
268
|
* Add index on {$field_collection_field}_revision_id column for all tables.
|
269
|
*/
|
270
|
function field_collection_update_7004() {
|
271
|
// Update the field_collection_field_schema columns for all tables.
|
272
|
foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) {
|
273
|
$table_prefixes = array('field_data', 'field_revision');
|
274
|
foreach ($table_prefixes as $table_prefix) {
|
275
|
|
276
|
$table = sprintf('%s_%s', $table_prefix, $field_name);
|
277
|
$revision_id_column = sprintf('%s_revision_id', $field_name);
|
278
|
|
279
|
// Add index on revision_id column.
|
280
|
if (!db_index_exists($table, $revision_id_column)) {
|
281
|
db_add_index($table, $revision_id_column, array($revision_id_column));
|
282
|
}
|
283
|
}
|
284
|
}
|
285
|
}
|
286
|
|
287
|
/**
|
288
|
* Force the creation of the table cache_entity_field_collection_item.
|
289
|
*
|
290
|
* entity_update_7003 will attempt to install entitycache tables for existing
|
291
|
* modules, but it uses module_list() to get the list of available modules,
|
292
|
* which, when called from a database update, may not return field_collection
|
293
|
* since drupal is bootstrapped at a lower level.
|
294
|
*/
|
295
|
function field_collection_update_7005() {
|
296
|
if (module_exists('entitycache')) {
|
297
|
$entity_type = 'field_collection_item';
|
298
|
$table = 'cache_entity_' . $entity_type;
|
299
|
if (!db_table_exists($table)) {
|
300
|
$schema = drupal_get_schema_unprocessed('system', 'cache');
|
301
|
$schema['description'] = 'Cache table used to store' . $entity_type . ' entity records.';
|
302
|
db_create_table($table, $schema);
|
303
|
}
|
304
|
}
|
305
|
}
|
306
|
|
307
|
/**
|
308
|
* Ensures revision_id indexes are present at field_config table.
|
309
|
*/
|
310
|
function field_collection_update_7006() {
|
311
|
$result = db_query("SELECT id, field_name, data FROM {field_config} WHERE type = 'field_collection'");
|
312
|
foreach ($result as $field_config) {
|
313
|
$data = unserialize($field_config->data);
|
314
|
// Skip this record if the revision_id index is already present.
|
315
|
if (isset($data['indexes']['revision_id'])) {
|
316
|
continue;
|
317
|
}
|
318
|
// Otherwise, add the revision_id index and update the record.
|
319
|
$data['indexes']['revision_id'] = array('revision_id');
|
320
|
$data = serialize($data);
|
321
|
$num_updated = db_update('field_config')
|
322
|
->fields(array('data' => $data))
|
323
|
->condition('id', $field_config->id)
|
324
|
->execute();
|
325
|
// If for some reason the update failed, throw an exception.
|
326
|
if ($num_updated != 1) {
|
327
|
$t_args['@field'] = $field_config->field_name;
|
328
|
throw new DrupalUpdateException(t('An error was detected when attempting to update field configuration for field @field.', $t_args));
|
329
|
}
|
330
|
}
|
331
|
}
|
332
|
|
333
|
/**
|
334
|
* Add index on {$field_collection_field}_value column for all tables.
|
335
|
*/
|
336
|
function field_collection_update_7007() {
|
337
|
foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) {
|
338
|
if (!isset($field['indexes']['value'])) {
|
339
|
// Add index on the value column and update the field.
|
340
|
$field['indexes']['value'] = array('value');
|
341
|
field_update_field($field);
|
342
|
}
|
343
|
|
344
|
$table_prefixes = array('field_data', 'field_revision');
|
345
|
foreach ($table_prefixes as $table_prefix) {
|
346
|
$table = "{$table_prefix}_{$field_name}";
|
347
|
$value_column = "{$field_name}_value";
|
348
|
if (!db_index_exists($table, $value_column)) {
|
349
|
// Add index on the value column.
|
350
|
db_add_index($table, $value_column, array($value_column));
|
351
|
}
|
352
|
}
|
353
|
}
|
354
|
}
|
355
|
|
356
|
/**
|
357
|
* Update fields in field collections already set to use Entity Translation.
|
358
|
*/
|
359
|
function field_collection_update_7008() {
|
360
|
// Include FieldCollectionItemEntity class.
|
361
|
module_load_include('inc', 'field_collection', 'field_collection.entity');
|
362
|
|
363
|
$results = array();
|
364
|
foreach (field_info_fields() as $f_name => $field) {
|
365
|
if ($field['translatable'] == 1 && isset($field['bundles']['field_collection_item'])) {
|
366
|
$query = new EntityFieldQuery();
|
367
|
$query->entityCondition('entity_type', 'field_collection_item')
|
368
|
->fieldLanguageCondition($f_name, LANGUAGE_NONE);
|
369
|
$query_result = $query->execute();
|
370
|
if (isset($query_result['field_collection_item'])) {
|
371
|
$results = $results + $query_result['field_collection_item'];
|
372
|
}
|
373
|
}
|
374
|
}
|
375
|
if (count($results)) {
|
376
|
$orphans = array();
|
377
|
$ids = array_keys($results);
|
378
|
$field_collection_items = entity_load('field_collection_item', $ids);
|
379
|
foreach ($field_collection_items as $item) {
|
380
|
/** @var FieldCollectionItemEntity $item */
|
381
|
if ($item->hostEntity()) {
|
382
|
$item->copyTranslations(LANGUAGE_NONE);
|
383
|
$item->save(TRUE);
|
384
|
}
|
385
|
else {
|
386
|
$orphans[] = $item->identifier();
|
387
|
}
|
388
|
}
|
389
|
if ($orphans) {
|
390
|
$count = count($orphans);
|
391
|
entity_delete_multiple('field_collection_item', $orphans);
|
392
|
drupal_set_message("Deleted $count orphaned field collection items.");
|
393
|
}
|
394
|
}
|
395
|
}
|