|
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 */ |