Mercurial > hg > rr-repo
comparison modules/user/user.install @ 0:ff03f76ab3fe
initial version
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Wed, 21 Aug 2013 18:51:11 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff03f76ab3fe |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Install, update and uninstall functions for the user module. | |
6 */ | |
7 | |
8 /** | |
9 * Implements hook_schema(). | |
10 */ | |
11 function user_schema() { | |
12 $schema['authmap'] = array( | |
13 'description' => 'Stores distributed authentication mapping.', | |
14 'fields' => array( | |
15 'aid' => array( | |
16 'description' => 'Primary Key: Unique authmap ID.', | |
17 'type' => 'serial', | |
18 'unsigned' => TRUE, | |
19 'not null' => TRUE, | |
20 ), | |
21 'uid' => array( | |
22 'type' => 'int', | |
23 'not null' => TRUE, | |
24 'default' => 0, | |
25 'description' => "User's {users}.uid.", | |
26 ), | |
27 'authname' => array( | |
28 'type' => 'varchar', | |
29 'length' => 128, | |
30 'not null' => TRUE, | |
31 'default' => '', | |
32 'description' => 'Unique authentication name.', | |
33 ), | |
34 'module' => array( | |
35 'type' => 'varchar', | |
36 'length' => 128, | |
37 'not null' => TRUE, | |
38 'default' => '', | |
39 'description' => 'Module which is controlling the authentication.', | |
40 ), | |
41 ), | |
42 'unique keys' => array( | |
43 'authname' => array('authname'), | |
44 ), | |
45 'primary key' => array('aid'), | |
46 'foreign keys' => array( | |
47 'user' => array( | |
48 'table' => 'users', | |
49 'columns' => array('uid' => 'uid'), | |
50 ), | |
51 ), | |
52 ); | |
53 | |
54 $schema['role_permission'] = array( | |
55 'description' => 'Stores the permissions assigned to user roles.', | |
56 'fields' => array( | |
57 'rid' => array( | |
58 'type' => 'int', | |
59 'unsigned' => TRUE, | |
60 'not null' => TRUE, | |
61 'description' => 'Foreign Key: {role}.rid.', | |
62 ), | |
63 'permission' => array( | |
64 'type' => 'varchar', | |
65 'length' => 128, | |
66 'not null' => TRUE, | |
67 'default' => '', | |
68 'description' => 'A single permission granted to the role identified by rid.', | |
69 ), | |
70 'module' => array( | |
71 'type' => 'varchar', | |
72 'length' => 255, | |
73 'not null' => TRUE, | |
74 'default' => '', | |
75 'description' => "The module declaring the permission.", | |
76 ), | |
77 ), | |
78 'primary key' => array('rid', 'permission'), | |
79 'indexes' => array( | |
80 'permission' => array('permission'), | |
81 ), | |
82 'foreign keys' => array( | |
83 'role' => array( | |
84 'table' => 'roles', | |
85 'columns' => array('rid' => 'rid'), | |
86 ), | |
87 ), | |
88 ); | |
89 | |
90 $schema['role'] = array( | |
91 'description' => 'Stores user roles.', | |
92 'fields' => array( | |
93 'rid' => array( | |
94 'type' => 'serial', | |
95 'unsigned' => TRUE, | |
96 'not null' => TRUE, | |
97 'description' => 'Primary Key: Unique role ID.', | |
98 ), | |
99 'name' => array( | |
100 'type' => 'varchar', | |
101 'length' => 64, | |
102 'not null' => TRUE, | |
103 'default' => '', | |
104 'description' => 'Unique role name.', | |
105 'translatable' => TRUE, | |
106 ), | |
107 'weight' => array( | |
108 'type' => 'int', | |
109 'not null' => TRUE, | |
110 'default' => 0, | |
111 'description' => 'The weight of this role in listings and the user interface.', | |
112 ), | |
113 ), | |
114 'unique keys' => array( | |
115 'name' => array('name'), | |
116 ), | |
117 'primary key' => array('rid'), | |
118 'indexes' => array( | |
119 'name_weight' => array('name', 'weight'), | |
120 ), | |
121 ); | |
122 | |
123 // The table name here is plural, despite Drupal table naming standards, | |
124 // because "user" is a reserved word in many databases. | |
125 $schema['users'] = array( | |
126 'description' => 'Stores user data.', | |
127 'fields' => array( | |
128 'uid' => array( | |
129 'type' => 'int', | |
130 'unsigned' => TRUE, | |
131 'not null' => TRUE, | |
132 'description' => 'Primary Key: Unique user ID.', | |
133 'default' => 0, | |
134 ), | |
135 'name' => array( | |
136 'type' => 'varchar', | |
137 'length' => 60, | |
138 'not null' => TRUE, | |
139 'default' => '', | |
140 'description' => 'Unique user name.', | |
141 ), | |
142 'pass' => array( | |
143 'type' => 'varchar', | |
144 'length' => 128, | |
145 'not null' => TRUE, | |
146 'default' => '', | |
147 'description' => "User's password (hashed).", | |
148 ), | |
149 'mail' => array( | |
150 'type' => 'varchar', | |
151 'length' => 254, | |
152 'not null' => FALSE, | |
153 'default' => '', | |
154 'description' => "User's e-mail address.", | |
155 ), | |
156 'theme' => array( | |
157 'type' => 'varchar', | |
158 'length' => 255, | |
159 'not null' => TRUE, | |
160 'default' => '', | |
161 'description' => "User's default theme.", | |
162 ), | |
163 'signature' => array( | |
164 'type' => 'varchar', | |
165 'length' => 255, | |
166 'not null' => TRUE, | |
167 'default' => '', | |
168 'description' => "User's signature.", | |
169 ), | |
170 'signature_format' => array( | |
171 'type' => 'varchar', | |
172 'length' => 255, | |
173 'not null' => FALSE, | |
174 'description' => 'The {filter_format}.format of the signature.', | |
175 ), | |
176 'created' => array( | |
177 'type' => 'int', | |
178 'not null' => TRUE, | |
179 'default' => 0, | |
180 'description' => 'Timestamp for when user was created.', | |
181 ), | |
182 'access' => array( | |
183 'type' => 'int', | |
184 'not null' => TRUE, | |
185 'default' => 0, | |
186 'description' => 'Timestamp for previous time user accessed the site.', | |
187 ), | |
188 'login' => array( | |
189 'type' => 'int', | |
190 'not null' => TRUE, | |
191 'default' => 0, | |
192 'description' => "Timestamp for user's last login.", | |
193 ), | |
194 'status' => array( | |
195 'type' => 'int', | |
196 'not null' => TRUE, | |
197 'default' => 0, | |
198 'size' => 'tiny', | |
199 'description' => 'Whether the user is active(1) or blocked(0).', | |
200 ), | |
201 'timezone' => array( | |
202 'type' => 'varchar', | |
203 'length' => 32, | |
204 'not null' => FALSE, | |
205 'description' => "User's time zone.", | |
206 ), | |
207 'language' => array( | |
208 'type' => 'varchar', | |
209 'length' => 12, | |
210 'not null' => TRUE, | |
211 'default' => '', | |
212 'description' => "User's default language.", | |
213 ), | |
214 'picture' => array( | |
215 'type' => 'int', | |
216 'not null' => TRUE, | |
217 'default' => 0, | |
218 'description' => "Foreign key: {file_managed}.fid of user's picture.", | |
219 ), | |
220 'init' => array( | |
221 'type' => 'varchar', | |
222 'length' => 254, | |
223 'not null' => FALSE, | |
224 'default' => '', | |
225 'description' => 'E-mail address used for initial account creation.', | |
226 ), | |
227 'data' => array( | |
228 'type' => 'blob', | |
229 'not null' => FALSE, | |
230 'size' => 'big', | |
231 'serialize' => TRUE, | |
232 'description' => 'A serialized array of name value pairs that are related to the user. Any form values posted during user edit are stored and are loaded into the $user object during user_load(). Use of this field is discouraged and it will likely disappear in a future version of Drupal.', | |
233 ), | |
234 ), | |
235 'indexes' => array( | |
236 'access' => array('access'), | |
237 'created' => array('created'), | |
238 'mail' => array('mail'), | |
239 'picture' => array('picture'), | |
240 ), | |
241 'unique keys' => array( | |
242 'name' => array('name'), | |
243 ), | |
244 'primary key' => array('uid'), | |
245 'foreign keys' => array( | |
246 'signature_format' => array( | |
247 'table' => 'filter_format', | |
248 'columns' => array('signature_format' => 'format'), | |
249 ), | |
250 ), | |
251 ); | |
252 | |
253 $schema['users_roles'] = array( | |
254 'description' => 'Maps users to roles.', | |
255 'fields' => array( | |
256 'uid' => array( | |
257 'type' => 'int', | |
258 'unsigned' => TRUE, | |
259 'not null' => TRUE, | |
260 'default' => 0, | |
261 'description' => 'Primary Key: {users}.uid for user.', | |
262 ), | |
263 'rid' => array( | |
264 'type' => 'int', | |
265 'unsigned' => TRUE, | |
266 'not null' => TRUE, | |
267 'default' => 0, | |
268 'description' => 'Primary Key: {role}.rid for role.', | |
269 ), | |
270 ), | |
271 'primary key' => array('uid', 'rid'), | |
272 'indexes' => array( | |
273 'rid' => array('rid'), | |
274 ), | |
275 'foreign keys' => array( | |
276 'user' => array( | |
277 'table' => 'users', | |
278 'columns' => array('uid' => 'uid'), | |
279 ), | |
280 'role' => array( | |
281 'table' => 'roles', | |
282 'columns' => array('rid' => 'rid'), | |
283 ), | |
284 ), | |
285 ); | |
286 | |
287 return $schema; | |
288 } | |
289 | |
290 /** | |
291 * Implements hook_install(). | |
292 */ | |
293 function user_install() { | |
294 // Insert a row for the anonymous user. | |
295 db_insert('users') | |
296 ->fields(array( | |
297 'uid' => 0, | |
298 'name' => '', | |
299 'mail' => '', | |
300 )) | |
301 ->execute(); | |
302 | |
303 // We need some placeholders here as name and mail are uniques and data is | |
304 // presumed to be a serialized array. This will be changed by the settings | |
305 // form in the installer. | |
306 db_insert('users') | |
307 ->fields(array( | |
308 'uid' => 1, | |
309 'name' => 'placeholder-for-uid-1', | |
310 'mail' => 'placeholder-for-uid-1', | |
311 'created' => REQUEST_TIME, | |
312 'status' => 1, | |
313 'data' => NULL, | |
314 )) | |
315 ->execute(); | |
316 | |
317 // Built-in roles. | |
318 $rid_anonymous = db_insert('role') | |
319 ->fields(array('name' => 'anonymous user', 'weight' => 0)) | |
320 ->execute(); | |
321 $rid_authenticated = db_insert('role') | |
322 ->fields(array('name' => 'authenticated user', 'weight' => 1)) | |
323 ->execute(); | |
324 | |
325 // Sanity check to ensure the anonymous and authenticated role IDs are the | |
326 // same as the drupal defined constants. In certain situations, this will | |
327 // not be true. | |
328 if ($rid_anonymous != DRUPAL_ANONYMOUS_RID) { | |
329 db_update('role') | |
330 ->fields(array('rid' => DRUPAL_ANONYMOUS_RID)) | |
331 ->condition('rid', $rid_anonymous) | |
332 ->execute(); | |
333 } | |
334 if ($rid_authenticated != DRUPAL_AUTHENTICATED_RID) { | |
335 db_update('role') | |
336 ->fields(array('rid' => DRUPAL_AUTHENTICATED_RID)) | |
337 ->condition('rid', $rid_authenticated) | |
338 ->execute(); | |
339 } | |
340 } | |
341 | |
342 /** | |
343 * Implements hook_update_dependencies(). | |
344 */ | |
345 function user_update_dependencies() { | |
346 // user_update_7006() updates data in the {role_permission} table, so it must | |
347 // run after system_update_7007(), which populates that table. | |
348 $dependencies['user'][7006] = array( | |
349 'system' => 7007, | |
350 ); | |
351 | |
352 // user_update_7010() needs to query the {filter_format} table to get a list | |
353 // of existing text formats, so it must run after filter_update_7000(), which | |
354 // creates that table. | |
355 $dependencies['user'][7010] = array( | |
356 'filter' => 7000, | |
357 ); | |
358 | |
359 // user_update_7012() uses the file API, which relies on the {file_managed} | |
360 // table, so it must run after system_update_7034(), which creates that | |
361 // table. | |
362 $dependencies['user'][7012] = array( | |
363 'system' => 7034, | |
364 ); | |
365 | |
366 // user_update_7013() uses the file usage API, which relies on the | |
367 // {file_usage} table, so it must run after system_update_7059(), which | |
368 // creates that table. | |
369 $dependencies['user'][7013] = array( | |
370 'system' => 7059, | |
371 ); | |
372 | |
373 return $dependencies; | |
374 } | |
375 | |
376 /** | |
377 * Utility function: grant a set of permissions to a role during update. | |
378 * | |
379 * This function is valid for a database schema version 7000. | |
380 * | |
381 * @param $rid | |
382 * The role ID. | |
383 * @param $permissions | |
384 * An array of permissions names. | |
385 * @param $module | |
386 * The name of the module defining the permissions. | |
387 * @ingroup update_api | |
388 */ | |
389 function _update_7000_user_role_grant_permissions($rid, array $permissions, $module) { | |
390 // Grant new permissions for the role. | |
391 foreach ($permissions as $name) { | |
392 db_merge('role_permission') | |
393 ->key(array( | |
394 'rid' => $rid, | |
395 'permission' => $name, | |
396 )) | |
397 ->fields(array( | |
398 'module' => $module, | |
399 )) | |
400 ->execute(); | |
401 } | |
402 } | |
403 | |
404 /** | |
405 * @addtogroup updates-6.x-to-7.x | |
406 * @{ | |
407 */ | |
408 | |
409 /** | |
410 * Increase the length of the password field to accommodate better hashes. | |
411 * | |
412 * Also re-hashes all current passwords to improve security. This may be a | |
413 * lengthy process, and is performed batch-wise. | |
414 */ | |
415 function user_update_7000(&$sandbox) { | |
416 $sandbox['#finished'] = 0; | |
417 // Lower than DRUPAL_HASH_COUNT to make the update run at a reasonable speed. | |
418 $hash_count_log2 = 11; | |
419 // Multi-part update. | |
420 if (!isset($sandbox['user_from'])) { | |
421 db_change_field('users', 'pass', 'pass', array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '')); | |
422 $sandbox['user_from'] = 0; | |
423 $sandbox['user_count'] = db_query("SELECT COUNT(uid) FROM {users}")->fetchField(); | |
424 } | |
425 else { | |
426 require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc'); | |
427 // Hash again all current hashed passwords. | |
428 $has_rows = FALSE; | |
429 // Update this many per page load. | |
430 $count = 1000; | |
431 $result = db_query_range("SELECT uid, pass FROM {users} WHERE uid > 0 ORDER BY uid", $sandbox['user_from'], $count); | |
432 foreach ($result as $account) { | |
433 $has_rows = TRUE; | |
434 | |
435 // If the $account->pass value is not a MD5 hash (a 32 character | |
436 // hexadecimal string) then skip it. | |
437 if (!preg_match('/^[0-9a-f]{32}$/', $account->pass)) { | |
438 continue; | |
439 } | |
440 | |
441 $new_hash = user_hash_password($account->pass, $hash_count_log2); | |
442 if ($new_hash) { | |
443 // Indicate an updated password. | |
444 $new_hash = 'U' . $new_hash; | |
445 db_update('users') | |
446 ->fields(array('pass' => $new_hash)) | |
447 ->condition('uid', $account->uid) | |
448 ->execute(); | |
449 } | |
450 } | |
451 $sandbox['#finished'] = $sandbox['user_from']/$sandbox['user_count']; | |
452 $sandbox['user_from'] += $count; | |
453 if (!$has_rows) { | |
454 $sandbox['#finished'] = 1; | |
455 return t('User passwords rehashed to improve security'); | |
456 } | |
457 } | |
458 } | |
459 | |
460 /** | |
461 * Remove the 'threshold', 'mode' and 'sort' columns from the {users} table. | |
462 * | |
463 * These fields were previously used to store per-user comment settings. | |
464 */ | |
465 | |
466 function user_update_7001() { | |
467 db_drop_field('users', 'threshold'); | |
468 db_drop_field('users', 'mode'); | |
469 db_drop_field('users', 'sort'); | |
470 } | |
471 | |
472 /** | |
473 * Convert user time zones from time zone offsets to time zone names. | |
474 */ | |
475 function user_update_7002(&$sandbox) { | |
476 $sandbox['#finished'] = 0; | |
477 | |
478 // Multi-part update. | |
479 if (!isset($sandbox['user_from'])) { | |
480 db_change_field('users', 'timezone', 'timezone', array('type' => 'varchar', 'length' => 32, 'not null' => FALSE)); | |
481 $sandbox['user_from'] = 0; | |
482 $sandbox['user_count'] = db_query("SELECT COUNT(uid) FROM {users}")->fetchField(); | |
483 $sandbox['user_not_migrated'] = 0; | |
484 } | |
485 else { | |
486 $timezones = system_time_zones(); | |
487 // Update this many per page load. | |
488 $count = 10000; | |
489 $contributed_date_module = db_field_exists('users', 'timezone_name'); | |
490 $contributed_event_module = db_field_exists('users', 'timezone_id'); | |
491 | |
492 $results = db_query_range("SELECT uid FROM {users} ORDER BY uid", $sandbox['user_from'], $count); | |
493 foreach ($results as $account) { | |
494 $timezone = NULL; | |
495 // If the contributed Date module has created a users.timezone_name | |
496 // column, use this data to set each user's time zone. | |
497 if ($contributed_date_module) { | |
498 $date_timezone = db_query("SELECT timezone_name FROM {users} WHERE uid = :uid", array(':uid' => $account->uid))->fetchField(); | |
499 if (isset($timezones[$date_timezone])) { | |
500 $timezone = $date_timezone; | |
501 } | |
502 } | |
503 // If the contributed Event module has stored user time zone information | |
504 // use that information to update the user accounts. | |
505 if (!$timezone && $contributed_event_module) { | |
506 try { | |
507 $event_timezone = db_query("SELECT t.name FROM {users} u LEFT JOIN {event_timezones} t ON u.timezone_id = t.timezone WHERE u.uid = :uid", array(':uid' => $account->uid))->fetchField(); | |
508 $event_timezone = str_replace(' ', '_', $event_timezone); | |
509 if (isset($timezones[$event_timezone])) { | |
510 $timezone = $event_timezone; | |
511 } | |
512 } | |
513 catch (PDOException $e) { | |
514 // Ignore error if event_timezones table does not exist or unexpected | |
515 // schema found. | |
516 } | |
517 } | |
518 if ($timezone) { | |
519 db_update('users') | |
520 ->fields(array('timezone' => $timezone)) | |
521 ->condition('uid', $account->uid) | |
522 ->execute(); | |
523 } | |
524 else { | |
525 $sandbox['user_not_migrated']++; | |
526 db_update('users') | |
527 ->fields(array('timezone' => NULL)) | |
528 ->condition('uid', $account->uid) | |
529 ->execute(); | |
530 } | |
531 $sandbox['user_from']++; | |
532 } | |
533 | |
534 $sandbox['#finished'] = $sandbox['user_from'] / $sandbox['user_count']; | |
535 if ($sandbox['user_from'] == $sandbox['user_count']) { | |
536 if ($sandbox['user_not_migrated'] > 0) { | |
537 variable_set('empty_timezone_message', 1); | |
538 drupal_set_message(format_string('Some user time zones have been emptied and need to be set to the correct values. Use the new <a href="@config-url">time zone options</a> to choose whether to remind users at login to set the correct time zone.', array('@config-url' => url('admin/config/regional/settings'))), 'warning'); | |
539 } | |
540 return t('Migrated user time zones'); | |
541 } | |
542 } | |
543 } | |
544 | |
545 /** | |
546 * Update user settings for cancelling user accounts. | |
547 * | |
548 * Prior to 7.x, users were not able to cancel their accounts. When | |
549 * administrators deleted an account, all contents were assigned to uid 0, | |
550 * which is the same as the 'user_cancel_reassign' method now. | |
551 */ | |
552 function user_update_7003() { | |
553 // Set the default account cancellation method. | |
554 variable_set('user_cancel_method', 'user_cancel_reassign'); | |
555 // Re-assign notification setting. | |
556 if ($setting = variable_get('user_mail_status_deleted_notify', FALSE)) { | |
557 variable_set('user_mail_status_canceled_notify', $setting); | |
558 variable_del('user_mail_status_deleted_notify'); | |
559 } | |
560 // Re-assign "Account deleted" mail strings to "Account canceled" mail. | |
561 if ($setting = variable_get('user_mail_status_deleted_subject', FALSE)) { | |
562 variable_set('user_mail_status_canceled_subject', $setting); | |
563 variable_del('user_mail_status_deleted_subject'); | |
564 } | |
565 if ($setting = variable_get('user_mail_status_deleted_body', FALSE)) { | |
566 variable_set('user_mail_status_canceled_body', $setting); | |
567 variable_del('user_mail_status_deleted_body'); | |
568 } | |
569 } | |
570 | |
571 /** | |
572 * Changes the users table to allow longer e-mail addresses. | |
573 */ | |
574 function user_update_7005(&$sandbox) { | |
575 $mail_field = array( | |
576 'type' => 'varchar', | |
577 'length' => 254, | |
578 'not null' => FALSE, | |
579 'default' => '', | |
580 'description' => "User's e-mail address.", | |
581 ); | |
582 $init_field = array( | |
583 'type' => 'varchar', | |
584 'length' => 254, | |
585 'not null' => FALSE, | |
586 'default' => '', | |
587 'description' => 'E-mail address used for initial account creation.', | |
588 ); | |
589 db_drop_index('users', 'mail'); | |
590 db_change_field('users', 'mail', 'mail', $mail_field, array('indexes' => array('mail' => array('mail')))); | |
591 db_change_field('users', 'init', 'init', $init_field); | |
592 } | |
593 | |
594 /** | |
595 * Add module data to {role_permission}. | |
596 */ | |
597 function user_update_7006(&$sandbox) { | |
598 $module_field = array( | |
599 'type' => 'varchar', | |
600 'length' => 255, | |
601 'not null' => TRUE, | |
602 'default' => '', | |
603 'description' => "The module declaring the permission.", | |
604 ); | |
605 // Check that the field hasn't been updated in an aborted run of this | |
606 // update. | |
607 if (!db_field_exists('role_permission', 'module')) { | |
608 // Add a new field for the fid. | |
609 db_add_field('role_permission', 'module', $module_field); | |
610 } | |
611 } | |
612 | |
613 /** | |
614 * Add a weight column to user roles. | |
615 */ | |
616 function user_update_7007() { | |
617 db_add_field('role', 'weight', array('type' => 'int', 'not null' => TRUE, 'default' => 0)); | |
618 db_add_index('role', 'name_weight', array('name', 'weight')); | |
619 } | |
620 | |
621 /** | |
622 * If 'user_register' variable was unset in Drupal 6, set it to be the same as | |
623 * the Drupal 6 default setting. | |
624 */ | |
625 function user_update_7008() { | |
626 if (!isset($GLOBALS['conf']['user_register'])) { | |
627 // Set to the Drupal 6 default, "visitors can create accounts". | |
628 variable_set('user_register', USER_REGISTER_VISITORS); | |
629 } | |
630 } | |
631 | |
632 /** | |
633 * Converts fields that store serialized variables from text to blob. | |
634 */ | |
635 function user_update_7009() { | |
636 $spec = array( | |
637 'type' => 'blob', | |
638 'not null' => FALSE, | |
639 'size' => 'big', | |
640 'serialize' => TRUE, | |
641 'description' => 'A serialized array of name value pairs that are related to the user. Any form values posted during user edit are stored and are loaded into the $user object during user_load(). Use of this field is discouraged and it will likely disappear in a future version of Drupal.', | |
642 ); | |
643 db_change_field('users', 'data', 'data', $spec); | |
644 } | |
645 | |
646 /** | |
647 * Update the {user}.signature_format column. | |
648 */ | |
649 function user_update_7010() { | |
650 // Update the database column to allow NULL values. | |
651 db_change_field('users', 'signature_format', 'signature_format', array( | |
652 'type' => 'int', | |
653 'unsigned' => TRUE, | |
654 'not null' => FALSE, | |
655 'description' => 'The {filter_format}.format of the signature.', | |
656 )); | |
657 | |
658 // Replace the signature format with NULL if the signature is empty and does | |
659 // not already have a stored text format. | |
660 // | |
661 // In Drupal 6, "0" (the former FILTER_FORMAT_DEFAULT constant) could be used | |
662 // to indicate this situation, but in Drupal 7, only NULL is supported. This | |
663 // update therefore preserves the ability of user accounts which were never | |
664 // given a signature (for example, if the site did not have user signatures | |
665 // enabled, or if the user never edited their account information) to not | |
666 // have a particular text format assumed for them the first time the | |
667 // signature is edited. | |
668 db_update('users') | |
669 ->fields(array('signature_format' => NULL)) | |
670 ->condition('signature', '') | |
671 ->condition('signature_format', 0) | |
672 ->execute(); | |
673 | |
674 // There are a number of situations in which a Drupal 6 site could store | |
675 // content with a nonexistent text format. This includes text formats that | |
676 // had later been deleted, or non-empty content stored with a value of "0" | |
677 // (the former FILTER_FORMAT_DEFAULT constant). Drupal 6 would filter this | |
678 // content using whatever the site-wide default text format was at the moment | |
679 // the text was being displayed. | |
680 // | |
681 // In Drupal 7, this behavior is no longer supported, and all content must be | |
682 // stored with an explicit text format (or it will not be displayed when it | |
683 // is filtered). Therefore, to preserve the behavior of the site after the | |
684 // upgrade, we must replace all instances described above with the current | |
685 // value of the (old) site-wide default format at the moment of the upgrade. | |
686 $existing_formats = db_query("SELECT format FROM {filter_format}")->fetchCol(); | |
687 $default_format = variable_get('filter_default_format', 1); | |
688 db_update('users') | |
689 ->fields(array('signature_format' => $default_format)) | |
690 ->isNotNull('signature_format') | |
691 ->condition('signature_format', $existing_formats, 'NOT IN') | |
692 ->execute(); | |
693 } | |
694 | |
695 /** | |
696 * Placeholder function. | |
697 * | |
698 * As a fix for user_update_7011() not updating email templates to use the new | |
699 * tokens, user_update_7017() now targets email templates of Drupal 6 sites and | |
700 * already upgraded sites. | |
701 */ | |
702 function user_update_7011() { | |
703 } | |
704 | |
705 /** | |
706 * Add the user's pictures to the {file_managed} table and make them managed | |
707 * files. | |
708 */ | |
709 function user_update_7012(&$sandbox) { | |
710 | |
711 $picture_field = array( | |
712 'type' => 'int', | |
713 'not null' => TRUE, | |
714 'default' => 0, | |
715 'description' => "Foreign key: {file_managed}.fid of user's picture.", | |
716 ); | |
717 | |
718 if (!isset($sandbox['progress'])) { | |
719 // Check that the field hasn't been updated in an aborted run of this | |
720 // update. | |
721 if (!db_field_exists('users', 'picture_fid')) { | |
722 // Add a new field for the fid. | |
723 db_add_field('users', 'picture_fid', $picture_field); | |
724 } | |
725 | |
726 // Initialize batch update information. | |
727 $sandbox['progress'] = 0; | |
728 $sandbox['last_user_processed'] = -1; | |
729 $sandbox['max'] = db_query("SELECT COUNT(*) FROM {users} WHERE picture <> ''")->fetchField(); | |
730 } | |
731 | |
732 // As a batch operation move the photos into the {file_managed} table and | |
733 // update the {users} records. | |
734 $limit = 500; | |
735 $result = db_query_range("SELECT uid, picture FROM {users} WHERE picture <> '' AND uid > :uid ORDER BY uid", 0, $limit, array(':uid' => $sandbox['last_user_processed'])); | |
736 foreach ($result as $user) { | |
737 // Don't bother adding files that don't exist. | |
738 if (file_exists($user->picture)) { | |
739 | |
740 // Check if the file already exists. | |
741 $files = file_load_multiple(array(), array('uri' => $user->picture)); | |
742 if (count($files)) { | |
743 $file = reset($files); | |
744 } | |
745 else { | |
746 // Create a file object. | |
747 $file = new stdClass(); | |
748 $file->uri = $user->picture; | |
749 $file->filename = drupal_basename($file->uri); | |
750 $file->filemime = file_get_mimetype($file->uri); | |
751 $file->uid = $user->uid; | |
752 $file->status = FILE_STATUS_PERMANENT; | |
753 $file = file_save($file); | |
754 } | |
755 | |
756 db_update('users') | |
757 ->fields(array('picture_fid' => $file->fid)) | |
758 ->condition('uid', $user->uid) | |
759 ->execute(); | |
760 } | |
761 | |
762 // Update our progress information for the batch update. | |
763 $sandbox['progress']++; | |
764 $sandbox['last_user_processed'] = $user->uid; | |
765 } | |
766 | |
767 // Indicate our current progress to the batch update system. If there's no | |
768 // max value then there's nothing to update and we're finished. | |
769 $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); | |
770 | |
771 // When we're finished, drop the old picture field and rename the new one to | |
772 // replace it. | |
773 if (isset($sandbox['#finished']) && $sandbox['#finished'] == 1) { | |
774 db_drop_field('users', 'picture'); | |
775 db_change_field('users', 'picture_fid', 'picture', $picture_field); | |
776 } | |
777 } | |
778 | |
779 /** | |
780 * Add user module file usage entries. | |
781 */ | |
782 function user_update_7013(&$sandbox) { | |
783 if (!isset($sandbox['progress'])) { | |
784 // Initialize batch update information. | |
785 $sandbox['progress'] = 0; | |
786 $sandbox['last_uid_processed'] = -1; | |
787 $sandbox['max'] = db_query("SELECT COUNT(*) FROM {users} u WHERE u.picture <> 0")->fetchField(); | |
788 } | |
789 | |
790 // Add usage entries for the user picture files. | |
791 $limit = 500; | |
792 $result = db_query_range('SELECT f.*, u.uid as user_uid FROM {users} u INNER JOIN {file_managed} f ON u.picture = f.fid WHERE u.picture <> 0 AND u.uid > :uid ORDER BY u.uid', 0, $limit, array(':uid' => $sandbox['last_uid_processed']))->fetchAllAssoc('fid', PDO::FETCH_ASSOC); | |
793 foreach ($result as $row) { | |
794 $uid = $row['user_uid']; | |
795 $file = (object) $row; | |
796 file_usage_add($file, 'user', 'user', $uid); | |
797 | |
798 // Update our progress information for the batch update. | |
799 $sandbox['progress']++; | |
800 $sandbox['last_uid_processed'] = $uid; | |
801 } | |
802 | |
803 // Indicate our current progress to the batch update system. | |
804 $sandbox['#finished'] = empty($sandbox['max']) || ($sandbox['progress'] / $sandbox['max']); | |
805 } | |
806 | |
807 /** | |
808 * Rename the 'post comments without approval' permission. | |
809 * | |
810 * In Drupal 7, this permission has been renamed to 'skip comment approval'. | |
811 */ | |
812 function user_update_7014() { | |
813 db_update('role_permission') | |
814 ->fields(array('permission' => 'skip comment approval')) | |
815 ->condition('permission', 'post comments without approval') | |
816 ->execute(); | |
817 | |
818 return t("Renamed the 'post comments without approval' permission to 'skip comment approval'."); | |
819 } | |
820 | |
821 /** | |
822 * Change {users}.signature_format into varchar. | |
823 */ | |
824 function user_update_7015() { | |
825 db_change_field('users', 'signature_format', 'signature_format', array( | |
826 'type' => 'varchar', | |
827 'length' => 255, | |
828 'not null' => FALSE, | |
829 'description' => 'The {filter_format}.format of the signature.', | |
830 )); | |
831 } | |
832 | |
833 /** | |
834 * @} End of "addtogroup updates-6.x-to-7.x". | |
835 */ | |
836 | |
837 /** | |
838 * @addtogroup updates-7.x-extra | |
839 * @{ | |
840 */ | |
841 | |
842 /** | |
843 * Update the database to match the schema. | |
844 */ | |
845 function user_update_7016() { | |
846 // Add field default. | |
847 db_change_field('users', 'uid', 'uid', array( | |
848 'type' => 'int', | |
849 'unsigned' => TRUE, | |
850 'not null' => TRUE, | |
851 'default' => 0, | |
852 )); | |
853 } | |
854 | |
855 /** | |
856 * Update email templates to use new tokens. | |
857 * | |
858 * This function upgrades customized email templates from the old !token format | |
859 * to the new core tokens format. Additionally, in Drupal 7 we no longer e-mail | |
860 * plain text passwords to users, and there is no token for a plain text | |
861 * password in the new token system. Therefore, it also modifies any saved | |
862 * templates using the old '!password' token such that the token is removed, and | |
863 * displays a warning to users that they may need to go and modify the wording | |
864 * of their templates. | |
865 */ | |
866 function user_update_7017() { | |
867 $message = ''; | |
868 | |
869 $tokens = array( | |
870 '!site' => '[site:name]', | |
871 '!username' => '[user:name]', | |
872 '!mailto' => '[user:mail]', | |
873 '!login_uri' => '[site:login-url]', | |
874 '!uri_brief' => '[site:url-brief]', | |
875 '!edit_uri' => '[user:edit-url]', | |
876 '!login_url' => '[user:one-time-login-url]', | |
877 '!uri' => '[site:url]', | |
878 '!date' => '[date:medium]', | |
879 '!password' => '', | |
880 ); | |
881 | |
882 $result = db_select('variable', 'v') | |
883 ->fields('v', array('name')) | |
884 ->condition('name', db_like('user_mail_') . '%', 'LIKE') | |
885 ->execute(); | |
886 | |
887 foreach ($result as $row) { | |
888 // Use variable_get() to get the unserialized value for free. | |
889 if ($value = variable_get($row->name, FALSE)) { | |
890 | |
891 if (empty($message) && (strpos($value, '!password') !== FALSE)) { | |
892 $message = t('The ability to send users their passwords in plain text has been removed in Drupal 7. Your existing email templates have been modified to remove it. You should <a href="@template-url">review these templates</a> to make sure they read properly.', array('@template-url' => url('admin/config/people/accounts'))); | |
893 } | |
894 | |
895 variable_set($row->name, str_replace(array_keys($tokens), $tokens, $value)); | |
896 } | |
897 } | |
898 | |
899 return $message; | |
900 } | |
901 | |
902 /** | |
903 * Ensure there is an index on {users}.picture. | |
904 */ | |
905 function user_update_7018() { | |
906 if (!db_index_exists('users', 'picture')) { | |
907 db_add_index('users', 'picture', array('picture')); | |
908 } | |
909 } | |
910 | |
911 /** | |
912 * @} End of "addtogroup updates-7.x-extra". | |
913 */ |