1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Install, update and uninstall functions for the node module.
|
6
|
*/
|
7
|
|
8
|
/**
|
9
|
* Implements hook_schema().
|
10
|
*/
|
11
|
function node_schema() {
|
12
|
$schema['node'] = array(
|
13
|
'description' => 'The base table for nodes.',
|
14
|
'fields' => array(
|
15
|
'nid' => array(
|
16
|
'description' => 'The primary identifier for a node.',
|
17
|
'type' => 'serial',
|
18
|
'unsigned' => TRUE,
|
19
|
'not null' => TRUE,
|
20
|
),
|
21
|
// Defaults to NULL in order to avoid a brief period of potential
|
22
|
// deadlocks on the index.
|
23
|
'vid' => array(
|
24
|
'description' => 'The current {node_revision}.vid version identifier.',
|
25
|
'type' => 'int',
|
26
|
'unsigned' => TRUE,
|
27
|
'not null' => FALSE,
|
28
|
'default' => NULL,
|
29
|
),
|
30
|
'type' => array(
|
31
|
'description' => 'The {node_type}.type of this node.',
|
32
|
'type' => 'varchar',
|
33
|
'length' => 32,
|
34
|
'not null' => TRUE,
|
35
|
'default' => '',
|
36
|
),
|
37
|
'language' => array(
|
38
|
'description' => 'The {languages}.language of this node.',
|
39
|
'type' => 'varchar',
|
40
|
'length' => 12,
|
41
|
'not null' => TRUE,
|
42
|
'default' => '',
|
43
|
),
|
44
|
'title' => array(
|
45
|
'description' => 'The title of this node, always treated as non-markup plain text.',
|
46
|
'type' => 'varchar',
|
47
|
'length' => 255,
|
48
|
'not null' => TRUE,
|
49
|
'default' => '',
|
50
|
),
|
51
|
'uid' => array(
|
52
|
'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
|
53
|
'type' => 'int',
|
54
|
'not null' => TRUE,
|
55
|
'default' => 0,
|
56
|
),
|
57
|
'status' => array(
|
58
|
'description' => 'Boolean indicating whether the node is published (visible to non-administrators).',
|
59
|
'type' => 'int',
|
60
|
'not null' => TRUE,
|
61
|
'default' => 1,
|
62
|
),
|
63
|
'created' => array(
|
64
|
'description' => 'The Unix timestamp when the node was created.',
|
65
|
'type' => 'int',
|
66
|
'not null' => TRUE,
|
67
|
'default' => 0,
|
68
|
),
|
69
|
'changed' => array(
|
70
|
'description' => 'The Unix timestamp when the node was most recently saved.',
|
71
|
'type' => 'int',
|
72
|
'not null' => TRUE,
|
73
|
'default' => 0,
|
74
|
),
|
75
|
'comment' => array(
|
76
|
'description' => 'Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).',
|
77
|
'type' => 'int',
|
78
|
'not null' => TRUE,
|
79
|
'default' => 0,
|
80
|
),
|
81
|
'promote' => array(
|
82
|
'description' => 'Boolean indicating whether the node should be displayed on the front page.',
|
83
|
'type' => 'int',
|
84
|
'not null' => TRUE,
|
85
|
'default' => 0,
|
86
|
),
|
87
|
'sticky' => array(
|
88
|
'description' => 'Boolean indicating whether the node should be displayed at the top of lists in which it appears.',
|
89
|
'type' => 'int',
|
90
|
'not null' => TRUE,
|
91
|
'default' => 0,
|
92
|
),
|
93
|
'tnid' => array(
|
94
|
'description' => 'The translation set id for this node, which equals the node id of the source post in each set.',
|
95
|
'type' => 'int',
|
96
|
'unsigned' => TRUE,
|
97
|
'not null' => TRUE,
|
98
|
'default' => 0,
|
99
|
),
|
100
|
'translate' => array(
|
101
|
'description' => 'A boolean indicating whether this translation page needs to be updated.',
|
102
|
'type' => 'int',
|
103
|
'not null' => TRUE,
|
104
|
'default' => 0,
|
105
|
),
|
106
|
),
|
107
|
'indexes' => array(
|
108
|
'node_changed' => array('changed'),
|
109
|
'node_created' => array('created'),
|
110
|
'node_frontpage' => array('promote', 'status', 'sticky', 'created'),
|
111
|
'node_status_type' => array('status', 'type', 'nid'),
|
112
|
'node_title_type' => array('title', array('type', 4)),
|
113
|
'node_type' => array(array('type', 4)),
|
114
|
'uid' => array('uid'),
|
115
|
'tnid' => array('tnid'),
|
116
|
'translate' => array('translate'),
|
117
|
'language' => array('language'),
|
118
|
),
|
119
|
'unique keys' => array(
|
120
|
'vid' => array('vid'),
|
121
|
),
|
122
|
'foreign keys' => array(
|
123
|
'node_revision' => array(
|
124
|
'table' => 'node_revision',
|
125
|
'columns' => array('vid' => 'vid'),
|
126
|
),
|
127
|
'node_author' => array(
|
128
|
'table' => 'users',
|
129
|
'columns' => array('uid' => 'uid'),
|
130
|
),
|
131
|
),
|
132
|
'primary key' => array('nid'),
|
133
|
);
|
134
|
|
135
|
$schema['node_access'] = array(
|
136
|
'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
|
137
|
'fields' => array(
|
138
|
'nid' => array(
|
139
|
'description' => 'The {node}.nid this record affects.',
|
140
|
'type' => 'int',
|
141
|
'unsigned' => TRUE,
|
142
|
'not null' => TRUE,
|
143
|
'default' => 0,
|
144
|
),
|
145
|
'gid' => array(
|
146
|
'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
|
147
|
'type' => 'int',
|
148
|
'unsigned' => TRUE,
|
149
|
'not null' => TRUE,
|
150
|
'default' => 0,
|
151
|
),
|
152
|
'realm' => array(
|
153
|
'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
|
154
|
'type' => 'varchar',
|
155
|
'length' => 255,
|
156
|
'not null' => TRUE,
|
157
|
'default' => '',
|
158
|
),
|
159
|
'grant_view' => array(
|
160
|
'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
|
161
|
'type' => 'int',
|
162
|
'unsigned' => TRUE,
|
163
|
'not null' => TRUE,
|
164
|
'default' => 0,
|
165
|
'size' => 'tiny',
|
166
|
),
|
167
|
'grant_update' => array(
|
168
|
'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
|
169
|
'type' => 'int',
|
170
|
'unsigned' => TRUE,
|
171
|
'not null' => TRUE,
|
172
|
'default' => 0,
|
173
|
'size' => 'tiny',
|
174
|
),
|
175
|
'grant_delete' => array(
|
176
|
'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
|
177
|
'type' => 'int',
|
178
|
'unsigned' => TRUE,
|
179
|
'not null' => TRUE,
|
180
|
'default' => 0,
|
181
|
'size' => 'tiny',
|
182
|
),
|
183
|
),
|
184
|
'primary key' => array('nid', 'gid', 'realm'),
|
185
|
'foreign keys' => array(
|
186
|
'affected_node' => array(
|
187
|
'table' => 'node',
|
188
|
'columns' => array('nid' => 'nid'),
|
189
|
),
|
190
|
),
|
191
|
);
|
192
|
|
193
|
$schema['node_revision'] = array(
|
194
|
'description' => 'Stores information about each saved version of a {node}.',
|
195
|
'fields' => array(
|
196
|
'nid' => array(
|
197
|
'description' => 'The {node} this version belongs to.',
|
198
|
'type' => 'int',
|
199
|
'unsigned' => TRUE,
|
200
|
'not null' => TRUE,
|
201
|
'default' => 0,
|
202
|
),
|
203
|
'vid' => array(
|
204
|
'description' => 'The primary identifier for this version.',
|
205
|
'type' => 'serial',
|
206
|
'unsigned' => TRUE,
|
207
|
'not null' => TRUE,
|
208
|
),
|
209
|
'uid' => array(
|
210
|
'description' => 'The {users}.uid that created this version.',
|
211
|
'type' => 'int',
|
212
|
'not null' => TRUE,
|
213
|
'default' => 0,
|
214
|
),
|
215
|
'title' => array(
|
216
|
'description' => 'The title of this version.',
|
217
|
'type' => 'varchar',
|
218
|
'length' => 255,
|
219
|
'not null' => TRUE,
|
220
|
'default' => '',
|
221
|
),
|
222
|
'log' => array(
|
223
|
'description' => 'The log entry explaining the changes in this version.',
|
224
|
'type' => 'text',
|
225
|
'not null' => TRUE,
|
226
|
'size' => 'big',
|
227
|
),
|
228
|
'timestamp' => array(
|
229
|
'description' => 'A Unix timestamp indicating when this version was created.',
|
230
|
'type' => 'int',
|
231
|
'not null' => TRUE,
|
232
|
'default' => 0,
|
233
|
),
|
234
|
'status' => array(
|
235
|
'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).',
|
236
|
'type' => 'int',
|
237
|
'not null' => TRUE,
|
238
|
'default' => 1,
|
239
|
),
|
240
|
'comment' => array(
|
241
|
'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).',
|
242
|
'type' => 'int',
|
243
|
'not null' => TRUE,
|
244
|
'default' => 0,
|
245
|
),
|
246
|
'promote' => array(
|
247
|
'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.',
|
248
|
'type' => 'int',
|
249
|
'not null' => TRUE,
|
250
|
'default' => 0,
|
251
|
),
|
252
|
'sticky' => array(
|
253
|
'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.',
|
254
|
'type' => 'int',
|
255
|
'not null' => TRUE,
|
256
|
'default' => 0,
|
257
|
),
|
258
|
),
|
259
|
'indexes' => array(
|
260
|
'nid' => array('nid'),
|
261
|
'uid' => array('uid'),
|
262
|
),
|
263
|
'primary key' => array('vid'),
|
264
|
'foreign keys' => array(
|
265
|
'versioned_node' => array(
|
266
|
'table' => 'node',
|
267
|
'columns' => array('nid' => 'nid'),
|
268
|
),
|
269
|
'version_author' => array(
|
270
|
'table' => 'users',
|
271
|
'columns' => array('uid' => 'uid'),
|
272
|
),
|
273
|
),
|
274
|
);
|
275
|
|
276
|
$schema['node_type'] = array(
|
277
|
'description' => 'Stores information about all defined {node} types.',
|
278
|
'fields' => array(
|
279
|
'type' => array(
|
280
|
'description' => 'The machine-readable name of this type.',
|
281
|
'type' => 'varchar',
|
282
|
'length' => 32,
|
283
|
'not null' => TRUE,
|
284
|
),
|
285
|
'name' => array(
|
286
|
'description' => 'The human-readable name of this type.',
|
287
|
'type' => 'varchar',
|
288
|
'length' => 255,
|
289
|
'not null' => TRUE,
|
290
|
'default' => '',
|
291
|
'translatable' => TRUE,
|
292
|
),
|
293
|
'base' => array(
|
294
|
'description' => 'The base string used to construct callbacks corresponding to this node type.',
|
295
|
'type' => 'varchar',
|
296
|
'length' => 255,
|
297
|
'not null' => TRUE,
|
298
|
),
|
299
|
'module' => array(
|
300
|
'description' => 'The module defining this node type.',
|
301
|
'type' => 'varchar',
|
302
|
'length' => 255,
|
303
|
'not null' => TRUE,
|
304
|
),
|
305
|
'description' => array(
|
306
|
'description' => 'A brief description of this type.',
|
307
|
'type' => 'text',
|
308
|
'not null' => TRUE,
|
309
|
'size' => 'medium',
|
310
|
'translatable' => TRUE,
|
311
|
),
|
312
|
'help' => array(
|
313
|
'description' => 'Help information shown to the user when creating a {node} of this type.',
|
314
|
'type' => 'text',
|
315
|
'not null' => TRUE,
|
316
|
'size' => 'medium',
|
317
|
'translatable' => TRUE,
|
318
|
),
|
319
|
'has_title' => array(
|
320
|
'description' => 'Boolean indicating whether this type uses the {node}.title field.',
|
321
|
'type' => 'int',
|
322
|
'unsigned' => TRUE,
|
323
|
'not null' => TRUE,
|
324
|
'size' => 'tiny',
|
325
|
),
|
326
|
'title_label' => array(
|
327
|
'description' => 'The label displayed for the title field on the edit form.',
|
328
|
'type' => 'varchar',
|
329
|
'length' => 255,
|
330
|
'not null' => TRUE,
|
331
|
'default' => '',
|
332
|
'translatable' => TRUE,
|
333
|
),
|
334
|
'custom' => array(
|
335
|
'description' => 'A boolean indicating whether this type is defined by a module (FALSE) or by a user via Add content type (TRUE).',
|
336
|
'type' => 'int',
|
337
|
'not null' => TRUE,
|
338
|
'default' => 0,
|
339
|
'size' => 'tiny',
|
340
|
),
|
341
|
'modified' => array(
|
342
|
'description' => 'A boolean indicating whether this type has been modified by an administrator; currently not used in any way.',
|
343
|
'type' => 'int',
|
344
|
'not null' => TRUE,
|
345
|
'default' => 0,
|
346
|
'size' => 'tiny',
|
347
|
),
|
348
|
'locked' => array(
|
349
|
'description' => 'A boolean indicating whether the administrator can change the machine name of this type.',
|
350
|
'type' => 'int',
|
351
|
'not null' => TRUE,
|
352
|
'default' => 0,
|
353
|
'size' => 'tiny',
|
354
|
),
|
355
|
'disabled' => array(
|
356
|
'description' => 'A boolean indicating whether the node type is disabled.',
|
357
|
'type' => 'int',
|
358
|
'not null' => TRUE,
|
359
|
'default' => 0,
|
360
|
'size' => 'tiny'
|
361
|
),
|
362
|
'orig_type' => array(
|
363
|
'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.',
|
364
|
'type' => 'varchar',
|
365
|
'length' => 255,
|
366
|
'not null' => TRUE,
|
367
|
'default' => '',
|
368
|
),
|
369
|
),
|
370
|
'primary key' => array('type'),
|
371
|
);
|
372
|
|
373
|
$schema['block_node_type'] = array(
|
374
|
'description' => 'Sets up display criteria for blocks based on content types',
|
375
|
'fields' => array(
|
376
|
'module' => array(
|
377
|
'type' => 'varchar',
|
378
|
'length' => 64,
|
379
|
'not null' => TRUE,
|
380
|
'description' => "The block's origin module, from {block}.module.",
|
381
|
),
|
382
|
'delta' => array(
|
383
|
'type' => 'varchar',
|
384
|
'length' => 32,
|
385
|
'not null' => TRUE,
|
386
|
'description' => "The block's unique delta within module, from {block}.delta.",
|
387
|
),
|
388
|
'type' => array(
|
389
|
'type' => 'varchar',
|
390
|
'length' => 32,
|
391
|
'not null' => TRUE,
|
392
|
'description' => "The machine-readable name of this type from {node_type}.type.",
|
393
|
),
|
394
|
),
|
395
|
'primary key' => array('module', 'delta', 'type'),
|
396
|
'indexes' => array(
|
397
|
'type' => array('type'),
|
398
|
),
|
399
|
);
|
400
|
|
401
|
$schema['history'] = array(
|
402
|
'description' => 'A record of which {users} have read which {node}s.',
|
403
|
'fields' => array(
|
404
|
'uid' => array(
|
405
|
'description' => 'The {users}.uid that read the {node} nid.',
|
406
|
'type' => 'int',
|
407
|
'not null' => TRUE,
|
408
|
'default' => 0,
|
409
|
),
|
410
|
'nid' => array(
|
411
|
'description' => 'The {node}.nid that was read.',
|
412
|
'type' => 'int',
|
413
|
'unsigned' => TRUE,
|
414
|
'not null' => TRUE,
|
415
|
'default' => 0,
|
416
|
),
|
417
|
'timestamp' => array(
|
418
|
'description' => 'The Unix timestamp at which the read occurred.',
|
419
|
'type' => 'int',
|
420
|
'not null' => TRUE,
|
421
|
'default' => 0,
|
422
|
),
|
423
|
),
|
424
|
'primary key' => array('uid', 'nid'),
|
425
|
'indexes' => array(
|
426
|
'nid' => array('nid'),
|
427
|
),
|
428
|
);
|
429
|
|
430
|
return $schema;
|
431
|
}
|
432
|
|
433
|
/**
|
434
|
* Implements hook_install().
|
435
|
*/
|
436
|
function node_install() {
|
437
|
// Populate the node access table.
|
438
|
db_insert('node_access')
|
439
|
->fields(array(
|
440
|
'nid' => 0,
|
441
|
'gid' => 0,
|
442
|
'realm' => 'all',
|
443
|
'grant_view' => 1,
|
444
|
'grant_update' => 0,
|
445
|
'grant_delete' => 0,
|
446
|
))
|
447
|
->execute();
|
448
|
}
|
449
|
|
450
|
/**
|
451
|
* Implements hook_update_dependencies().
|
452
|
*/
|
453
|
function node_update_dependencies() {
|
454
|
// node_update_7006() migrates node data to fields and therefore must run
|
455
|
// after all Field modules have been enabled, which happens in
|
456
|
// system_update_7027(). It also needs to query the {filter_format} table to
|
457
|
// get a list of existing text formats, so it must run after
|
458
|
// filter_update_7000(), which creates that table.
|
459
|
$dependencies['node'][7006] = array(
|
460
|
'system' => 7027,
|
461
|
'filter' => 7000,
|
462
|
);
|
463
|
|
464
|
// node_update_7008() migrates role permissions and therefore must run after
|
465
|
// the {role} and {role_permission} tables are properly set up, which happens
|
466
|
// in user_update_7007().
|
467
|
$dependencies['node'][7008] = array(
|
468
|
'user' => 7007,
|
469
|
);
|
470
|
|
471
|
return $dependencies;
|
472
|
}
|
473
|
|
474
|
/**
|
475
|
* Utility function: fetch the node types directly from the database.
|
476
|
*
|
477
|
* This function is valid for a database schema version 7000.
|
478
|
*
|
479
|
* @ingroup update_api
|
480
|
*/
|
481
|
function _update_7000_node_get_types() {
|
482
|
$node_types = db_query('SELECT * FROM {node_type}')->fetchAllAssoc('type', PDO::FETCH_OBJ);
|
483
|
|
484
|
// Create default settings for orphan nodes.
|
485
|
$all_types = db_query('SELECT DISTINCT type FROM {node}')->fetchCol();
|
486
|
$extra_types = array_diff($all_types, array_keys($node_types));
|
487
|
|
488
|
foreach ($extra_types as $type) {
|
489
|
$type_object = new stdClass();
|
490
|
$type_object->type = $type;
|
491
|
|
492
|
// In Drupal 6, whether you have a body field or not is a flag in the node
|
493
|
// type table. If it's enabled, nodes may or may not have an empty string
|
494
|
// for the bodies. As we can't detect what this setting should be in
|
495
|
// Drupal 7 without access to the Drupal 6 node type settings, we assume
|
496
|
// the default, which is to enable the body field.
|
497
|
$type_object->has_body = 1;
|
498
|
$type_object->body_label = 'Body';
|
499
|
$node_types[$type_object->type] = $type_object;
|
500
|
}
|
501
|
return $node_types;
|
502
|
}
|
503
|
|
504
|
/**
|
505
|
* @addtogroup updates-6.x-to-7.x
|
506
|
* @{
|
507
|
*/
|
508
|
|
509
|
/**
|
510
|
* Upgrade the node type table and fix node type 'module' attribute to avoid name-space conflicts.
|
511
|
*/
|
512
|
function node_update_7000() {
|
513
|
// Rename the module column to base.
|
514
|
db_change_field('node_type', 'module', 'base', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE));
|
515
|
|
516
|
db_add_field('node_type', 'module', array(
|
517
|
'description' => 'The module defining this node type.',
|
518
|
'type' => 'varchar',
|
519
|
'default' => '',
|
520
|
'length' => 255,
|
521
|
'not null' => TRUE,
|
522
|
));
|
523
|
|
524
|
db_add_field('node_type', 'disabled', array(
|
525
|
'description' => 'A boolean indicating whether the node type is disabled.',
|
526
|
'type' => 'int',
|
527
|
'not null' => TRUE,
|
528
|
'default' => 0,
|
529
|
'size' => 'tiny'
|
530
|
));
|
531
|
|
532
|
$modules = db_select('system', 's')
|
533
|
->fields('s', array('name'))
|
534
|
->condition('type', 'module');
|
535
|
db_update('node_type')
|
536
|
->expression('module', 'base')
|
537
|
->condition('base', $modules, 'IN')
|
538
|
->execute();
|
539
|
|
540
|
db_update('node_type')
|
541
|
->fields(array('base' => 'node_content'))
|
542
|
->condition('base', 'node')
|
543
|
->execute();
|
544
|
}
|
545
|
|
546
|
/**
|
547
|
* Rename {node_revisions} table to {node_revision}.
|
548
|
*/
|
549
|
function node_update_7001() {
|
550
|
db_rename_table('node_revisions', 'node_revision');
|
551
|
}
|
552
|
|
553
|
/**
|
554
|
* Extend the node_promote_status index to include all fields required for the node page query.
|
555
|
*/
|
556
|
function node_update_7002() {
|
557
|
db_drop_index('node', 'node_promote_status');
|
558
|
db_add_index('node', 'node_frontpage', array('promote', 'status', 'sticky', 'created'));
|
559
|
}
|
560
|
|
561
|
/**
|
562
|
* Remove the node_counter if the statistics module is uninstalled.
|
563
|
*/
|
564
|
function node_update_7003() {
|
565
|
if (drupal_get_installed_schema_version('statistics') == SCHEMA_UNINSTALLED) {
|
566
|
db_drop_table('node_counter');
|
567
|
}
|
568
|
}
|
569
|
|
570
|
/**
|
571
|
* Extend the existing default preview and teaser settings to all node types.
|
572
|
*/
|
573
|
function node_update_7004() {
|
574
|
// Get original settings and all types.
|
575
|
$original_length = variable_get('teaser_length', 600);
|
576
|
$original_preview = variable_get('node_preview', 0);
|
577
|
|
578
|
// Map old preview setting to new values order.
|
579
|
$original_preview ? $original_preview = 2 : $original_preview = 1;
|
580
|
node_type_cache_reset();
|
581
|
|
582
|
// Apply original settings to all types.
|
583
|
foreach (_update_7000_node_get_types() as $type => $type_object) {
|
584
|
variable_set('teaser_length_' . $type, $original_length);
|
585
|
variable_set('node_preview_' . $type, $original_preview);
|
586
|
}
|
587
|
// Delete old variable but leave 'teaser_length' for aggregator module upgrade.
|
588
|
variable_del('node_preview');
|
589
|
}
|
590
|
|
591
|
/**
|
592
|
* Add status/comment/promote and sticky columns to the {node_revision} table.
|
593
|
*/
|
594
|
function node_update_7005() {
|
595
|
foreach (array('status', 'comment', 'promote', 'sticky') as $column) {
|
596
|
db_add_field('node_revision', $column, array(
|
597
|
'type' => 'int',
|
598
|
'not null' => TRUE,
|
599
|
'default' => 0,
|
600
|
));
|
601
|
}
|
602
|
}
|
603
|
|
604
|
/**
|
605
|
* Convert body and teaser from node properties to fields, and migrate status/comment/promote and sticky columns to the {node_revision} table.
|
606
|
*/
|
607
|
function node_update_7006(&$sandbox) {
|
608
|
$sandbox['#finished'] = 0;
|
609
|
|
610
|
// Get node type info for every invocation.
|
611
|
node_type_cache_reset();
|
612
|
|
613
|
if (!isset($sandbox['total'])) {
|
614
|
// Initial invocation.
|
615
|
|
616
|
// First, create the body field.
|
617
|
$body_field = array(
|
618
|
'field_name' => 'body',
|
619
|
'type' => 'text_with_summary',
|
620
|
'module' => 'text',
|
621
|
'cardinality' => 1,
|
622
|
'entity_types' => array('node'),
|
623
|
'translatable' => TRUE,
|
624
|
);
|
625
|
_update_7000_field_create_field($body_field);
|
626
|
|
627
|
$default_trim_length = variable_get('teaser_length', 600);
|
628
|
|
629
|
// Get node type info, specifically the body field settings.
|
630
|
$node_types = _update_7000_node_get_types();
|
631
|
|
632
|
// Add body field instances for existing node types.
|
633
|
foreach ($node_types as $node_type) {
|
634
|
if ($node_type->has_body) {
|
635
|
$trim_length = variable_get('teaser_length_' . $node_type->type, $default_trim_length);
|
636
|
|
637
|
$instance = array(
|
638
|
'entity_type' => 'node',
|
639
|
'bundle' => $node_type->type,
|
640
|
'label' => $node_type->body_label,
|
641
|
'description' => isset($node_type->description) ? $node_type->description : '',
|
642
|
'required' => (isset($node_type->min_word_count) && $node_type->min_word_count > 0) ? 1 : 0,
|
643
|
'widget' => array(
|
644
|
'type' => 'text_textarea_with_summary',
|
645
|
'settings' => array(
|
646
|
'rows' => 20,
|
647
|
'summary_rows' => 5,
|
648
|
),
|
649
|
'weight' => -4,
|
650
|
'module' => 'text',
|
651
|
),
|
652
|
'settings' => array('display_summary' => TRUE),
|
653
|
'display' => array(
|
654
|
'default' => array(
|
655
|
'label' => 'hidden',
|
656
|
'type' => 'text_default',
|
657
|
),
|
658
|
'teaser' => array(
|
659
|
'label' => 'hidden',
|
660
|
'type' => 'text_summary_or_trimmed',
|
661
|
'trim_length' => $trim_length,
|
662
|
),
|
663
|
),
|
664
|
);
|
665
|
_update_7000_field_create_instance($body_field, $instance);
|
666
|
variable_del('teaser_length_' . $node_type->type);
|
667
|
}
|
668
|
// Leave 'teaser_length' variable for aggregator module upgrade.
|
669
|
|
670
|
$sandbox['node_types_info'][$node_type->type] = array(
|
671
|
'has_body' => $node_type->has_body,
|
672
|
);
|
673
|
}
|
674
|
|
675
|
// Used below when updating the stored text format of each node body.
|
676
|
$sandbox['existing_text_formats'] = db_query("SELECT format FROM {filter_format}")->fetchCol();
|
677
|
|
678
|
// Initialize state for future calls.
|
679
|
$sandbox['last'] = 0;
|
680
|
$sandbox['count'] = 0;
|
681
|
|
682
|
$query = db_select('node', 'n');
|
683
|
$query->join('node_revision', 'nr', 'n.nid = nr.nid');
|
684
|
$sandbox['total'] = $query->countQuery()->execute()->fetchField();
|
685
|
|
686
|
$sandbox['body_field_id'] = $body_field['id'];
|
687
|
}
|
688
|
else {
|
689
|
// Subsequent invocations.
|
690
|
|
691
|
$found = FALSE;
|
692
|
if ($sandbox['total']) {
|
693
|
// Operate on every revision of every node (whee!), in batches.
|
694
|
$batch_size = 200;
|
695
|
$query = db_select('node_revision', 'nr');
|
696
|
$query->innerJoin('node', 'n', 'n.nid = nr.nid');
|
697
|
$query
|
698
|
->fields('nr', array('nid', 'vid', 'body', 'teaser', 'format'))
|
699
|
->fields('n', array('type', 'status', 'comment', 'promote', 'sticky', 'language'))
|
700
|
->condition('nr.vid', $sandbox['last'], '>')
|
701
|
->orderBy('nr.vid', 'ASC')
|
702
|
->range(0, $batch_size);
|
703
|
$revisions = $query->execute();
|
704
|
|
705
|
// Load each revision of each node, set up 'body'
|
706
|
// appropriately, and save the node's field data. Note that
|
707
|
// node_load() will not return the body or teaser values from
|
708
|
// {node_revision} because those columns have been removed from the
|
709
|
// schema structure in memory (but not yet from the database),
|
710
|
// so we get the values from the explicit query of the table
|
711
|
// instead.
|
712
|
foreach ($revisions as $revision) {
|
713
|
$found = TRUE;
|
714
|
|
715
|
if ($sandbox['node_types_info'][$revision->type]['has_body']) {
|
716
|
$node = (object) array(
|
717
|
'nid' => $revision->nid,
|
718
|
'vid' => $revision->vid,
|
719
|
'type' => $revision->type,
|
720
|
);
|
721
|
// After node_update_7009() we will always have LANGUAGE_NONE as
|
722
|
// language neutral language code, but here we still have empty
|
723
|
// strings.
|
724
|
$langcode = empty($revision->language) ? LANGUAGE_NONE : $revision->language;
|
725
|
if (!empty($revision->teaser) && $revision->teaser != text_summary($revision->body)) {
|
726
|
$node->body[$langcode][0]['summary'] = $revision->teaser;
|
727
|
}
|
728
|
// Do this after text_summary() above.
|
729
|
$break = '<!--break-->';
|
730
|
if (substr($revision->body, 0, strlen($break)) == $break) {
|
731
|
$revision->body = substr($revision->body, strlen($break));
|
732
|
}
|
733
|
$node->body[$langcode][0]['value'] = $revision->body;
|
734
|
// Update the revision's text format for the changes to the Drupal 7
|
735
|
// filter system. This uses the same kind of logic that occurs, for
|
736
|
// example, in user_update_7010(), but we do this here rather than
|
737
|
// via a separate set of database queries, since we are already
|
738
|
// migrating the data.
|
739
|
if (empty($revision->body) && empty($revision->format)) {
|
740
|
$node->body[$langcode][0]['format'] = NULL;
|
741
|
}
|
742
|
elseif (!in_array($revision->format, $sandbox['existing_text_formats'])) {
|
743
|
$node->body[$langcode][0]['format'] = variable_get('filter_default_format', 1);
|
744
|
}
|
745
|
else {
|
746
|
$node->body[$langcode][0]['format'] = $revision->format;
|
747
|
}
|
748
|
// This is a core update and no contrib modules are enabled yet, so
|
749
|
// we can assume default field storage for a faster update.
|
750
|
_update_7000_field_sql_storage_write('node', $node->type, $node->nid, $node->vid, 'body', $node->body);
|
751
|
}
|
752
|
|
753
|
// Migrate the status columns to the {node_revision} table.
|
754
|
db_update('node_revision')
|
755
|
->fields(array(
|
756
|
'status' => $revision->status,
|
757
|
'comment' => $revision->comment,
|
758
|
'promote' => $revision->promote,
|
759
|
'sticky' => $revision->sticky,
|
760
|
))
|
761
|
->condition('vid', $revision->vid)
|
762
|
->execute();
|
763
|
|
764
|
$sandbox['last'] = $revision->vid;
|
765
|
$sandbox['count'] += 1;
|
766
|
}
|
767
|
|
768
|
$sandbox['#finished'] = min(0.99, $sandbox['count'] / $sandbox['total']);
|
769
|
}
|
770
|
|
771
|
if (!$found) {
|
772
|
// All nodes are processed.
|
773
|
|
774
|
// Remove the now-obsolete body info from node_revision.
|
775
|
db_drop_field('node_revision', 'body');
|
776
|
db_drop_field('node_revision', 'teaser');
|
777
|
db_drop_field('node_revision', 'format');
|
778
|
|
779
|
// Remove node_type properties related to the former 'body'.
|
780
|
db_drop_field('node_type', 'has_body');
|
781
|
db_drop_field('node_type', 'body_label');
|
782
|
|
783
|
// We're done.
|
784
|
$sandbox['#finished'] = 1;
|
785
|
}
|
786
|
}
|
787
|
}
|
788
|
|
789
|
/**
|
790
|
* Remove column min_word_count.
|
791
|
*/
|
792
|
function node_update_7007() {
|
793
|
db_drop_field('node_type', 'min_word_count');
|
794
|
}
|
795
|
|
796
|
/**
|
797
|
* Split the 'administer nodes' permission from 'access content overview'.
|
798
|
*/
|
799
|
function node_update_7008() {
|
800
|
$roles = user_roles(FALSE, 'administer nodes');
|
801
|
foreach ($roles as $rid => $role) {
|
802
|
_update_7000_user_role_grant_permissions($rid, array('access content overview'), 'node');
|
803
|
}
|
804
|
}
|
805
|
|
806
|
/**
|
807
|
* Convert node languages from the empty string to LANGUAGE_NONE.
|
808
|
*/
|
809
|
function node_update_7009() {
|
810
|
db_update('node')
|
811
|
->fields(array('language' => LANGUAGE_NONE))
|
812
|
->condition('language', '')
|
813
|
->execute();
|
814
|
}
|
815
|
|
816
|
/**
|
817
|
* Add the {block_node_type} table.
|
818
|
*/
|
819
|
function node_update_7010() {
|
820
|
$schema['block_node_type'] = array(
|
821
|
'description' => 'Sets up display criteria for blocks based on content types',
|
822
|
'fields' => array(
|
823
|
'module' => array(
|
824
|
'type' => 'varchar',
|
825
|
'length' => 64,
|
826
|
'not null' => TRUE,
|
827
|
'description' => "The block's origin module, from {block}.module.",
|
828
|
),
|
829
|
'delta' => array(
|
830
|
'type' => 'varchar',
|
831
|
'length' => 32,
|
832
|
'not null' => TRUE,
|
833
|
'description' => "The block's unique delta within module, from {block}.delta.",
|
834
|
),
|
835
|
'type' => array(
|
836
|
'type' => 'varchar',
|
837
|
'length' => 32,
|
838
|
'not null' => TRUE,
|
839
|
'description' => "The machine-readable name of this type from {node_type}.type.",
|
840
|
),
|
841
|
),
|
842
|
'primary key' => array('module', 'delta', 'type'),
|
843
|
'indexes' => array(
|
844
|
'type' => array('type'),
|
845
|
),
|
846
|
);
|
847
|
|
848
|
db_create_table('block_node_type', $schema['block_node_type']);
|
849
|
}
|
850
|
|
851
|
/**
|
852
|
* @} End of "addtogroup updates-6.x-to-7.x".
|
853
|
*/
|
854
|
|
855
|
/**
|
856
|
* @addtogroup updates-7.x-extra
|
857
|
* @{
|
858
|
*/
|
859
|
|
860
|
/**
|
861
|
* Update the database from Drupal 6 to match the schema.
|
862
|
*/
|
863
|
function node_update_7011() {
|
864
|
// Drop node moderation field.
|
865
|
db_drop_field('node', 'moderate');
|
866
|
db_drop_index('node', 'node_moderate');
|
867
|
|
868
|
// Change {node_revision}.status field to default to 1.
|
869
|
db_change_field('node_revision', 'status', 'status', array(
|
870
|
'type' => 'int',
|
871
|
'not null' => TRUE,
|
872
|
'default' => 1,
|
873
|
));
|
874
|
|
875
|
// Change {node_type}.module field default.
|
876
|
db_change_field('node_type', 'module', 'module', array(
|
877
|
'type' => 'varchar',
|
878
|
'length' => 255,
|
879
|
'not null' => TRUE,
|
880
|
));
|
881
|
}
|
882
|
|
883
|
/**
|
884
|
* Switches body fields to untranslatable while upgrading from D6 and makes them language neutral.
|
885
|
*/
|
886
|
function node_update_7012() {
|
887
|
// If we are upgrading from D6, then body fields should be set back to
|
888
|
// untranslatable, as D6 did not know about the idea of translating fields,
|
889
|
// but only nodes. If a D7 > D7 update is running we need to skip this update,
|
890
|
// as it is a valid use case to have translatable body fields in this context.
|
891
|
if (variable_get('update_d6', FALSE)) {
|
892
|
// Make node bodies untranslatable: field_update_field() cannot be used
|
893
|
// throughout the upgrade process and we do not have an update counterpart
|
894
|
// for _update_7000_field_create_field(). Hence we are forced to update the
|
895
|
// 'field_config' table directly. This is a safe operation since it is
|
896
|
// being performed while upgrading from D6. Perfoming the same operation
|
897
|
// during a D7 update is highly discouraged.
|
898
|
db_update('field_config')
|
899
|
->fields(array('translatable' => 0))
|
900
|
->condition('field_name', 'body')
|
901
|
->execute();
|
902
|
|
903
|
// Switch field languages to LANGUAGE_NONE, since initially they were
|
904
|
// assigned the node language.
|
905
|
foreach (array('field_data_body', 'field_revision_body') as $table) {
|
906
|
db_update($table)
|
907
|
->fields(array('language' => LANGUAGE_NONE))
|
908
|
->execute();
|
909
|
}
|
910
|
|
911
|
node_type_cache_reset();
|
912
|
}
|
913
|
}
|
914
|
|
915
|
/**
|
916
|
* Change {node}.vid default value from 0 to NULL to avoid deadlock issues on MySQL.
|
917
|
*/
|
918
|
function node_update_7013() {
|
919
|
db_drop_unique_key('node', 'vid');
|
920
|
db_change_field('node', 'vid', 'vid', array(
|
921
|
'description' => 'The current {node_revision}.vid version identifier.',
|
922
|
'type' => 'int',
|
923
|
'unsigned' => TRUE,
|
924
|
'not null' => FALSE,
|
925
|
'default' => NULL,
|
926
|
));
|
927
|
db_add_unique_key('node', 'vid', array('vid'));
|
928
|
}
|
929
|
|
930
|
/**
|
931
|
* Add an index on {node}.language.
|
932
|
*/
|
933
|
function node_update_7014() {
|
934
|
db_add_index('node', 'language', array('language'));
|
935
|
}
|
936
|
|
937
|
/**
|
938
|
* Enable node types that may have been erroneously disabled in Drupal 7.36.
|
939
|
*/
|
940
|
function node_update_7015() {
|
941
|
db_update('node_type')
|
942
|
->fields(array('disabled' => 0))
|
943
|
->condition('base', 'node_content')
|
944
|
->execute();
|
945
|
}
|
946
|
|
947
|
/**
|
948
|
* Change {history}.nid to an unsigned int in order to match {node}.nid.
|
949
|
*/
|
950
|
function node_update_7016() {
|
951
|
db_drop_primary_key('history');
|
952
|
db_drop_index('history', 'nid');
|
953
|
db_change_field('history', 'nid', 'nid', array(
|
954
|
'description' => 'The {node}.nid that was read.',
|
955
|
'type' => 'int',
|
956
|
'unsigned' => TRUE,
|
957
|
'not null' => TRUE,
|
958
|
'default' => 0,
|
959
|
));
|
960
|
db_add_primary_key('history', array('uid', 'nid'));
|
961
|
db_add_index('history', 'nid', array('nid'));
|
962
|
}
|
963
|
|
964
|
/**
|
965
|
* @} End of "addtogroup updates-7.x-extra".
|
966
|
*/
|