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