PageRenderTime 24ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/reason_4.0/lib/core/scripts/upgrade/4.0b6_to_4.0b7/forms.php

https://github.com/luthercollege/reason_package
PHP | 412 lines | 330 code | 30 blank | 52 comment | 56 complexity | e4f7a27cb65f63c7d644bb407bd5fbfe MD5 | raw file
  1. <?php
  2. /**
  3. * Modify the form type with extra fields for expanded thor capabilities
  4. *
  5. * @package reason
  6. * @subpackage scripts
  7. */
  8. /**
  9. * Start script
  10. */
  11. ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  12. <html>
  13. <head>
  14. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  15. <title>Upgrade Reason: Form Upgrader</title>
  16. </head>
  17. <body>
  18. <?php
  19. include ('reason_header.php');
  20. include_once(CARL_UTIL_INC.'db/db_selector.php');
  21. reason_include_once('classes/entity_selector.php');
  22. reason_include_once('function_libraries/util.php');
  23. reason_include_once('function_libraries/user_functions.php');
  24. reason_include_once('function_libraries/admin_actions.php');
  25. reason_include_once('classes/field_to_entity_table_class.php');
  26. class formUpgrader
  27. {
  28. var $mode;
  29. var $reason_user_id;
  30. var $fields_to_add =
  31. array('is_editable' =>
  32. array('db_type' => 'enum("yes","no")'),
  33. 'thor_view' =>
  34. array('db_type' => 'tinytext'),
  35. 'allow_multiple' =>
  36. array('db_type' => 'enum("yes","no")'),
  37. 'email_submitter' =>
  38. array('db_type' => 'enum("yes","no")'),
  39. 'email_link' =>
  40. array('db_type' => 'enum("yes","no")'),
  41. 'email_data' =>
  42. array('db_type' => 'enum("yes","no") DEFAULT "yes"'),
  43. 'email_empty_fields' =>
  44. array('db_type' => 'enum("yes","no") DEFAULT "yes"')); // lets preserve old behavior
  45. //type_to_default_view
  46. function do_updates($mode, $reason_user_id)
  47. {
  48. if($mode != 'run' && $mode != 'test')
  49. {
  50. trigger_error('$mode most be either "run" or "test"');
  51. return;
  52. }
  53. $this->mode = $mode;
  54. settype($reason_user_id, 'integer');
  55. if(empty($reason_user_id))
  56. {
  57. trigger_error('$reason_user_id must be a nonempty integer');
  58. return;
  59. }
  60. $this->reason_user_id = $reason_user_id;
  61. // The updates
  62. $this->create_authenticated_group_if_it_does_not_exist();
  63. $this->add_fields_to_form_entity_table($this->fields_to_add);
  64. $this->modify_form_force_login_pages();
  65. $this->add_last_modified_field();
  66. $this->show_local_link();
  67. }
  68. function add_fields_to_form_entity_table($fields)
  69. {
  70. $es = new entity_selector();
  71. $es->add_type(id_of('content_table'));
  72. $es->add_relation('entity.name = "form"');
  73. $es->set_num(1);
  74. $table = $es->run_one();
  75. if(empty($table))
  76. {
  77. echo '<p>Unable to find form entity table - the script cannot run.</p>';
  78. }
  79. else
  80. {
  81. $field_string = '"'.implode('","', array_keys($fields)).'"';
  82. $form_table = current($table);
  83. $es = new entity_selector();
  84. $es->add_type(id_of('field'));
  85. $es->add_relation('entity.name IN ('.$field_string.')');
  86. $es->add_left_relationship($form_table->id(),relationship_id_of('field_to_entity_table'));
  87. $existing_fields = $es->run_one();
  88. foreach($existing_fields as $field)
  89. {
  90. unset($fields[$field->get_value('name')]);
  91. }
  92. if(empty($fields))
  93. {
  94. echo '<p>All new form fields exist - the form type has already been updated.</p>';
  95. }
  96. else
  97. {
  98. if($this->mode != 'run')
  99. {
  100. echo '<p>Would have created these fields:</p>';
  101. pray($fields);
  102. }
  103. else
  104. {
  105. $updater = new FieldToEntityTable($form_table->get_value('name'), $fields);
  106. $updater->update_entity_table();
  107. $updater->report();
  108. }
  109. }
  110. }
  111. }
  112. function modify_form_force_login_pages()
  113. {
  114. $es = new entity_selector();
  115. $es->add_type(id_of('minisite_page'));
  116. $es->limit_tables('page_node');
  117. $es->limit_fields('custom_page');
  118. $es->add_relation('page_node.custom_page = "form_force_login"');
  119. $result = $es->run_one();
  120. if(empty($result))
  121. {
  122. echo '<p>These are no pages of type form_force_login in this reason instance.</p>';
  123. }
  124. else
  125. {
  126. if ($this->mode != 'run')
  127. {
  128. echo '<p>Would modify ' . count($result) . ' page(s) with page type form_force_login</p>';
  129. }
  130. else
  131. {
  132. foreach ($result as $page_id => $page)
  133. {
  134. $site = $page->get_owner();
  135. $this->ensure_group_type_is_on_site($site);
  136. $this->restrict_page_to_group_and_change_page_type($site, $page);
  137. }
  138. }
  139. }
  140. }
  141. function add_last_modified_field()
  142. {
  143. connectDB(THOR_FORM_DB_CONN);
  144. $updates_to_make = false;
  145. $prefix = 'form_';
  146. $result = db_query("show tables");
  147. if (mysql_num_rows($result) > 0)
  148. {
  149. while ($row = mysql_fetch_row($result))
  150. if (substr($row[0], 0, strlen($prefix)) == $prefix) $return[] = $row[0];
  151. }
  152. if (!empty($return))
  153. {
  154. foreach ($return as $key => $table)
  155. {
  156. $result = db_query("select * from " . $table . " LIMIT 1");
  157. if (mysql_num_rows($result) > 0) // a thor table by definition has records - so don't do anything if not
  158. {
  159. // first lets make sure this needs to be updated
  160. $has_date_created = $has_last_modified = $has_submitter_ip = false;
  161. while ($colinfo = mysql_fetch_field($result))
  162. {
  163. if ($colinfo->name == 'date_created') $has_date_created = true;
  164. elseif ($colinfo->name == 'date_modified') $has_last_modified = true;
  165. elseif ($colinfo->name == 'submitter_ip') $has_submitter_ip = true;
  166. }
  167. if ( ($has_date_created === true) && ($has_last_modified === false) && ($has_submitter_ip === true) )
  168. {
  169. $updates_to_make = true;
  170. //lets alter the table and update ALL the fields!
  171. if ($this->mode == 'test')
  172. {
  173. echo '<p>Would update thor table with name ' . $table . '</p>';
  174. }
  175. else
  176. {
  177. $qry1 = 'ALTER TABLE `'.$table.'` CHANGE `date_created` `date_modified` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
  178. $qry2 = 'ALTER TABLE `'.$table.'` ADD `date_created` TIMESTAMP NOT NULL DEFAULT 0 AFTER `submitter_ip`';
  179. $qry3 = 'UPDATE `'.$table.'` SET `date_created` = `date_modified`, `date_modified` = `date_modified`';
  180. db_query($qry1);
  181. db_query($qry2);
  182. db_query($qry3);
  183. echo '<p>Updated thor table with name ' . $table . '</p>';
  184. }
  185. }
  186. }
  187. }
  188. }
  189. if (!$updates_to_make) echo '<p>No thor tables need updating - the script has probably been run</p>';
  190. connectDB(REASON_DB);
  191. }
  192. //$q .= '`date_created` timestamp default 0 NOT NULL , ';
  193. //$q .= '`date_modified` timestamp default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , ';
  194. function ensure_group_type_is_on_site($site)
  195. {
  196. $site_id = $site->id();
  197. $es = new entity_selector();
  198. $es->add_type(id_of('group_type'));
  199. $es->add_right_relationship($site_id,relationship_id_of('site_to_type'));
  200. $es->add_relation('entity.id = "'.id_of('group_type').'"');
  201. $es->set_num(1);
  202. $type = $es->run_one();
  203. if(empty($type))
  204. {
  205. create_relationship( $site_id, id_of('group_type'), relationship_id_of('site_to_type'));
  206. }
  207. }
  208. function restrict_page_to_group_and_change_page_type($site, $page)
  209. {
  210. $site_id = $site->id();
  211. $page_id = $page->id();
  212. // first lets see if there is a group related to the page over the page_to_access_group relationship
  213. $es = new entity_selector();
  214. $es->add_type(id_of('group_type'));
  215. $es->add_right_relationship($page_id, relationship_id_of('page_to_access_group'));
  216. $es->set_num(1);
  217. $group = $es->run_one();
  218. if(empty($group))
  219. {
  220. if(!site_borrows_entity( $site_id, id_of('authenticated_group', false)))
  221. {
  222. create_relationship( $site_id, id_of('authenticated_group', false), get_borrow_relationship_id(id_of('group_type')));
  223. }
  224. create_relationship( $page_id, id_of('authenticated_group', false), relationship_id_of('page_to_access_group'));
  225. }
  226. reason_update_entity($page_id, $this->reason_user_id, array('custom_page' => 'form'));
  227. echo '<p>Page ' . $page->get_value('name') . ' on site ' . $site->get_value('name') . ' is now of the form page type and properly restricted.</p>';
  228. }
  229. function create_authenticated_group_if_it_does_not_exist()
  230. {
  231. if (!reason_unique_name_exists('authenticated_group', false))
  232. {
  233. if ($this->mode != 'run') echo '<p>Would create authenticated group</p>';
  234. else
  235. {
  236. $group['name'] = 'Authenticated Group';
  237. $group['require_authentication'] = "true";
  238. $group['limit_authorization'] = "false";
  239. $group['group_has_members'] = "true";
  240. $group['new'] = 0;
  241. $group['unique_name'] = 'authenticated_group';
  242. $group_id = reason_create_entity(id_of('master_admin'), id_of('group_type'), $this->reason_user_id, $group['name'], $group);
  243. echo '<p>Created authenticated group</p>';
  244. }
  245. }
  246. else echo '<p>Authenticated group already exists</p>';
  247. }
  248. /**
  249. * A little hook to link to a local update file if it exists
  250. */
  251. function show_local_link()
  252. {
  253. if (reason_file_exists('scripts/upgrade/4.0b6_to_4.0b7/forms_local.php'))
  254. {
  255. $link = carl_construct_link(array(), array(), '/reason_package/reason_4.0/lib/local/scripts/upgrade/4.0b6_to_4.0b7/forms_local.php');
  256. echo '<a href="'.$link.'">Proceed to local updates</a>';
  257. }
  258. }
  259. function add_type_to_site($type_id)
  260. {
  261. $rel_id = create_relationship( $this->get_value('site_id'), $type_id, relationship_id_of('site_to_type'));
  262. return $rel_id;
  263. }
  264. }
  265. force_secure_if_available();
  266. $user_netID = reason_require_authentication();
  267. $reason_user_id = get_user_id( $user_netID );
  268. if(empty($reason_user_id))
  269. {
  270. die('valid Reason user required');
  271. }
  272. if(!reason_user_has_privs( $reason_user_id, 'upgrade' ) )
  273. {
  274. die('You must have Reason upgrade rights to run this script');
  275. }
  276. ?>
  277. <h2>Reason: Form Upgrader</h2>
  278. <p>The thor form module has been completely reworked in Reason 4 Beta 7. Existing forms should continue to function as usual.
  279. The content manager has been updated a bit, but the new features are for the moment only exposed to instance administrators.
  280. Reason 4 Beta 8 will expose more of the new functionality to site administrators, and make the interface prettier.</p>
  281. <p><strong>Changes include:</strong></p>
  282. <ul>
  283. <li>Forms can be marked as "editable," allowing users to fill out a form, and edit the submission at a later time.</li>
  284. <li>A form can allow multiple editable submissions from a single user</li>
  285. <li>Forms can be set to e-mail the submitter</li>
  286. <li>Forms can be set to e-mail data, a link to the form data (great for more secure forms), or both</li>
  287. <li>Forms can be set to not e-mail empty fields</li>
  288. <li>Administrators can develop and choose custom views for a particular thor form.</li>
  289. <li>Thor tables now have both a last_modified and date_created field - date_created used to function like a last_modified</li>
  290. </ul>
  291. <p><strong>What will this update do?</strong></p>
  292. <ul>
  293. <li>Adds is_editable to the form entity table.</li>
  294. <li>Adds allow_multiple to the form entity table.</li>
  295. <li>Adds email_submitter to the form entity table.</li>
  296. <li>Adds email_link to the form entity table.</li>
  297. <li>Adds email_data to the form entity table.</li>
  298. <li>Adds email_empty_fields to the form entity table.</li>
  299. <li>Adds thor_view to the form entity table.</li>
  300. <li>Create the authenticated group - a group comprised of people with netids, it it does not exist</li>
  301. <li>Modifies pages using form_force_login page type to be restricted to users with a netid.</li>
  302. <li>Modifies pages using form_force_login page type to use the standard form page type.</li>
  303. <li>Updates all thor tables to add a last_modified field, and changes the definition of the date_created field</li>
  304. </ul>
  305. <?php
  306. if(!defined('REASON_FORMS_THOR_DEFAULT_VIEW') || !defined('REASON_FORMS_THOR_DEFAULT_CONTROLLER') || !defined('REASON_FORMS_THOR_DEFAULT_VIEW'))
  307. {
  308. echo '<h3>Step 1: Add setting</h3>';
  309. if(!empty($_GET['setting']))
  310. {
  311. echo '<h4 style="color:#c00;">ALERT: It does not appear that all needed constants are defined. You need to add the following constants to reason_settings.php before proceeding.</h4>'."\n";
  312. echo '<ul>';
  313. if(!defined('REASON_FORMS_THOR_DEFAULT_VIEW')) echo '<li>REASON_FORMS_THOR_DEFAULT_VIEW</li>';
  314. if(!defined('REASON_FORMS_THOR_DEFAULT_CONTROLLER')) echo '<li>REASON_FORMS_THOR_DEFAULT_CONTROLLER</li>';
  315. if(!defined('REASON_FORMS_THOR_DEFAULT_MODEL')) echo '<li>REASON_FORMS_THOR_DEFAULT_MODEL</li>';
  316. echo '</ul>';
  317. }
  318. ?>
  319. <p>Copy and paste the missing constant definitions below into your reason_settings.php file.</p>
  320. <textarea rows="24" cols="80" style="width:100%;background-color:#ddd;">
  321. /**
  322. * REASON_FORMS_THOR_DEFAULT_MODEL
  323. *
  324. * Indicates the filename that should be used as the default model for thor forms within Reason.
  325. *
  326. * You can provide the path in one of three ways:
  327. *
  328. * 1. Fully qualified path
  329. * 2. Pathname from the core/local split
  330. * 3. Relative path from within minisite_templates/modules/form/models/ directory
  331. */
  332. define('REASON_FORMS_THOR_DEFAULT_MODEL', 'thor.php');
  333. /**
  334. * REASON_FORMS_THOR_DEFAULT_CONTROLLER
  335. *
  336. * Indicates the filename that should be used as the default controller for thor forms within Reason.
  337. *
  338. * You can provide the path in one of three ways:
  339. *
  340. * 1. Fully qualified path
  341. * 2. Pathname from the core/local split
  342. * 3. Relative path from within minisite_templates/modules/form/controllers/ directory
  343. */
  344. define('REASON_FORMS_THOR_DEFAULT_CONTROLLER', 'thor.php');
  345. /**
  346. * REASON_FORMS_THOR_DEFAULT_VIEW
  347. *
  348. * Indicates the filename that should be used as the default thor view for thor forms within Reason.
  349. *
  350. * You can provide the path in one of three ways:
  351. *
  352. * 1. Fully qualified path
  353. * 2. Pathname from the core/local split
  354. * 3. filename within minisite_templates/modules/form/views/thor/ directory
  355. */
  356. define('REASON_FORMS_THOR_DEFAULT_VIEW', 'default.php');
  357. </textarea>
  358. <p>Once you have done that, <a href="?setting=1">Proceed to the database upgrade</a>.</p>
  359. <?php
  360. }
  361. else
  362. {
  363. ?>
  364. <p>REASON_FORMS_THOR_DEFAULT_VIEW setting OK.</p>
  365. <p>Next step: update the database.</p>
  366. <form method="post"><input type="submit" name="go" value="test" /><input type="submit" name="go" value="run" /></form>
  367. <?php
  368. }
  369. if(!empty($_POST['go']) && ($_POST['go'] == 'run' || $_POST['go'] == 'test'))
  370. {
  371. if($_POST['go'] == 'run')
  372. echo '<p>Running updater...</p>'."\n";
  373. else
  374. echo '<p>Testing updates...</p>'."\n";
  375. $updater = new formUpgrader();
  376. $updater->do_updates($_POST['go'], $reason_user_id);
  377. }
  378. $link = carl_construct_link(array(),array(), REASON_HTTP_BASE_PATH . 'scripts/upgrade/4.0b6_to_4.0b7/index.php');
  379. echo '<p><a href="'.$link.'">Return to Index</a></p>';
  380. ?>
  381. </body>
  382. </html>