| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |