| Drupal | PHP Cross Reference | Content Management Systems |
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('Some user time zones have been emptied and need to be set to the correct values. Use the new ' . l('time zone options', 'admin/config/regional/settings') . ' to choose whether to remind users at login to set the correct time zone.', '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 */
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title