Drupal PHP Cross Reference Content Management Systems

Source: /modules/user/user.install - 913 lines - 29412 bytes - Summary - Text - Print

   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

title

Description

title

Description

title

title

Body