webform.install 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. <?php
  2. /**
  3. * @file
  4. * Webform module install/schema hooks.
  5. */
  6. /**
  7. * Implements hook_schema().
  8. */
  9. function webform_schema() {
  10. $schema = array();
  11. $schema['webform'] = array(
  12. 'description' => 'Table for storing additional properties for webform nodes.',
  13. 'fields' => array(
  14. 'nid' => array(
  15. 'description' => 'The node identifier of a webform.',
  16. 'type' => 'int',
  17. 'unsigned' => TRUE,
  18. 'not null' => TRUE,
  19. ),
  20. 'confirmation' => array(
  21. 'description' => 'The confirmation message or URL displayed to the user after submitting a form.',
  22. 'type' => 'text',
  23. 'not null' => TRUE,
  24. ),
  25. 'confirmation_format' => array(
  26. 'description' => 'The {filter_format}.format of the confirmation message.',
  27. 'type' => 'varchar',
  28. 'length' => 255,
  29. 'not null' => FALSE,
  30. ),
  31. 'redirect_url' => array(
  32. 'description' => 'The URL a user is redirected to after submitting a form.',
  33. 'type' => 'varchar',
  34. 'length' => 255,
  35. 'default' => '<confirmation>',
  36. ),
  37. 'status' => array(
  38. 'description' => 'Boolean value of a webform for open (1) or closed (0).',
  39. 'type' => 'int',
  40. 'size' => 'tiny',
  41. 'not null' => TRUE,
  42. 'default' => 1,
  43. ),
  44. 'block' => array(
  45. 'description' => 'Boolean value for whether this form be available as a block.',
  46. 'type' => 'int',
  47. 'size' => 'tiny',
  48. 'not null' => TRUE,
  49. 'default' => 0,
  50. ),
  51. 'teaser' => array(
  52. 'description' => 'Boolean value for whether the entire form should be displayed on the teaser.',
  53. 'type' => 'int',
  54. 'size' => 'tiny',
  55. 'not null' => TRUE,
  56. 'default' => 0,
  57. ),
  58. 'allow_draft' => array(
  59. 'description' => 'Boolean value for whether submissions to this form be saved as a draft.',
  60. 'type' => 'int',
  61. 'size' => 'tiny',
  62. 'not null' => TRUE,
  63. 'default' => 0,
  64. ),
  65. 'auto_save' => array(
  66. 'description' => 'Boolean value for whether submissions to this form should be auto-saved between pages.',
  67. 'type' => 'int',
  68. 'size' => 'tiny',
  69. 'not null' => TRUE,
  70. 'default' => 0,
  71. ),
  72. 'submit_notice' => array(
  73. 'description' => 'Boolean value for whether to show or hide the previous submissions notification.',
  74. 'type' => 'int',
  75. 'size' => 'tiny',
  76. 'not null' => TRUE,
  77. 'default' => 1,
  78. ),
  79. 'submit_text' => array(
  80. 'description' => 'The title of the submit button on the form.',
  81. 'type' => 'varchar',
  82. 'length' => 255,
  83. ),
  84. 'submit_limit' => array(
  85. 'description' => 'The number of submissions a single user is allowed to submit within an interval. -1 is unlimited.',
  86. 'type' => 'int',
  87. 'size' => 'tiny',
  88. 'not null' => TRUE,
  89. 'default' => -1,
  90. ),
  91. 'submit_interval' => array(
  92. 'description' => 'The amount of time in seconds that must pass before a user can submit another submission within the set limit.',
  93. 'type' => 'int',
  94. 'not null' => TRUE,
  95. 'default' => -1,
  96. ),
  97. 'total_submit_limit' => array(
  98. 'description' => 'The total number of submissions allowed within an interval. -1 is unlimited.',
  99. 'type' => 'int',
  100. 'not null' => TRUE,
  101. 'default' => -1,
  102. ),
  103. 'total_submit_interval' => array(
  104. 'description' => 'The amount of time in seconds that must pass before another submission can be submitted within the set limit.',
  105. 'type' => 'int',
  106. 'not null' => TRUE,
  107. 'default' => -1,
  108. ),
  109. ),
  110. 'primary key' => array('nid'),
  111. );
  112. $schema['webform_component'] = array(
  113. 'description' => 'Stores information about components for webform nodes.',
  114. 'fields' => array(
  115. 'nid' => array(
  116. 'description' => 'The node identifier of a webform.',
  117. 'type' => 'int',
  118. 'unsigned' => TRUE,
  119. 'not null' => TRUE,
  120. 'default' => 0,
  121. ),
  122. 'cid' => array(
  123. 'description' => 'The identifier for this component within this node, starts at 0 for each node.',
  124. 'type' => 'int',
  125. 'size' => 'small',
  126. 'unsigned' => TRUE,
  127. 'not null' => TRUE,
  128. 'default' => 0,
  129. ),
  130. 'pid' => array(
  131. 'description' => 'If this component has a parent fieldset, the cid of that component.',
  132. 'type' => 'int',
  133. 'size' => 'small',
  134. 'unsigned' => TRUE,
  135. 'not null' => TRUE,
  136. 'default' => 0,
  137. ),
  138. 'form_key' => array(
  139. 'description' => 'When the form is displayed and processed, this key can be used to reference the results.',
  140. 'type' => 'varchar',
  141. 'length' => 128,
  142. ),
  143. 'name' => array(
  144. 'description' => 'The label for this component.',
  145. 'type' => 'varchar',
  146. 'length' => 255,
  147. ),
  148. 'type' => array(
  149. 'description' => 'The field type of this component (textfield, select, hidden, etc.).',
  150. 'type' => 'varchar',
  151. 'length' => 16,
  152. ),
  153. 'value' => array(
  154. 'description' => 'The default value of the component when displayed to the end-user.',
  155. 'type' => 'text',
  156. 'not null' => TRUE,
  157. ),
  158. 'extra' => array(
  159. 'description' => 'Additional information unique to the display or processing of this component.',
  160. 'type' => 'text',
  161. 'not null' => TRUE,
  162. ),
  163. 'mandatory' => array(
  164. 'description' => 'Boolean flag for if this component is required.',
  165. 'type' => 'int',
  166. 'size' => 'tiny',
  167. 'not null' => TRUE,
  168. 'default' => 0,
  169. ),
  170. 'weight' => array(
  171. 'description' => 'Determines the position of this component in the form.',
  172. 'type' => 'int',
  173. 'size' => 'small',
  174. 'not null' => TRUE,
  175. 'default' => 0,
  176. ),
  177. ),
  178. 'primary key' => array('nid', 'cid'),
  179. );
  180. $schema['webform_emails'] = array(
  181. 'description' => 'Holds information regarding e-mails that should be sent upon submitting a webform',
  182. 'fields' => array(
  183. 'nid' => array(
  184. 'description' => 'The node identifier of a webform.',
  185. 'type' => 'int',
  186. 'unsigned' => TRUE,
  187. 'not null' => TRUE,
  188. 'default' => 0,
  189. ),
  190. 'eid' => array(
  191. 'description' => 'The e-mail identifier for this row\'s settings.',
  192. 'type' => 'int',
  193. 'unsigned' => TRUE,
  194. 'size' => 'small',
  195. 'not null' => TRUE,
  196. 'default' => 0,
  197. ),
  198. 'email' => array(
  199. '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.',
  200. 'type' => 'text',
  201. 'not null' => FALSE,
  202. ),
  203. 'subject' => array(
  204. '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.',
  205. 'type' => 'varchar',
  206. 'length' => '255',
  207. 'not null' => FALSE,
  208. ),
  209. 'from_name' => array(
  210. '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.',
  211. 'type' => 'varchar',
  212. 'length' => '255',
  213. 'not null' => FALSE,
  214. ),
  215. 'from_address' => array(
  216. '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.',
  217. 'type' => 'varchar',
  218. 'length' => '255',
  219. 'not null' => FALSE,
  220. ),
  221. 'template' => array(
  222. '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.',
  223. 'type' => 'text',
  224. 'not null' => FALSE,
  225. ),
  226. 'excluded_components' => array(
  227. 'description' => 'A list of components that will not be included in the %email_values token. A list of CIDs separated by commas.',
  228. 'type' => 'text',
  229. 'not null' => TRUE,
  230. ),
  231. 'html' => array(
  232. 'description' => 'Determines if the e-mail will be sent in an HTML format. Requires Mime Mail module.',
  233. 'type' => 'int',
  234. 'unsigned' => TRUE,
  235. 'size' => 'tiny',
  236. 'not null' => TRUE,
  237. 'default' => 0,
  238. ),
  239. 'attachments' => array(
  240. 'description' => 'Determines if the e-mail will include file attachments. Requires Mime Mail module.',
  241. 'type' => 'int',
  242. 'unsigned' => TRUE,
  243. 'size' => 'tiny',
  244. 'not null' => TRUE,
  245. 'default' => 0,
  246. ),
  247. ),
  248. 'primary key' => array('nid', 'eid'),
  249. );
  250. $schema['webform_roles'] = array(
  251. '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.',
  252. 'fields' => array(
  253. 'nid' => array(
  254. 'description' => 'The node identifier of a webform.',
  255. 'type' => 'int',
  256. 'unsigned' => TRUE,
  257. 'not null' => TRUE,
  258. 'default' => 0,
  259. ),
  260. 'rid' => array(
  261. 'description' => 'The role identifier.',
  262. 'type' => 'int',
  263. 'unsigned' => TRUE,
  264. 'not null' => TRUE,
  265. 'default' => 0,
  266. ),
  267. ),
  268. 'primary key' => array('nid', 'rid'),
  269. );
  270. $schema['webform_submissions'] = array(
  271. 'description' => 'Holds general information about submissions outside of field values.',
  272. 'fields' => array(
  273. 'sid' => array(
  274. 'description' => 'The unique identifier for this submission.',
  275. 'type' => 'serial',
  276. 'unsigned' => TRUE,
  277. 'not null' => TRUE,
  278. ),
  279. 'nid' => array(
  280. 'description' => 'The node identifier of a webform.',
  281. 'type' => 'int',
  282. 'unsigned' => TRUE,
  283. 'not null' => TRUE,
  284. 'default' => 0,
  285. ),
  286. 'uid' => array(
  287. 'description' => 'The id of the user that completed this submission.',
  288. 'type' => 'int',
  289. 'unsigned' => TRUE,
  290. 'not null' => TRUE,
  291. 'default' => 0,
  292. ),
  293. 'is_draft' => array(
  294. 'description' => 'Is this a draft of the submission?',
  295. 'type' => 'int',
  296. 'size' => 'tiny',
  297. 'not null' => TRUE,
  298. 'default' => 0,
  299. ),
  300. 'submitted' => array(
  301. 'description' => 'Timestamp of when the form was submitted.',
  302. 'type' => 'int',
  303. 'not null' => TRUE,
  304. 'default' => 0,
  305. ),
  306. 'remote_addr' => array(
  307. 'description' => 'The IP address of the user that submitted the form.',
  308. 'type' => 'varchar',
  309. 'length' => 128,
  310. ),
  311. ),
  312. 'primary key' => array('sid'),
  313. 'unique keys' => array(
  314. 'sid_nid' => array('sid', 'nid'),
  315. ),
  316. 'indexes' => array(
  317. 'nid_uid_sid' => array('nid', 'uid', 'sid'),
  318. 'nid_sid' => array('nid', 'sid'),
  319. ),
  320. );
  321. $schema['webform_submitted_data'] = array(
  322. 'description' => 'Stores all submitted field data for webform submissions.',
  323. 'fields' => array(
  324. 'nid' => array(
  325. 'description' => 'The node identifier of a webform.',
  326. 'type' => 'int',
  327. 'unsigned' => TRUE,
  328. 'not null' => TRUE,
  329. 'default' => 0,
  330. ),
  331. 'sid' => array(
  332. 'description' => 'The unique identifier for this submission.',
  333. 'type' => 'int',
  334. 'unsigned' => TRUE,
  335. 'not null' => TRUE,
  336. 'default' => 0,
  337. ),
  338. 'cid' => array(
  339. 'description' => 'The identifier for this component within this node, starts at 0 for each node.',
  340. 'type' => 'int',
  341. 'size' => 'small',
  342. 'unsigned' => TRUE,
  343. 'not null' => TRUE,
  344. 'default' => 0,
  345. ),
  346. 'no' => array(
  347. '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.',
  348. 'type' => 'varchar',
  349. 'length' => 128,
  350. 'not null' => TRUE,
  351. 'default' => '0',
  352. ),
  353. 'data' => array(
  354. 'description' => 'The submitted value of this field, may be serialized for some components.',
  355. 'type' => 'text',
  356. 'size' => 'medium',
  357. 'not null' => TRUE,
  358. ),
  359. ),
  360. 'primary key' => array('nid', 'sid', 'cid', 'no'),
  361. 'indexes' => array(
  362. 'nid' => array('nid'),
  363. 'sid_nid' => array('sid', 'nid'),
  364. ),
  365. );
  366. $schema['webform_last_download'] = array(
  367. 'description' => 'Stores last submission number per user download.',
  368. 'fields' => array(
  369. 'nid' => array(
  370. 'description' => 'The node identifier of a webform.',
  371. 'type' => 'int',
  372. 'unsigned' => TRUE,
  373. 'not null' => TRUE,
  374. 'default' => 0,
  375. ),
  376. 'uid' => array(
  377. 'description' => 'The user identifier.',
  378. 'type' => 'int',
  379. 'unsigned' => TRUE,
  380. 'not null' => TRUE,
  381. 'default' => 0,
  382. ),
  383. 'sid' => array(
  384. 'description' => 'The last downloaded submission number.',
  385. 'type' => 'int',
  386. 'unsigned' => TRUE,
  387. 'not null' => TRUE,
  388. 'default' => 0,
  389. ),
  390. 'requested' => array(
  391. 'description' => 'Timestamp of last download request.',
  392. 'type' => 'int',
  393. 'unsigned' => TRUE,
  394. 'not null' => TRUE,
  395. 'default' => 0,
  396. ),
  397. ),
  398. 'primary key' => array('nid', 'uid'),
  399. );
  400. return $schema;
  401. }
  402. /**
  403. * Implements hook_install().
  404. */
  405. function webform_install() {
  406. module_load_include('inc', 'node', 'content_types');
  407. db_update('system')
  408. ->condition('name', 'webform')
  409. ->condition('type', 'module')
  410. ->fields(array('weight' => -1))
  411. ->execute();
  412. // Optionally create the default webform type.
  413. if (variable_get('webform_install_create_content_type', TRUE)) {
  414. $webform_type = array(
  415. 'type' => 'webform',
  416. 'name' => st('Webform'),
  417. 'base' => 'node_content',
  418. 'description' => st('Create a new form or questionnaire accessible to users. Submission results and statistics are recorded and accessible to privileged users.'),
  419. 'custom' => TRUE,
  420. 'modified' => TRUE,
  421. 'locked' => FALSE,
  422. );
  423. $webform_type = node_type_set_defaults($webform_type);
  424. node_type_save($webform_type);
  425. node_add_body_field($webform_type);
  426. }
  427. }
  428. /**
  429. * Implements hook_uninstall().
  430. */
  431. function webform_uninstall() {
  432. // Unset webform variables.
  433. variable_del('webform_node_types');
  434. variable_del('webform_node_types_primary');
  435. variable_del('webform_use_cookies');
  436. variable_del('webform_default_from_address');
  437. variable_del('webform_default_from_name');
  438. variable_del('webform_default_subject');
  439. variable_del('webform_default_format');
  440. variable_del('webform_format_override');
  441. variable_del('webform_csv_delimiter');
  442. variable_del('webform_allowed_tags');
  443. variable_del('webform_blocks');
  444. $component_list = array();
  445. $path = drupal_get_path('module', 'webform') . '/components';
  446. $files = file_scan_directory($path, '/^.*\.inc$/');
  447. foreach ($files as $filename => $file) {
  448. variable_del('webform_enable_' . $file->name, 1);
  449. }
  450. // Delete uploaded files.
  451. $filepath = file_build_uri('webform');
  452. file_unmanaged_delete_recursive($filepath);
  453. }
  454. /**
  455. * Set the minimum upgrade version.
  456. *
  457. * Currently you cannot upgrade from 2.x in Drupal 6 to 3.x in Drupal 7. However
  458. * there are no database changes between the 3.x versions, so no update is
  459. * needed at all to move from 3.x in Drupal 6 to Drupal 7.
  460. */
  461. function webform_update_last_removed() {
  462. return 6313;
  463. }
  464. /**
  465. * Allow the confirmation format column to have a NULL value.
  466. */
  467. function webform_update_7301() {
  468. // These changes are modeled after user_update_7010().
  469. db_change_field('webform', 'confirmation_format', 'confirmation_format', array(
  470. 'description' => 'The {filter_format}.format of the confirmation message.',
  471. 'type' => 'int',
  472. 'unsigned' => TRUE,
  473. 'not null' => FALSE,
  474. ));
  475. db_update('webform')
  476. ->fields(array('confirmation_format' => NULL))
  477. ->condition('confirmation', '')
  478. ->condition('confirmation_format', 0)
  479. ->execute();
  480. $existing_formats = db_query("SELECT format FROM {filter_format}")->fetchCol();
  481. $default_format = variable_get('filter_default_format', 1);
  482. // Since Webform may be updated separately from Drupal core, not all format
  483. // names may be numbers when running this update.
  484. $numeric_formats = array();
  485. foreach ($existing_formats as $format_name) {
  486. if (is_numeric($format_name)) {
  487. $numeric_formats[] = (int) $format_name;
  488. }
  489. }
  490. $query = db_update('webform')
  491. ->fields(array('confirmation_format' => $default_format))
  492. ->isNotNull('confirmation_format');
  493. if (!empty($numeric_formats)) {
  494. $query->condition('confirmation_format', $numeric_formats, 'NOT IN');
  495. }
  496. $query->execute();
  497. }
  498. /**
  499. * Add columns for e-mail HTML and attachment settings.
  500. */
  501. function webform_update_7302() {
  502. if (!db_field_exists('webform_emails', 'html')) {
  503. db_add_field('webform_emails', 'html', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'default' => 0, 'not null' => TRUE));
  504. db_add_field('webform_emails', 'attachments', array('type' => 'int', 'size' => 'tiny', 'unsigned' => TRUE, 'default' => 0, 'not null' => TRUE));
  505. }
  506. }
  507. /**
  508. * Set the default for the "submit_notice" column to 1.
  509. */
  510. function webform_update_7303() {
  511. db_change_field('webform', 'submit_notice', 'submit_notice', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 1));
  512. }
  513. /**
  514. * Add field for block feature and redirection setting.
  515. */
  516. function webform_update_7304() {
  517. if (!db_field_exists('webform', 'block')) {
  518. db_add_field('webform', 'block', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
  519. db_change_field('webform', 'redirect_url', 'redirect_url', array('type' => 'varchar', 'length' => 255, 'default' => '<confirmation>'));
  520. db_update('webform')
  521. ->fields(array('redirect_url' => 'confirmation'))
  522. ->condition('redirect_url', '')
  523. ->execute();
  524. }
  525. }
  526. /**
  527. * Set additional_validate and additional_submit columns to allow NULL.
  528. */
  529. function webform_update_7305() {
  530. if (db_field_exists('webform', 'additional_validate')) {
  531. db_change_field('webform', 'additional_validate', 'additional_validate', array('type' => 'text', 'not null' => FALSE));
  532. db_change_field('webform', 'additional_submit', 'additional_submit', array('type' => 'text', 'not null' => FALSE));
  533. }
  534. }
  535. /**
  536. * Add column for webform status (open or closed).
  537. */
  538. function webform_update_7306() {
  539. if (!db_field_exists('webform', 'status')) {
  540. db_add_field('webform', 'status', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 1));
  541. }
  542. }
  543. /**
  544. * Update the confirmation_format column for default text format changes.
  545. */
  546. function webform_update_7307() {
  547. // Update removed and moved to webform_update_7301().
  548. // See http://drupal.org/node/976102.
  549. }
  550. /**
  551. * Update the confirmation_format column to allow it to store strings.
  552. */
  553. function webform_update_7308() {
  554. db_change_field('webform', 'confirmation_format', 'confirmation_format', array(
  555. 'description' => 'The {filter_format}.format of the confirmation message.',
  556. 'type' => 'varchar',
  557. 'length' => 255,
  558. 'not null' => FALSE,
  559. ));
  560. }
  561. /**
  562. * Add the ability to auto-save as draft between pages.
  563. */
  564. function webform_update_7309() {
  565. if (!db_field_exists('webform', 'auto_save')) {
  566. db_add_field('webform', 'auto_save', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
  567. }
  568. }
  569. /**
  570. * Remove orphaned and unnecessary rows in the webform table.
  571. */
  572. function webform_update_7310() {
  573. $result = db_query("SELECT nid FROM {webform} WHERE
  574. nid NOT IN
  575. (SELECT DISTINCT(w1.nid) FROM {webform} w1 INNER JOIN {webform_component} wc ON w1.nid = wc.nid)
  576. AND nid NOT IN
  577. (SELECT w2.nid FROM {webform} w2 INNER JOIN {node} n ON w2.nid = n.nid WHERE n.type = 'webform')"
  578. );
  579. $empty_nids = array();
  580. foreach ($result as $row) {
  581. $empty_nids[] = $row->nid;
  582. }
  583. if (!empty($empty_nids)) {
  584. db_delete('webform')->condition('nid', $empty_nids, 'IN')->execute();
  585. }
  586. }
  587. /**
  588. * Add an index for nid_uid_sid to webform_submissions.
  589. */
  590. function webform_update_7311() {
  591. if (!db_index_exists('webform_submissions', 'nid_uid_sid')) {
  592. db_add_index('webform_submissions', 'nid_uid_sid', array('nid', 'uid', 'sid'));
  593. }
  594. }
  595. /**
  596. * Remove unused Webform variables.
  597. */
  598. function webform_update_7312() {
  599. variable_del('node_types');
  600. variable_del('components');
  601. }
  602. /**
  603. * Convert the Date component start and end year options to start and end date.
  604. */
  605. function webform_update_7313() {
  606. $result = db_select('webform_component', 'wc', array('fetch' => PDO::FETCH_ASSOC))
  607. ->fields('wc')
  608. ->condition('type', 'date')
  609. ->execute();
  610. foreach ($result as $component) {
  611. $component['extra'] = unserialize($component['extra']);
  612. if (!isset($component['extra']['start_date']) && !isset($component['end_date'])) {
  613. foreach (array('year_start' => 'start_date', 'year_end' => 'end_date') as $key => $replacement) {
  614. $value = isset($component['extra'][$key]) ? trim($component['extra'][$key]) : '';
  615. // Relative years.
  616. if (preg_match('/[-+][ ]*[0-9]+/', $value)) {
  617. $component['extra'][$replacement] = ($value == 1) ? ($value . ' year') : ($value . ' years');
  618. }
  619. // Absolute years.
  620. elseif (is_numeric($value)) {
  621. $component['extra'][$replacement] = 'Dec 31 ' . $value;
  622. }
  623. unset($component['extra'][$key]);
  624. }
  625. $component['extra'] = serialize($component['extra']);
  626. drupal_write_record('webform_component', $component, array('nid', 'cid'));
  627. }
  628. }
  629. }
  630. /**
  631. * Add webform_last_download table to store last downloaded sid per user.
  632. */
  633. function webform_update_7314() {
  634. // Safety check to prevent recreating the webform_last_download table.
  635. if (db_table_exists('webform_last_download')) {
  636. return;
  637. }
  638. $schema['webform_last_download'] = array(
  639. 'description' => 'Stores last submission number per user download.',
  640. 'fields' => array(
  641. 'nid' => array(
  642. 'description' => 'The node identifier of a webform.',
  643. 'type' => 'int',
  644. 'unsigned' => TRUE,
  645. 'not null' => TRUE,
  646. 'default' => 0,
  647. ),
  648. 'uid' => array(
  649. 'description' => 'The user identifier.',
  650. 'type' => 'int',
  651. 'unsigned' => TRUE,
  652. 'not null' => TRUE,
  653. 'default' => 0,
  654. ),
  655. 'sid' => array(
  656. 'description' => 'The last downloaded submission number.',
  657. 'type' => 'int',
  658. 'unsigned' => TRUE,
  659. 'not null' => TRUE,
  660. 'default' => 0,
  661. ),
  662. ),
  663. 'primary key' => array('nid', 'uid'),
  664. );
  665. db_create_table('webform_last_download', $schema['webform_last_download']);
  666. }
  667. /**
  668. * Add column for timestamp of last requested CSV download.
  669. */
  670. function webform_update_7315() {
  671. if (!db_field_exists('webform_last_download', 'requested')) {
  672. db_add_field('webform_last_download', 'requested', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,));
  673. }
  674. }
  675. /**
  676. * Add additional columns for total submission limit.
  677. */
  678. function webform_update_7316() {
  679. if (!db_field_exists('webform', 'total_submit_limit')) {
  680. db_add_field('webform', 'total_submit_limit', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
  681. }
  682. if (!db_field_exists('webform', 'total_submit_interval')) {
  683. db_add_field('webform', 'total_submit_interval', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
  684. }
  685. }
  686. /**
  687. * Add an index for 'nid_sid' to webform_submissions.
  688. */
  689. function webform_update_7317() {
  690. // Even though we already have an index 'nid_uid_sid', adding the index for
  691. // 'nid_sid' saves us a tablesort on the node/x/webform-results page.
  692. if (!db_index_exists('webform_submissions', 'nid_sid')) {
  693. db_add_index('webform_submissions', 'nid_sid', array('nid', 'sid'));
  694. }
  695. }
  696. /**
  697. * Upgrade file components to support the new AJAX-upload element.
  698. */
  699. function webform_update_7318() {
  700. $result = db_select('webform_component', 'wc', array('fetch' => PDO::FETCH_ASSOC))
  701. ->fields('wc')
  702. ->condition('type', 'file')
  703. ->execute();
  704. foreach ($result as $component) {
  705. $component['extra'] = unserialize($component['extra']);
  706. if (!isset($component['extra']['directory'])) {
  707. $component['extra']['directory'] = $component['extra']['savelocation'];
  708. $component['extra']['scheme'] = file_default_scheme();
  709. $component['extra']['filtering']['size'] = $component['extra']['filtering']['size'] . ' KB';
  710. unset($component['extra']['savelocation']);
  711. $component['extra'] = serialize($component['extra']);
  712. drupal_write_record('webform_component', $component, array('nid', 'cid'));
  713. }
  714. }
  715. return t('File components updated to support AJAX uploading.');
  716. }
  717. /**
  718. * Add file usage entries for all files uploaded through Webform.
  719. */
  720. function webform_update_7319(&$sandbox) {
  721. if (!isset($sandbox['progress'])) {
  722. // Initialize batch update information.
  723. $sandbox['progress'] = 0;
  724. $sandbox['last_fid_processed'] = -1;
  725. $sandbox['max'] = db_select('file_managed')
  726. ->condition('uri', '%' . db_like('://webform/') . '%', 'LIKE')
  727. ->countQuery()
  728. ->execute()
  729. ->fetchField();
  730. }
  731. // Process all files attached to a given revision during the same batch.
  732. $limit = variable_get('webform_update_batch_size', 100);
  733. $files = db_select('file_managed', 'f')
  734. ->fields('f')
  735. ->condition('uri', '%' . db_like('://webform/') . '%', 'LIKE')
  736. ->condition('fid', $sandbox['last_fid_processed'], '>')
  737. ->orderBy('fid', 'ASC')
  738. ->range(0, $limit)
  739. ->execute()
  740. ->fetchAllAssoc('fid', PDO::FETCH_ASSOC);
  741. // Determine each submission with which a file is associated.
  742. if (!empty($files)) {
  743. foreach ($files as $fid => $file) {
  744. $file = (object) $file;
  745. $sids = db_query('SELECT wsd.sid FROM {webform_component} wc INNER JOIN {webform_submitted_data} wsd ON wc.nid = wsd.nid AND wc.type = :file WHERE data = :fid', array(':file' => 'file', ':fid' => $file->fid))->fetchAllAssoc('sid', PDO::FETCH_ASSOC);
  746. foreach ($sids as $sid => $row) {
  747. // We use a db_merge() instead of file_usage_add() to prevent problems
  748. // in the event this update was run twice. No file provided by Webform
  749. // should ever be in use more than once at this point.
  750. db_merge('file_usage')
  751. ->key(array(
  752. 'fid' => $file->fid,
  753. 'type' => 'submission',
  754. 'module' => 'webform',
  755. 'id' => $sid,
  756. ))
  757. ->fields(array(
  758. 'count' => 1,
  759. ))
  760. ->execute();
  761. }
  762. // Update our progress information for the batch update.
  763. $sandbox['progress']++;
  764. $sandbox['last_fid_processed'] = $file->fid;
  765. }
  766. }
  767. // If less than limit was processed, the update process is finished.
  768. if (count($files) < $limit || $sandbox['progress'] == $sandbox['max']) {
  769. $finished = TRUE;
  770. }
  771. // If there's no max value then there's nothing to update and we're finished.
  772. if (empty($sandbox['max']) || isset($finished)) {
  773. return t('Webform file entries created in the file_usage table.');
  774. }
  775. else {
  776. // Indicate our current progress to the batch update system.
  777. $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max'];
  778. }
  779. }
  780. /**
  781. * Mark files uploaded through Webform that report active usage permanent.
  782. */
  783. function webform_update_7320() {
  784. db_query("UPDATE {file_managed} SET status = 1 WHERE fid IN (SELECT fid FROM {file_usage} WHERE module = :module_name)", array(':module_name' => 'webform'));
  785. }