[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/webform/ -> webform.install (source)

   1  <?php
   2  
   3  /**
   4   * @file
   5   *   Webform module install/schema hooks.
   6   */
   7  
   8  /**
   9   * Implements hook_schema().
  10   */
  11  function webform_schema() {
  12    $schema = array();
  13  
  14    $schema['webform'] = array(
  15      'description' => 'Table for storing additional properties for webform nodes.',
  16      'fields' => array(
  17        'nid' => array(
  18          'description' => 'The node identifier of a webform.',
  19          'type' => 'int',
  20          'unsigned' => TRUE,
  21          'not null' => TRUE,
  22        ),
  23        'confirmation' => array(
  24          'description' => 'The confirmation message or URL displayed to the user after submitting a form.',
  25          'type' => 'text',
  26          'not null' => TRUE,
  27        ),
  28        'confirmation_format' => array(
  29          'description' => 'The input format used by the confirmation message.',
  30          'type' => 'int',
  31          'size' => 'tiny',
  32          'not null' => TRUE,
  33          'default' => 0,
  34        ),
  35        'redirect_url' => array(
  36          'description' => 'The URL a user is redirected to after submitting a form.',
  37          'type' => 'varchar',
  38          'length' => 255,
  39          'default' => '<confirmation>',
  40        ),
  41        'status' => array(
  42          'description' => 'Boolean value of a webform for open (1) or closed (0).',
  43          'type' => 'int',
  44          'size' => 'tiny',
  45          'not null' => TRUE,
  46          'default' => 1,
  47        ),
  48        'block' => array(
  49           'description' => 'Boolean value for whether this form be available as a block.',
  50           'type' => 'int',
  51           'size' => 'tiny',
  52           'not null' => TRUE,
  53           'default' => 0,
  54        ),
  55        'teaser' => array(
  56          'description' => 'Boolean value for whether the entire form should be displayed on the teaser.',
  57          'type' => 'int',
  58          'size' => 'tiny',
  59          'not null' => TRUE,
  60          'default' => 0,
  61        ),
  62        'allow_draft' => array(
  63           'description' => 'Boolean value for whether submissions to this form be saved as a draft.',
  64           'type' => 'int',
  65           'size' => 'tiny',
  66           'not null' => TRUE,
  67           'default' => 0,
  68        ),
  69        'auto_save' => array(
  70           'description' => 'Boolean value for whether submissions to this form should be auto-saved between pages.',
  71           'type' => 'int',
  72           'size' => 'tiny',
  73           'not null' => TRUE,
  74           'default' => 0,
  75        ),
  76        'submit_notice' => array(
  77          'description' => 'Boolean value for whether to show or hide the previous submissions notification.',
  78          'type' => 'int',
  79          'size' => 'tiny',
  80          'not null' => TRUE,
  81          'default' => 1,
  82        ),
  83        'submit_text' => array(
  84          'description' => 'The title of the submit button on the form.',
  85          'type' => 'varchar',
  86          'length' => 255,
  87        ),
  88        'submit_limit' => array(
  89          'description' => 'The number of submissions a single user is allowed to submit within an interval. -1 is unlimited.',
  90          'type' => 'int',
  91          'size' => 'tiny',
  92          'not null' => TRUE,
  93          'default' => -1,
  94        ),
  95        'submit_interval' => array(
  96          'description' => 'The amount of time in seconds that must pass before a user can submit another submission within the set limit.',
  97          'type' => 'int',
  98          'not null' => TRUE,
  99          'default' => -1,
 100        ),
 101        'total_submit_limit' => array(
 102          'description' => 'The total number of submissions allowed within an interval. -1 is unlimited.',
 103          'type' => 'int',
 104          'not null' => TRUE,
 105          'default' => -1,
 106        ),
 107        'total_submit_interval' => array(
 108          'description' => 'The amount of time in seconds that must pass before another submission can be submitted within the set limit.',
 109          'type' => 'int',
 110          'not null' => TRUE,
 111          'default' => -1,
 112        ),
 113      ),
 114      'primary key' => array('nid'),
 115    );
 116  
 117    $schema['webform_component'] = array(
 118      'description' => 'Stores information about components for webform nodes.',
 119      'fields' => array(
 120        'nid' => array(
 121          'description' => 'The node identifier of a webform.',
 122          'type' => 'int',
 123          'unsigned' => TRUE,
 124          'not null' => TRUE,
 125          'default' => 0,
 126        ),
 127        'cid' => array(
 128          'description' => 'The identifier for this component within this node, starts at 0 for each node.',
 129          'type' => 'int',
 130          'size' => 'small',
 131          'unsigned' => TRUE,
 132          'not null' => TRUE,
 133          'default' => 0,
 134        ),
 135        'pid' => array(
 136          'description' => 'If this component has a parent fieldset, the cid of that component.',
 137          'type' => 'int',
 138          'size' => 'small',
 139          'unsigned' => TRUE,
 140          'not null' => TRUE,
 141          'default' => 0,
 142        ),
 143        'form_key' => array(
 144          'description' => 'When the form is displayed and processed, this key can be used to reference the results.',
 145          'type' => 'varchar',
 146          'length' => 128,
 147        ),
 148        'name' => array(
 149          'description' => 'The label for this component.',
 150          'type' => 'varchar',
 151          'length' => 255,
 152        ),
 153        'type' => array(
 154          'description' => 'The field type of this component (textfield, select, hidden, etc.).',
 155          'type' => 'varchar',
 156          'length' => 16,
 157        ),
 158        'value' => array(
 159          'description' => 'The default value of the component when displayed to the end-user.',
 160          'type' => 'text',
 161          'not null' => TRUE,
 162        ),
 163        'extra' => array(
 164          'description' => 'Additional information unique to the display or processing of this component.',
 165          'type' => 'text',
 166          'not null' => TRUE,
 167        ),
 168        'mandatory' => array(
 169          'description' => 'Boolean flag for if this component is required.',
 170          'type' => 'int',
 171          'size' => 'tiny',
 172          'not null' => TRUE,
 173          'default' => 0,
 174        ),
 175        'weight' => array(
 176          'description' => 'Determines the position of this component in the form.',
 177          'type' => 'int',
 178          'size' => 'small',
 179          'not null' => TRUE,
 180          'default' => 0,
 181        ),
 182      ),
 183      'primary key' => array('nid', 'cid'),
 184    );
 185  
 186    $schema['webform_emails'] = array(
 187      'description' => 'Holds information regarding e-mails that should be sent upon submitting a webform',
 188      'fields' => array(
 189        'nid' => array(
 190          'description' => 'The node identifier of a webform.',
 191          'type' => 'int',
 192          'unsigned' => TRUE,
 193          'not null' => TRUE,
 194          'default' => 0,
 195        ),
 196        'eid' => array(
 197          'description' => 'The e-mail identifier for this row\'s settings.',
 198          'type' => 'int',
 199          'unsigned' => TRUE,
 200          'size' => 'small',
 201          'not null' => TRUE,
 202          'default' => 0,
 203        ),
 204        'email' => array(
 205          'description' => 'The e-mail address that will be sent to upon submission. This may be an e-mail address, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.',
 206          'type' => 'text',
 207          'not null' => FALSE,
 208        ),
 209        'subject' => array(
 210          'description' => 'The e-mail subject that will be used. This may be a string, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.',
 211          'type' => 'varchar',
 212          'length' => '255',
 213          'not null' => FALSE,
 214        ),
 215        'from_name' => array(
 216          'description' => 'The e-mail "from" name that will be used. This may be a string, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.',
 217          'type' => 'varchar',
 218          'length' => '255',
 219          'not null' => FALSE,
 220        ),
 221        'from_address' => array(
 222          'description' => 'The e-mail "from" e-mail address that will be used. This may be a string, the special key "default" or a numeric value. If a numeric value is used, the value of a component will be substituted on submission.',
 223          'type' => 'varchar',
 224          'length' => '255',
 225          'not null' => FALSE,
 226        ),
 227        'template' => array(
 228          'description' => 'A template that will be used for the sent e-mail. This may be a string or the special key "default", which will use the template provided by the theming layer.',
 229          'type' => 'text',
 230          'not null' => FALSE,
 231        ),
 232        'excluded_components' => array(
 233          'description' => 'A list of components that will not be included in the %email_values token. A list of CIDs separated by commas.',
 234          'type' => 'text',
 235          'not null' => TRUE,
 236        ),
 237        'html' => array(
 238          'description' => 'Determines if the e-mail will be sent in an HTML format. Requires Mime Mail module.',
 239          'type' => 'int',
 240          'unsigned' => TRUE,
 241          'size' => 'tiny',
 242          'not null' => TRUE,
 243          'default' => 0,
 244        ),
 245        'attachments' => array(
 246          'description' => 'Determines if the e-mail will include file attachments. Requires Mime Mail module.',
 247          'type' => 'int',
 248          'unsigned' => TRUE,
 249          'size' => 'tiny',
 250          'not null' => TRUE,
 251          'default' => 0,
 252        ),
 253      ),
 254      'primary key' => array('nid', 'eid'),
 255    );
 256  
 257    $schema['webform_roles'] = array(
 258      'description' => 'Holds access information regarding which roles are allowed to submit which webform nodes. Does not prevent access to the webform node entirely, use the {node_access} table for that purpose.',
 259      'fields' => array(
 260        'nid' => array(
 261          'description' => 'The node identifier of a webform.',
 262          'type' => 'int',
 263          'unsigned' => TRUE,
 264          'not null' => TRUE,
 265          'default' => 0,
 266        ),
 267        'rid' => array(
 268          'description' => 'The role identifier.',
 269          'type' => 'int',
 270          'unsigned' => TRUE,
 271          'not null' => TRUE,
 272          'default' => 0,
 273        ),
 274      ),
 275      'primary key' => array('nid', 'rid'),
 276    );
 277  
 278    $schema['webform_submissions'] = array(
 279      'description' => 'Holds general information about submissions outside of field values.',
 280      'fields' => array(
 281        'sid' => array(
 282          'description' => 'The unique identifier for this submission.',
 283          'type' => 'serial',
 284          'unsigned' => TRUE,
 285          'not null' => TRUE,
 286        ),
 287        'nid' => array(
 288          'description' => 'The node identifier of a webform.',
 289          'type' => 'int',
 290          'unsigned' => TRUE,
 291          'not null' => TRUE,
 292          'default' => 0,
 293        ),
 294        'uid' => array(
 295          'description' => 'The id of the user that completed this submission.',
 296          'type' => 'int',
 297          'unsigned' => TRUE,
 298          'not null' => TRUE,
 299          'default' => 0,
 300        ),
 301        'is_draft' => array(
 302           'description' => 'Is this a draft of the submission?',
 303           'type' => 'int',
 304           'size' => 'tiny',
 305           'not null' => TRUE,
 306           'default' => 0,
 307        ),
 308        'submitted' => array(
 309          'description' => 'Timestamp of when the form was submitted.',
 310          'type' => 'int',
 311          'not null' => TRUE,
 312          'default' => 0,
 313        ),
 314        'remote_addr' => array(
 315          'description' => 'The IP address of the user that submitted the form.',
 316          'type' => 'varchar',
 317          'length' => 128,
 318        ),
 319      ),
 320      'primary key' => array('sid'),
 321      'unique keys' => array(
 322        'sid_nid' => array('sid', 'nid'),
 323      ),
 324      'indexes' => array(
 325        'nid_uid_sid' => array('nid', 'uid', 'sid'),
 326        'nid_sid' => array('nid', 'sid'),
 327      ),
 328    );
 329  
 330    $schema['webform_submitted_data'] = array(
 331      'description' => 'Stores all submitted field data for webform submissions.',
 332      'fields' => array(
 333        'nid' => array(
 334          'description' => 'The node identifier of a webform.',
 335          'type' => 'int',
 336          'unsigned' => TRUE,
 337          'not null' => TRUE,
 338          'default' => 0,
 339        ),
 340        'sid' => array(
 341          'description' => 'The unique identifier for this submission.',
 342          'type' => 'int',
 343          'unsigned' => TRUE,
 344          'not null' => TRUE,
 345          'default' => 0,
 346        ),
 347        'cid' => array(
 348          'description' => 'The identifier for this component within this node, starts at 0 for each node.',
 349          'type' => 'int',
 350          'size' => 'small',
 351          'unsigned' => TRUE,
 352          'not null' => TRUE,
 353          'default' => 0,
 354        ),
 355        'no' => array(
 356          'description' => 'Usually this value is 0, but if a field has multiple values (such as a time or date), it may require multiple rows in the database.',
 357          'type' => 'varchar',
 358          'length' => 128,
 359          'not null' => TRUE,
 360          'default' => '0',
 361        ),
 362        'data' => array(
 363          'description' => 'The submitted value of this field, may be serialized for some components.',
 364          'type' => 'text',
 365          'size' => 'medium',
 366          'not null' => TRUE,
 367        ),
 368      ),
 369      'primary key' => array('nid', 'sid', 'cid', 'no'),
 370      'indexes' => array(
 371        'nid' => array('nid'),
 372        'sid_nid' => array('sid', 'nid'),
 373      ),
 374    );
 375  
 376    $schema['webform_last_download'] = array(
 377     'description' => 'Stores last submission number per user download.',
 378      'fields' => array(
 379        'nid' => array(
 380          'description' => 'The node identifier of a webform.',
 381          'type' => 'int',
 382          'unsigned' => TRUE,
 383          'not null' => TRUE,
 384          'default' => 0,
 385        ),
 386        'uid' => array(
 387         'description' => 'The user identifier.',
 388          'type' => 'int',
 389          'unsigned' => TRUE,
 390          'not null' => TRUE,
 391          'default' => 0,
 392        ),
 393       'sid' => array(
 394          'description' => 'The last downloaded submission number.',
 395          'type' => 'int',
 396          'unsigned' => TRUE,
 397          'not null' => TRUE,
 398          'default' => 0,
 399        ),
 400       'requested' => array(
 401          'description' => 'Timestamp of last download request.',
 402          'type' => 'int',
 403          'unsigned' => TRUE,
 404          'not null' => TRUE,
 405          'default' => 0,
 406        ),
 407      ),
 408      'primary key' => array('nid', 'uid'),
 409    );
 410  
 411    return $schema;
 412  }
 413  
 414  /**
 415   * Implements hook_install().
 416   */
 417  function webform_install() {
 418    module_load_include('inc', 'node', 'content_types');
 419    db_query("UPDATE {system} SET weight = -1 WHERE name = 'webform' AND type = 'module'");
 420    drupal_install_schema('webform');
 421  
 422    // Optionally create the default webform type.
 423    if (variable_get('webform_install_create_content_type', TRUE)) {
 424      $webform_type = array(
 425        'type' => 'webform',
 426        'name' => st('Webform'),
 427        'module' => 'node',
 428        'description' => st('Create a new form or questionnaire accessible to users. Submission results and statistics are recorded and accessible to privileged users.'),
 429        'custom' => TRUE,
 430        'modified' => TRUE,
 431        'locked' => FALSE,
 432      );
 433      $webform_type = (object) _node_type_set_defaults($webform_type);
 434      node_type_save($webform_type);
 435    }
 436  }
 437  
 438  /**
 439   * Implements hook_uninstall().
 440   */
 441  function webform_uninstall() {
 442    // Unset webform variables.
 443    variable_del('webform_node_types');
 444    variable_del('webform_node_types_primary');
 445    variable_del('webform_use_cookies');
 446    variable_del('webform_default_from_address');
 447    variable_del('webform_default_from_name');
 448    variable_del('webform_default_subject');
 449    variable_del('webform_default_format');
 450    variable_del('webform_format_override');
 451    variable_del('webform_csv_delimiter');
 452    variable_del('webform_allowed_tags');
 453    variable_del('webform_blocks');
 454  
 455    $component_list = array();
 456    $path = drupal_get_path('module', 'webform') . '/components';
 457    $files = file_scan_directory($path, '^.*\.inc$');
 458    foreach ($files as $filename => $file) {
 459      variable_del('webform_enable_' . $file->name, 1);
 460    }
 461  
 462    // Delete uploaded files.
 463    $filepath = file_create_path('webform');
 464    _webform_recursive_delete($filepath);
 465  
 466    // Drop tables.
 467    drupal_uninstall_schema('webform');
 468  }
 469  
 470  /**
 471   * Implements hook_requirements().
 472   */
 473  function webform_requirements($phase) {
 474    $requirements = array();
 475    $t = get_t();
 476  
 477    if (version_compare(VERSION, '6.16') < 0) {
 478      $requirements['webform_drupal_version'] = array(
 479        'title' => $t('Webform'),
 480        'value' => VERSION,
 481        'severity' => REQUIREMENT_ERROR,
 482        'description' => $t('Webform requires at least version @version of Drupal core.', array('@version' => '6.16')),
 483      );
 484    }
 485  
 486    return $requirements;
 487  }
 488  
 489  /**
 490   * Set the minimum upgrade version.
 491   *
 492   * This should allow updates from any 2.x version of Webform (for D5 or D6),
 493   * but prevent updates from any version prior to Webform 1.10.
 494   */
 495  function webform_update_last_removed() {
 496    return 20;
 497  }
 498  
 499  /**
 500   * Upgrade to Drupal 6. Convert submissions sid column to auto-increment.
 501   */
 502  function webform_update_6001() {
 503    $ret = array();
 504    // Keys must be dropped before altering the column.
 505    db_drop_primary_key($ret, 'webform_submissions');
 506    db_drop_unique_key($ret, 'webform_submissions', 'sid_nid');
 507  
 508    // Alter to a primary key and add the unique key back.
 509    db_change_field($ret, 'webform_submissions', 'sid', 'sid', array('type' => 'serial', 'not null' => TRUE), array('primary key' => array('sid')));
 510    db_add_unique_key($ret, 'webform_submissions', 'sid_nid', array('sid', 'nid'));
 511    return $ret;
 512  }
 513  
 514  /**
 515   * Increase the size of the component instance name.
 516   */
 517  function webform_update_6200() {
 518    $ret = array();
 519    db_change_field($ret, 'webform_component', 'name', 'name', array('type' => 'varchar', 'length' => 255, 'default' => 'NULL'));
 520    return $ret;
 521  }
 522  
 523  /**
 524   * Add a column for email to the webform_component table.
 525   */
 526  function webform_update_6201() {
 527    $ret = array();
 528  
 529    // This update will already be run as webform_update_5201 on Drupal 5.
 530    if (db_column_exists('webform_component', 'email')) {
 531      return $ret;
 532    }
 533  
 534    db_add_field($ret, 'webform_component', 'email', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
 535    $ret[] = update_sql('UPDATE {webform_component} SET email = 1');
 536  
 537    return $ret;
 538  }
 539  
 540  /**
 541   * Per-webform submission access control based on roles.
 542   */
 543  function webform_update_6202() {
 544    $ret = array();
 545  
 546    // This update will already be run as webform_update_5202 on Drupal 5.
 547    if (db_table_exists('webform_roles')) {
 548      return $ret;
 549    }
 550  
 551    db_create_table($ret, 'webform_roles', array(
 552      'description' => 'Holds access information regarding which roles are allowed to submit which webform nodes. Does not prevent access to the webform node entirely, use the {node_access} table for that purpose.',
 553      'fields' => array(
 554        'nid' => array(
 555          'description' => 'The node identifier of a webform.',
 556          'type' => 'int',
 557          'unsigned' => TRUE,
 558          'not null' => TRUE,
 559          'default' => 0,
 560        ),
 561        'rid' => array(
 562          'description' => 'The role identifier.',
 563          'type' => 'int',
 564          'unsigned' => TRUE,
 565          'not null' => TRUE,
 566          'default' => 0,
 567        ),
 568      ),
 569      'primary key' => array('nid', 'rid'),
 570    ));
 571  
 572    $result = db_query("SELECT nid FROM {node} WHERE type = 'webform'");
 573    while ($node = db_fetch_object($result)) {
 574      db_query("INSERT INTO {webform_roles} (nid, rid) VALUES (%d, 1)", $node->nid);
 575      db_query("INSERT INTO {webform_roles} (nid, rid) VALUES (%d, 2)", $node->nid);
 576    }
 577  
 578    return $ret;
 579  }
 580  
 581  /**
 582   * Cleanup filtering values used by the file component.
 583   *
 584   * Previously, file extensions were saved by category, exactly as the FormAPI
 585   * returned to the submit handler. All extensions are now stored in a single
 586   * array, including only valid extensions.
 587   */
 588  function webform_update_6203() {
 589    $ret = array();
 590  
 591    // This update will already be run as webform_update_5203 on Drupal 5.
 592  
 593    $result = db_query("SELECT nid, cid, extra FROM {webform_component} WHERE type = 'file'");
 594    while ($component = db_fetch_object($result)) {
 595      $extra = unserialize($component->extra);
 596      $extensions = array();
 597  
 598      // Sanity check, set some defaults if no filtering is in place.
 599      if (!isset($extra['filtering']['types'])) {
 600        $extra['filtering']['types'] = array(
 601          'webimages' => drupal_map_assoc(array('png', 'gif', 'jpg')),
 602        );
 603      }
 604      // Or if filtering has already been updated, skip this update.
 605      elseif (!isset($extra['filtering']['types']['webimages'])) {
 606        continue;
 607      }
 608  
 609      // Defined types.
 610      foreach ($extra['filtering']['types'] as $category => $category_extensions) {
 611        foreach ((array)$category_extensions as $extension) {
 612          if (!is_numeric($extension)) {
 613            $extensions[] = $extension;
 614          }
 615        }
 616      }
 617  
 618      // Additional types.
 619      $additional_extensions = explode(',', $extra['filtering']['addextensions']);
 620      foreach ($additional_extensions as $extension) {
 621        $clean_extension = drupal_strtolower(trim($extension));
 622        if (!empty($clean_extension) && !in_array($clean_extension, $extensions)) {
 623          $extensions[] = $clean_extension;
 624        }
 625      }
 626  
 627      $extra['filtering']['types'] = $extensions;
 628      db_query("UPDATE {webform_component} SET extra = '%s' WHERE nid = %d AND cid = %d", serialize($extra), $component->nid, $component->cid);
 629    }
 630  
 631    return $ret;
 632  }
 633  
 634  /**
 635   * Set all files to permanent status uploaded by Webform.
 636   */
 637  function webform_update_6204() {
 638    $ret = array();
 639    $ret[] = update_sql("UPDATE {files} SET status = 1 WHERE filepath LIKE '" . file_directory_path() . "/webform/%'");
 640    return $ret;
 641  }
 642  
 643  /**
 644   * Schema fixes to make Drupal 5 upgrades identical to clean Drupal 6 installs.
 645   */
 646  function webform_update_6205() {
 647    $ret = array();
 648  
 649    // Remove disp-width and default from webform.nid.
 650    db_drop_primary_key($ret, 'webform');
 651    db_change_field($ret, 'webform', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('nid')));
 652  
 653    // Set not null property on webform.confirmation.
 654    db_change_field($ret, 'webform', 'confirmation', 'confirmation', array('type' => 'text', 'not null' => TRUE));
 655  
 656    // Set size to tiny, remove disp-width on webform.submit_limit.
 657    db_change_field($ret, 'webform', 'submit_limit', 'submit_limit', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => -1));
 658  
 659    // Set default value to -1, remove disp-width on webform.submit_interval.
 660    db_change_field($ret, 'webform', 'submit_interval', 'submit_interval', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
 661  
 662    // Set not null property on webform.additional_validate.
 663    db_change_field($ret, 'webform', 'additional_validate', 'additional_validate', array('type' => 'text', 'not null' => TRUE));
 664  
 665    // Set not null property on webform.additional_submit.
 666    db_change_field($ret, 'webform', 'additional_submit', 'additional_submit', array('type' => 'text', 'not null' => TRUE));
 667  
 668    // Set not null property, default on webform_component.name.
 669    db_change_field($ret, 'webform_component', 'name', 'name', array('type' => 'varchar', 'length' => 255));
 670  
 671    // Set not null property on webform_component.value.
 672    db_change_field($ret, 'webform_component', 'value', 'value', array('type' => 'text', 'not null' => TRUE));
 673  
 674    // Set not null property on webform_component.extra.
 675    db_change_field($ret, 'webform_component', 'extra', 'extra', array('type' => 'text', 'not null' => TRUE));
 676  
 677    // Set column size, disp-width on webform_component.mandatory.
 678    db_change_field($ret, 'webform_component', 'mandatory', 'mandatory', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
 679  
 680    // Set column size, disp-width, not null property on webform_component.weight.
 681    db_change_field($ret, 'webform_component', 'weight', 'weight', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
 682  
 683    // Set unsigned, not null property on webform_submissions.sid.
 684    db_drop_unique_key($ret, 'webform_submissions', 'sid_nid');
 685    db_change_field($ret, 'webform_submissions', 'sid', 'sid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
 686    db_drop_primary_key($ret, 'webform_submissions');
 687    db_change_field($ret, 'webform_submissions', 'sid', 'sid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('sid'), 'unique keys' => array('sid_nid' => array('sid', 'nid'))));
 688  
 689    // Temporarily drop all keys from the webform_submitted_data table for changes.
 690    db_drop_primary_key($ret, 'webform_submitted_data');
 691    db_drop_index($ret, 'webform_submitted_data', 'nid');
 692    db_drop_index($ret, 'webform_submitted_data', 'sid_nid');
 693  
 694    // Set unsigned, size on webform_submitted_data.no.
 695    db_change_field($ret, 'webform_submitted_data', 'no', 'no', array('type' => 'int', 'unsigned' => TRUE, 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
 696  
 697    // Set size, not null property on webform_submitted_data.data.
 698    db_change_field($ret, 'webform_submitted_data', 'data', 'data', array('type' => 'text', 'size' => 'medium', 'not null' => TRUE));
 699  
 700    // Set correct keys.
 701    db_add_primary_key($ret, 'webform_submitted_data', array('nid', 'sid', 'cid', 'no'));
 702    db_add_index($ret, 'webform_submitted_data', 'nid', array('nid'));
 703    db_add_index($ret, 'webform_submitted_data', 'sid_nid', array('sid', 'nid'));
 704  
 705    return $ret;
 706  }
 707  
 708  /**
 709   * Add a separate column for confirmation message input format.
 710   */
 711  function webform_update_6301() {
 712    $ret = array();
 713  
 714    // Safety check to prevent re-adding existing column.
 715    if (db_column_exists('webform', 'confirmation_format')) {
 716      return $ret;
 717    }
 718  
 719    db_add_field($ret, 'webform', 'confirmation_format', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
 720    $result = db_query("SELECT n.nid, nr.format FROM {node} n INNER JOIN {node_revisions} nr ON n.vid = nr.vid WHERE n.type = 'webform'");
 721    while ($node = db_fetch_object($result)) {
 722      db_query('UPDATE {webform} SET confirmation_format = %d WHERE nid = %d', $node->format, $node->nid);
 723    }
 724  
 725    return $ret;
 726  }
 727  
 728  /**
 729   * Convert node-level e-mail settings to new webform_emails table.
 730   */
 731  function webform_update_6302() {
 732    $ret = array();
 733  
 734    // Safety check to prevent recreating the webform_emails table.
 735    if (db_table_exists('webform_emails')) {
 736      return $ret;
 737    }
 738  
 739    $table = array(
 740      'fields' => array(
 741        'nid' => array(
 742          'type' => 'int',
 743          'unsigned' => TRUE,
 744          'not null' => TRUE,
 745          'default' => 0,
 746        ),
 747        'eid' => array(
 748          'type' => 'int',
 749          'unsigned' => TRUE,
 750          'size' => 'small',
 751          'not null' => TRUE,
 752          'default' => 0,
 753        ),
 754        'email' => array(
 755          'type' => 'text',
 756          'not null' => FALSE,
 757        ),
 758        'subject' => array(
 759          'type' => 'varchar',
 760          'length' => '255',
 761          'not null' => FALSE,
 762        ),
 763        'from_name' => array(
 764          'type' => 'varchar',
 765          'length' => '255',
 766          'not null' => FALSE,
 767        ),
 768        'from_address' => array(
 769          'type' => 'varchar',
 770          'length' => '255',
 771          'not null' => FALSE,
 772        ),
 773        'template' => array(
 774          'type' => 'text',
 775          'not null' => FALSE,
 776        )
 777      ),
 778      'primary key' => array('nid', 'eid'),
 779    );
 780  
 781    db_create_table($ret, 'webform_emails', $table);
 782  
 783    // Move over data from the webform table.
 784    $result = db_query("SELECT w.nid, w.email, w.email_from_name, w.email_from_address, w.email_subject, wc.cid, wc.extra FROM {webform} w LEFT JOIN {webform_component} wc ON w.nid = wc.nid AND type IN ('select', 'hidden', 'email') ORDER BY nid");
 785    $nid = 0;
 786    while ($row = db_fetch_object($result)) {
 787      // Insert an e-mail settings row for the default e-mail.
 788      if ($row->nid != $nid) {
 789        $nid = $row->nid;
 790        $eid = 0;
 791        if (!empty($row->email)) {
 792          $eid++;
 793          db_query("INSERT INTO {webform_emails} (nid, eid, email, subject, from_name, from_address, template) VALUES (%d, %d, '%s', '%s', '%s', '%s', 'default')", $nid, $eid, $row->email, $row->email_subject, $row->email_from_name, $row->email_from_address);
 794        }
 795      }
 796  
 797      // Check for an e-mail based on a component.
 798      if ($row->extra) {
 799        $extra = unserialize($row->extra);
 800        if ($extra['email']) {
 801          $eid++;
 802          unset($extra['email']);
 803          db_query("INSERT INTO {webform_emails} (nid, eid, email, subject, from_name, from_address, template) VALUES (%d, %d, '%s', '%s', '%s', '%s', 'default')", $nid, $eid, $row->cid, $row->email_subject, $row->email_from_name, $row->email_from_address);
 804          db_query("UPDATE {webform_component} SET extra = '%s' WHERE nid = %d AND cid = %d", serialize($extra), $row->nid, $row->cid);
 805        }
 806      }
 807    }
 808  
 809    // Remove columns from webform table.
 810    db_drop_field($ret, 'webform', 'email');
 811    db_drop_field($ret, 'webform', 'email_from_name');
 812    db_drop_field($ret, 'webform', 'email_from_address');
 813    db_drop_field($ret, 'webform', 'email_subject');
 814  
 815    return $ret;
 816  }
 817  
 818  /**
 819   * Add the submit_notice field and update all existing webforms to the 2.x previous submissions notice default.
 820   */
 821  function webform_update_6303() {
 822    $ret = array();
 823    db_add_field($ret, 'webform', 'submit_notice', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
 824    $ret[] = update_sql("UPDATE {webform} SET submit_notice = 1 WHERE submit_notice = 0");
 825    return $ret;
 826  }
 827  
 828  /**
 829   * Convert the webform content type to be owned by Node module.
 830   */
 831  function webform_update_6304() {
 832    $ret = array();
 833    $ret[] = update_sql("UPDATE {node_type} SET module = 'node', custom = 1, modified = 1, locked = 0 WHERE type = 'webform'");
 834    if (!db_affected_rows()) {
 835      $ret[] = update_sql("INSERT INTO {node_type} (type, name, module, description, help, has_title, title_label, has_body, body_label, min_word_count, custom, modified, locked, orig_type) VALUES ('webform', 'Webform', 'node', 'Create a new form or questionnaire accessible to users. Submission results and statistics are recorded and accessible to privileged users.', '', 1, 'Title', 1, 'Body', 0, 1, 1, 0, 'webform')");
 836    }
 837  
 838    // This variable for some reason must be set manually.
 839    variable_set('webform_node_types', array('webform'));
 840  
 841    return $ret;
 842  }
 843  
 844  /**
 845   * Migrate the renamed permissions. Add separate permissions for delete.
 846   */
 847  function webform_update_6305() {
 848    $ret = array();
 849  
 850    $updated_permissions = array(
 851      'create webforms' => array('add webform content'),
 852      'edit own webforms' => array('edit own webform content', 'delete own webform content'),
 853      'edit webforms' => array('edit any webform content', 'delete any webform content'),
 854      'access webform results' => array('access all webform results'),
 855      'edit webform submissions' => array('edit all webform submissions'),
 856      'edit own webform submissions' => array('edit own webform submissions', 'delete own webform submissions'),
 857      'clear webform results' => array('delete all webform submissions'),
 858    );
 859  
 860    $result = db_query("SELECT * FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid");
 861    while ($role = db_fetch_object($result)) {
 862      $role->perm = drupal_map_assoc(explode(', ', db_escape_string($role->perm)));
 863      foreach ($updated_permissions as $old => $new) {
 864        if (isset($role->perm[$old])) {
 865          unset($role->perm[$old]);
 866          foreach ($new as $perm) {
 867            $role->perm[$perm] = $perm;
 868          }
 869        }
 870      }
 871      $ret[] = update_sql("UPDATE {permission} SET perm = '" . implode(', ', $role->perm) . "' WHERE rid = " . $role->rid);
 872    }
 873  
 874    return $ret;
 875  }
 876  
 877  /**
 878   * Add the ability to save as draft.
 879   */
 880  function webform_update_6306() {
 881    $ret = array();
 882    db_add_field($ret, 'webform', 'allow_draft', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
 883    db_add_field($ret, 'webform_submissions', 'is_draft', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
 884    return $ret;
 885  }
 886  
 887  /**
 888   * Convert the file component to use only FIDs instead of serialized arrays.
 889   */
 890  function webform_update_6307() {
 891    $ret = array();
 892  
 893    $result = db_query("SELECT d.*, s.uid, s.submitted FROM {webform_submitted_data} d INNER JOIN {webform_component} c ON d.cid = c.cid AND d.nid = c.nid AND c.type = 'file' INNER JOIN {webform_submissions} s ON d.sid = s.sid");
 894    while ($row = db_fetch_object($result)) {
 895      $file = @unserialize($row->data);
 896      // File name should always exist, even when upgrading from Drupal 5.
 897      if ($file && isset($file['filename'])) {
 898        // Create an entry in the files table if needed.
 899        if (!isset($file['fid'])) {
 900          db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, 1, %d)", $row->uid, $file['filename'], $file['filepath'], $file['filemime'], $file['filesize'], $row->submitted);
 901          $fid = db_last_insert_id('files', 'fid');
 902        }
 903        else {
 904          $fid = $file['fid'];
 905        }
 906        // Update the submitted data with the FID.
 907        db_query("UPDATE {webform_submitted_data} SET data = '%d' WHERE nid = %d AND sid = %d AND cid = %d", $fid, $row->nid, $row->sid, $row->cid);
 908      }
 909      // Insert an empty entry, now just an empty string.
 910      else {
 911        db_query("UPDATE {webform_submitted_data} SET data = '' WHERE nid = %d AND sid = %d AND cid = %d", $row->nid, $row->sid, $row->cid);
 912      }
 913    }
 914  
 915    $ret[] = array('success' => TRUE, 'query' => t('Updated file components to use numeric file IDs in the submitted values.'));
 916  
 917    return $ret;
 918  }
 919  
 920  /**
 921   * Convert "Include in e-mail" from the component-level to a per e-mail setting.
 922   */
 923  function webform_update_6308() {
 924    $ret = array();
 925  
 926    // Add the new column to the e-mail table.
 927    db_add_field($ret, 'webform_emails', 'excluded_components', array('type' => 'text', 'not null' => TRUE, 'initial' => ''));
 928  
 929    // Build up our EXCLUSION lists, finding all components not in e-mails.
 930    $result = db_query("SELECT nid, cid FROM {webform_component} WHERE email = 0 ORDER BY nid");
 931    $nid = 0;
 932    $excluded_components = array();
 933    while ($row = db_fetch_object($result)) {
 934      if ($nid != $row->nid) {
 935        if (!empty($excluded_components)) {
 936          db_query("UPDATE {webform_emails} SET excluded_components = '%s' WHERE nid = %d", implode(',', $excluded_components), $nid);
 937        }
 938        $nid = $row->nid;
 939        $excluded_components = array();
 940      }
 941      $excluded_components[] = $row->cid;
 942    }
 943  
 944    // One last query for the last form in the list.
 945    if (!empty($excluded_components)) {
 946      db_query("UPDATE {webform_emails} SET excluded_components = '%s' WHERE nid = %d", implode(',', $excluded_components), $nid);
 947    }
 948  
 949    db_drop_field($ret, 'webform_component', 'email');
 950  
 951    return $ret;
 952  }
 953  
 954  /**
 955   * Fix permissions for all roles by adding an additional space after comma.
 956   */
 957  function webform_update_6309() {
 958    $ret = array();
 959  
 960    $result = db_query("SELECT r.rid, p.perm FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid");
 961    while ($role = db_fetch_object($result)) {
 962      $perms = explode(',', $role->perm);
 963      foreach ($perms as $id => $perm) {
 964        $perms[$id] = db_escape_string(trim($perm));
 965      }
 966      $ret[] = update_sql("UPDATE {permission} SET perm = '" . implode(', ', $perms) . "' WHERE rid = " . $role->rid);
 967    }
 968  
 969    return $ret;
 970  }
 971  
 972  /**
 973   * Add the redirect_url field and update existing webforms to use it.
 974   */
 975  function webform_update_6310() {
 976    $ret = array();
 977  
 978    // Safety check to prevent re-adding existing column.
 979    if (db_column_exists('webform', 'redirect_url')) {
 980      return $ret;
 981    }
 982  
 983    // Add the new redirect_url column.
 984    db_add_field($ret, 'webform', 'redirect_url', array('type' => 'varchar', 'length' => '255'));
 985  
 986    // If the webform is using the confirmation field as a redirect then move it
 987    // to the new redirect_url field.
 988    $result = db_query("SELECT nid, confirmation FROM {webform}");
 989    while ($row = db_fetch_object($result)) {
 990      $confirmation = trim(strip_tags($row->confirmation, '<front>'));
 991      if (valid_url($confirmation, TRUE) || preg_match('/^internal:/', $confirmation)) {
 992        $redirect_url = preg_replace('/^internal:/', '', $confirmation);
 993        db_query("UPDATE {webform} SET redirect_url = '%s' WHERE nid = %d", $redirect_url, $row->nid);
 994        db_query("UPDATE {webform} SET confirmation = '' WHERE nid = %d", $row->nid);
 995      }
 996      elseif (preg_match('/^message:/', $confirmation)) {
 997        $message = preg_replace('/^message:/', '', $confirmation);
 998        db_query("UPDATE {webform} SET redirect_url = '%s' WHERE nid = %d", 'node/' . $row->nid, $row->nid);
 999        db_query("UPDATE {webform} SET confirmation = '%s' WHERE nid = %d", $message, $row->nid);
1000      }
1001    }
1002  
1003    return $ret;
1004  }
1005  
1006  /**
1007   * Convert the "no" column to be a varchar column instead of an integer.
1008   */
1009  function webform_update_6311() {
1010    $ret = array();
1011  
1012    // Change the column.
1013    db_drop_primary_key($ret, 'webform_submitted_data');
1014    db_change_field($ret, 'webform_submitted_data', 'no', 'no', array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => '0'), array());
1015    db_add_primary_key($ret, 'webform_submitted_data', array('nid', 'sid', 'cid', 'no'));
1016  
1017    // Update date components.
1018    $ret[] = update_sql("UPDATE {webform_submitted_data} SET no = 'month' WHERE no = '0' AND (nid, cid) IN (SELECT nid, cid FROM {webform_component} WHERE type = 'date')");
1019    $ret[] = update_sql("UPDATE {webform_submitted_data} SET no = 'day' WHERE no = '1' AND (nid, cid) IN (SELECT nid, cid FROM {webform_component} WHERE type = 'date')");
1020    $ret[] = update_sql("UPDATE {webform_submitted_data} SET no = 'year' WHERE no = '2' AND (nid, cid) IN (SELECT nid, cid FROM {webform_component} WHERE type = 'date')");
1021  
1022    // Update time components.
1023    $ret[] = update_sql("UPDATE {webform_submitted_data} SET no = 'hour' WHERE no = '0' AND (nid, cid) IN (SELECT nid, cid FROM {webform_component} WHERE type = 'time')");
1024    $ret[] = update_sql("UPDATE {webform_submitted_data} SET no = 'minute' WHERE no = '1' AND (nid, cid) IN (SELECT nid, cid FROM {webform_component} WHERE type = 'time')");
1025    $ret[] = update_sql("UPDATE {webform_submitted_data} SET no = 'ampm' WHERE no = '2' AND (nid, cid) IN (SELECT nid, cid FROM {webform_component} WHERE type = 'time')");
1026  
1027    // Updating of select and grid components is done in following updates.
1028  
1029    return $ret;
1030  }
1031  
1032  /**
1033   * Convert select options to use numeric keys if none are manually specified.
1034   */
1035  function webform_update_6312() {
1036    $ret = array();
1037  
1038    $result = db_query("SELECT * FROM {webform_component} WHERE type = 'select'");
1039    while ($row = db_fetch_object($result)) {
1040      $extra = unserialize($row->extra);
1041      $lines = explode("\n", $extra['items']);
1042  
1043      // Get a list of items that have manual keys or no keys at all.
1044      $keys = array();
1045      $values = array();
1046      foreach ($lines as $line) {
1047        $line = rtrim($line, "\r\n");
1048        if (strlen($line) == 0) {
1049          continue;
1050        }
1051        $matches = array();
1052        if (preg_match('/^\<([^>]*)\>$/', $line, $matches)) {
1053          $keys[] = '<group>';
1054          $values[] = $line;
1055        }
1056        elseif (preg_match('/^([^|]+)\|(.*)$/', $line, $matches)) {
1057          $keys[] = $matches[1];
1058          $values[] = $matches[2];
1059        }
1060        else {
1061          $keys[] = '<unknown>';
1062          $values[] = $line;
1063        }
1064      }
1065  
1066      // Assign new keys to items that have none.
1067      $new_key = 0;
1068      $new_keys = array();
1069      $items = '';
1070      foreach ($keys as $n => $key) {
1071        if ($key == '<group>') {
1072          $items .= $values[$n] . "\n";
1073        }
1074        elseif ($key == '<unknown>') {
1075          while (in_array($new_key, $keys, TRUE) || in_array($new_key, $new_keys, TRUE)) {
1076            $new_key++;
1077          }
1078          $new_keys[$n] = $new_key;
1079          $items .= $new_key . '|' . $values[$n] . "\n";
1080        }
1081        else {
1082          $items .= $key . '|' . $values[$n] . "\n";
1083        }
1084      }
1085  
1086      // While we're here, get rid of the 'Y' value for options.
1087      foreach ($extra as $key => $value) {
1088        if ($value === 'Y') {
1089          $extra[$key] = '1';
1090        }
1091        elseif ($value === 'N') {
1092          $extra[$key] = 0;
1093        }
1094      }
1095  
1096      // Update the component.
1097      $extra['items'] = $items;
1098      db_query("UPDATE {webform_component} SET extra = '%s' WHERE nid = %d AND cid = %d", serialize($extra), $row->nid, $row->cid);
1099  
1100      // Update the saved results.
1101      foreach ($new_keys as $delta => $new_key) {
1102        db_query("UPDATE {webform_submitted_data} SET data = '%s' WHERE nid = %d AND cid = %d AND data = '%s'", $new_key, $row->nid, $row->cid, $values[$delta]);
1103      }
1104  
1105      // Delete empty rows, which are no longer stored for select lists.
1106      db_query("DELETE FROM {webform_submitted_data} WHERE data = '' AND nid = %d AND cid = %d");
1107    }
1108  
1109    return $ret;
1110  }
1111  
1112  /**
1113   * Create keys for all questions (which don't currently have keys at all),
1114   * create keys for all options that don't yet have any, and then convert the
1115   * existing data to use these keys.
1116   */
1117  function webform_update_6313() {
1118    $ret = array();
1119  
1120    $result = db_query("SELECT * FROM {webform_component} WHERE type = 'grid'");
1121    while ($row = db_fetch_object($result)) {
1122      $extra = unserialize($row->extra);
1123      $lines = explode("\n", $extra['options']);
1124  
1125      // Get a list of items that have manual keys or no keys at all.
1126      $keys = array();
1127      $values = array();
1128      foreach ($lines as $line) {
1129        $line = rtrim($line, "\r\n");
1130        if (strlen($line) == 0) {
1131          continue;
1132        }
1133        $matches = array();
1134        if (preg_match('/^([^|]+)\|(.*)$/', $line, $matches)) {
1135          $keys[] = $matches[1];
1136          $values[] = $matches[2];
1137        }
1138        else {
1139          $keys[] = '<unknown>';
1140          $values[] = $line;
1141        }
1142      }
1143  
1144      // Assign new keys to options that have none.
1145      $new_key = 0;
1146      $new_keys = array();
1147      $options = '';
1148      foreach ($keys as $n => $key) {
1149        if ($key == '<unknown>') {
1150          while (in_array($new_key, $keys, TRUE) || in_array($new_key, $new_keys, TRUE)) {
1151            $new_key++;
1152          }
1153          $new_keys[$n] = $new_key;
1154          $options .= $new_key . '|' . $values[$n] . "\n";
1155        }
1156        else {
1157          $options .= $key . '|' . $values[$n] . "\n";
1158        }
1159      }
1160      $extra['options'] = $options;
1161  
1162      // Assign question keys. This is easier since they don't have keys at all.
1163      $lines = explode("\n", $extra['questions']);
1164      $questions = array();
1165      foreach ($lines as $delta => $line) {
1166        $line = rtrim($line, "\r\n");
1167        if (strlen($line) == 0) {
1168          continue;
1169        }
1170        $questions[$delta] = $delta . '|' . $line;
1171      }
1172      $extra['questions'] = implode("\n", $questions);
1173  
1174      // While we're here, get rid of the 'Y' value for options.
1175      foreach ($extra as $key => $value) {
1176        if ($value === 'Y') {
1177          $extra[$key] = '1';
1178        }
1179        elseif ($value === 'N') {
1180          $extra[$key] = 0;
1181        }
1182      }
1183  
1184      // Update the component.
1185      db_query("UPDATE {webform_component} SET extra = '%s' WHERE nid = %d AND cid = %d", serialize($extra), $row->nid, $row->cid);
1186  
1187      // Convert the option values into keys if new ones were created.
1188      foreach ($new_keys as $delta => $new_key) {
1189        db_query("UPDATE {webform_submitted_data} SET data = '%s' WHERE nid = %d AND cid = %d AND data = '%s'", $new_key, $row->nid, $row->cid, $values[$delta]);
1190      }
1191  
1192      // Note: Converting the question values into keys is not necessary because
1193      // data was already stored based on the question position. Since we assigned
1194      // permanent keys based on position, all our keys are already accurate.
1195  
1196      // Delete empty rows, which are no longer stored for grids.
1197      db_query("DELETE FROM {webform_submitted_data} WHERE data = '' AND nid = %d AND cid = %d");
1198    }
1199  
1200    return $ret;
1201  }
1202  
1203  /**
1204   * Convert Dates and Times into using ISO 8601 strings instead of 3 rows.
1205   */
1206  function webform_update_6314() {
1207    $ret = array();
1208  
1209    // Note that we can't use webform_component_include(), because calls to
1210    // hook_webform_component_info() will fail if webform.module is disabled.
1211    drupal_load('module', 'webform');
1212    module_load_include('inc', 'webform', 'components/time');
1213    module_load_include('inc', 'webform', 'components/date');
1214  
1215    $result = db_query("SELECT c.type, c.extra, d.* FROM {webform_component} c INNER JOIN {webform_submitted_data} d ON c.nid = d.nid AND c.cid = d.cid WHERE c.type = 'time' OR c.type = 'date' ORDER BY d.sid, d.cid");
1216    $current_cid = NULL;
1217    $current_sid = NULL;
1218    while ($row = db_fetch_object($result)) {
1219      if ($current_cid != $row->cid || $current_sid != $row->sid) {
1220        $current_cid = $row->cid;
1221        $current_sid = $row->sid;
1222        $extra = unserialize($row->extra);
1223        $value = array();
1224      }
1225  
1226      $value[$row->no] = $row->data;
1227  
1228      // Update a complete date.
1229      if ($row->type == 'date' && array_key_exists('day', $value) && array_key_exists('month', $value) && array_key_exists('year', $value)) {
1230        $value = ($value['day'] && $value['month'] && $value['year']) ? webform_date_string($value, 'date') : '';
1231        db_query("UPDATE {webform_submitted_data} SET no = '0', data = '%s' WHERE sid = %d AND cid = %d AND no = 'day'", $value, $current_sid, $current_cid);
1232      }
1233  
1234      // Update a complete time.
1235      if ($row->type == 'time' && array_key_exists('hour', $value) && array_key_exists('minute', $value) && ($extra['hourformat'] == '24-hour' || array_key_exists('ampm', $value))) {
1236        if ($extra['hourformat'] == '12-hour') {
1237          $value = webform_time_convert($value, '24-hour');
1238        }
1239        $value = ($value['hour']) ? webform_date_string($value, 'time') : '';
1240        db_query("UPDATE {webform_submitted_data} SET no = '0', data = '%s' WHERE sid = %d AND cid = %d AND no = 'hour'", $value, $current_sid, $current_cid);
1241      }
1242    }
1243  
1244    // Remove all extra rows (which should just be day, minute, and ampm values).
1245    db_query("DELETE FROM {webform_submitted_data} WHERE no IN ('day', 'month', 'year', 'hour', 'minute', 'second', 'ampm')");
1246  
1247    $ret[] = array('success' => TRUE, 'query' => t('Updated date and time components to use ISO 8601 formatted strings in the submitted values.'));
1248  
1249    return $ret;
1250  }
1251  
1252  /**
1253   * Remove "daylight_savings" and the GMT option in "timezone".
1254   */
1255  function webform_update_6315() {
1256    $ret = array();
1257  
1258    $result = db_query("SELECT * FROM {webform_component} WHERE type IN ('date', 'time')");
1259    while ($row = db_fetch_object($result)) {
1260      $extra = unserialize($row->extra);
1261      if ($extra['timezone'] == 'gmt') {
1262        $extra['timezone'] = 'site';
1263      }
1264      unset($extra['check_daylight_savings']);
1265      db_query("UPDATE {webform_component} SET extra = '%s' WHERE nid = %d AND cid = %d", serialize($extra), $row->nid, $row->cid);
1266    }
1267  
1268    $ret[] = array('success' => TRUE, 'query' => t('Removed Webform-specific daylight savings handling, now provided by Date API module if available.'));
1269  
1270    return $ret;
1271  }
1272  
1273  /**
1274   * Remove the Webform Debug variable.
1275   */
1276  function webform_update_6316() {
1277    $ret = array();
1278    variable_del('webform_debug');
1279    $ret[] = array('success' => TRUE, 'query' => t('Removed the webform_debug variable which is no longer used.'));
1280    return $ret;
1281  }
1282  
1283  /**
1284   * Remove orphaned e-mail settings of nodes that have been deleted.
1285   */
1286  function webform_update_6317() {
1287    $ret = array();
1288    $ret[] = update_sql("DELETE FROM {webform_emails} WHERE nid NOT IN (SELECT nid FROM {node})");
1289    return $ret;
1290  }
1291  
1292  /**
1293   * Ensure that the confirmation format column is correctly using size = 'tiny'.
1294   */
1295  function webform_update_6318() {
1296    $ret = array();
1297    db_change_field($ret, 'webform', 'confirmation_format', 'confirmation_format', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
1298    return $ret;
1299  }
1300  
1301  /**
1302   * Add columns for e-mail HTML and attachment settings.
1303   */
1304  function webform_update_6319() {
1305    $ret = array();
1306    if (!db_column_exists('webform_emails', 'html')) {
1307      db_add_field($ret, 'webform_emails', 'html', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'default' => 0, 'not null' => TRUE));
1308      db_add_field($ret, 'webform_emails', 'attachments', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'default' => 0, 'not null' => TRUE));
1309    }
1310    return $ret;
1311  }
1312  
1313  /**
1314   * Set the default for the "submit_notice" column to 1.
1315   */
1316  function webform_update_6320() {
1317    $ret = array();
1318    db_change_field($ret, 'webform', 'submit_notice', 'submit_notice', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 1));
1319    return $ret;
1320  }
1321  
1322  /**
1323   * Add field for block feature and redirection setting.
1324   */
1325  function webform_update_6321() {
1326    $ret = array();
1327    db_add_field($ret, 'webform', 'block', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
1328    db_change_field($ret, 'webform', 'redirect_url', 'redirect_url', array('type' => 'varchar', 'length' => 255, 'default' => '<confirmation>'));
1329    update_sql("UPDATE {webform} SET redirect_url = '<confirmation>' WHERE redirect_url = '' OR redirect_url IS NULL");
1330    return $ret;
1331  }
1332  
1333  /**
1334   * Set additional_validate and additional_submit columns to allow NULL.
1335   */
1336  function webform_update_6322() {
1337    $ret = array();
1338    if (db_column_exists('webform', 'additional_validate')) {
1339      db_change_field($ret, 'webform', 'additional_validate', 'additional_validate', array('type' => 'text', 'not null' => FALSE));
1340      db_change_field($ret, 'webform', 'additional_submit', 'additional_submit', array('type' => 'text', 'not null' => FALSE));
1341    }
1342    return $ret;
1343  }
1344  
1345  /**
1346   * Add column for webform status (open or closed).
1347   */
1348  function webform_update_6323() {
1349    $ret = array();
1350    if (!db_column_exists('webform', 'status')) {
1351      db_add_field($ret, 'webform', 'status', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 1));
1352    }
1353    return $ret;
1354  }
1355  
1356  /**
1357   * Add the ability to auto-save as draft between pages.
1358   */
1359  function webform_update_6324() {
1360    $ret = array();
1361    db_add_field($ret, 'webform', 'auto_save', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
1362    return $ret;
1363  }
1364  
1365  /**
1366   * Remove orphaned and unnecessary rows in the webform table.
1367   */
1368  function webform_update_6325() {
1369    $ret = array();
1370    $result = db_query("SELECT nid FROM {webform} WHERE
1371      nid NOT IN
1372      (SELECT DISTINCT(w1.nid) FROM {webform} w1 INNER JOIN {webform_component} wc ON w1.nid = wc.nid)
1373      AND nid NOT IN
1374      (SELECT w2.nid FROM {webform} w2 INNER JOIN {node} n ON w2.nid = n.nid WHERE n.type = 'webform')"
1375    );
1376    $empty_nids = array();
1377    while ($row = db_fetch_object($result)) {
1378      $empty_nids[] = $row->nid;
1379    }
1380    if (!empty($empty_nids)) {
1381      $empty_list = implode(',', $empty_nids);
1382      $ret[] = update_sql("DELETE FROM {webform} WHERE nid in ($empty_list)");
1383    }
1384    return $ret;
1385  }
1386  
1387  /**
1388   * Add an index for nid_uid_sid to webform_submissions.
1389   */
1390  function webform_update_6326() {
1391    $ret = array();
1392    db_add_index($ret, 'webform_submissions', 'nid_uid_sid', array('nid', 'uid', 'sid'));
1393    return $ret;
1394  }
1395  
1396  /**
1397   * Remove unused Webform variables.
1398   */
1399  function webform_update_6327() {
1400    $ret = array();
1401    variable_del('node_types');
1402    variable_del('components');
1403    return $ret;
1404  }
1405  
1406  /**
1407   * Convert the Date component start and end year options to start and end date.
1408   */
1409  function webform_update_6328() {
1410    $ret = array();
1411  
1412    $result = db_query("SELECT * FROM {webform_component} WHERE type = 'date'");
1413    while ($component = db_fetch_array($result)) {
1414      $component['extra'] = unserialize($component['extra']);
1415      if (!isset($component['extra']['start_date']) && !isset($component['end_date'])) {
1416        foreach (array('year_start' => 'start_date', 'year_end' => 'end_date') as $key => $replacement) {
1417          $value = isset($component['extra'][$key]) ? trim($component['extra'][$key]) : '';
1418          // Relative years.
1419          if (preg_match('/[-+][ ]*[0-9]+/', $value)) {
1420            $component['extra'][$replacement] = ($value == 1) ? ($value . ' year') : ($value . ' years');
1421          }
1422          // Absolute years.
1423          elseif (is_numeric($value)) {
1424            $component['extra'][$replacement] = 'Dec 31 ' . $value;
1425          }
1426          unset($component['extra'][$key]);
1427        }
1428        $component['extra'] = serialize($component['extra']);
1429        drupal_write_record('webform_component', $component, array('nid', 'cid'));
1430      }
1431    }
1432  
1433    return $ret;
1434  }
1435  
1436  /**
1437   * Add webform_last_download table to store last downloaded sid per user.
1438   */
1439  function webform_update_6329() {
1440    // Safety check to prevent recreating the webform_last_download table.
1441    $ret = array();
1442    if (db_table_exists('webform_last_download')) {
1443      return $ret;
1444    }
1445  
1446    $schema['webform_last_download'] = array(
1447      'description' => 'Stores last submission number per user download.',
1448      'fields' => array(
1449        'nid' => array(
1450          'description' => 'The node identifier of a webform.',
1451          'type' => 'int',
1452          'unsigned' => TRUE,
1453          'not null' => TRUE,
1454          'default' => 0,
1455        ),
1456        'uid' => array(
1457          'description' => 'The user identifier.',
1458          'type' => 'int',
1459          'unsigned' => TRUE,
1460          'not null' => TRUE,
1461          'default' => 0,
1462        ),
1463        'sid' => array(
1464          'description' => 'The last downloaded submission number.',
1465          'type' => 'int',
1466          'unsigned' => TRUE,
1467          'not null' => TRUE,
1468          'default' => 0,
1469        ),
1470        'requested' => array(
1471          'description' => 'Timestamp of last download request.',
1472          'type' => 'int',
1473          'unsigned' => TRUE,
1474          'not null' => TRUE,
1475          'default' => 0,
1476        ),
1477      ),
1478      'primary key' => array('nid', 'uid'),
1479    );
1480  
1481    db_create_table($ret, 'webform_last_download', $schema['webform_last_download']);
1482  
1483    return $ret;
1484  }
1485  
1486  /**
1487   * Add additional columns for total submission limit.
1488   */
1489  function webform_update_6330() {
1490    $ret = array();
1491    if (!db_column_exists('webform', 'total_submit_limit')) {
1492      db_add_field($ret, 'webform', 'total_submit_limit', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
1493    }
1494  
1495    if (!db_column_exists('webform', 'total_submit_interval')) {
1496      db_add_field($ret, 'webform', 'total_submit_interval', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
1497    }
1498  
1499    return $ret;
1500  }
1501  
1502  /**
1503   * Add an index for nid_sid to webform_submissions.
1504   */
1505  function webform_update_6331() {
1506    // Even though we already have an index 'nid_uid_sid', adding the index for
1507    // 'nid_sid' saves us a tablesort on the node/x/webform-results page.
1508    $ret = array();
1509    db_add_index($ret, 'webform_submissions', 'nid_sid', array('nid', 'sid'));
1510    return $ret;
1511  }
1512  
1513  /**
1514   * Recursively delete all files and folders in the specified filepath, then
1515   * delete the containing folder.
1516   *
1517   * Note that this only deletes visible files with write permission
1518   *
1519   * @param string $path
1520   *   A filepath relative to file_directory_path
1521   */
1522  function _webform_recursive_delete($path) {
1523    if ($path && is_dir($path)) {
1524      $listing = $path . '/*';
1525      foreach (glob($listing) as $file) {
1526        if (is_file($file) === TRUE) {
1527          @unlink($file);
1528        }
1529        elseif (is_dir($file) === TRUE) {
1530          _webform_recursive_delete($file);
1531        }
1532      }
1533      @rmdir($path);
1534    }
1535  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7