custom_tables.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <?php
  2. /**
  3. * @file
  4. * Contains functions for creating, editing and deleting custom tables
  5. * on the Tripal website.
  6. *
  7. * @ingroup tripal_core
  8. */
  9. /**
  10. * Provides a landing page for tripal jobs admin
  11. */
  12. function tripal_custom_table_admin_view() {
  13. $output = '';
  14. // set the breadcrumb
  15. $breadcrumb = array();
  16. $breadcrumb[] = l('Home', '<front>');
  17. $breadcrumb[] = l('Administration', 'admin');
  18. $breadcrumb[] = l('Tripal', 'admin/tripal');
  19. $breadcrumb[] = l('Chado Schema', 'admin/tripal/schema');
  20. $breadcrumb[] = l('Custom Tables', 'admin/tripal/schema/custom_tables');
  21. drupal_set_breadcrumb($breadcrumb);
  22. // Add the view
  23. $view = views_embed_view('tripal_core_admin_custom_table','default');
  24. if (isset($view)) {
  25. $output .= $view;
  26. }
  27. else {
  28. $output .= '<p>The Tripal Custom Table management system uses primarily views to provide an '
  29. . 'administrative interface. Currently one or more views needed for this '
  30. . 'administrative interface are disabled. <strong>Click each of the following links to '
  31. . 'enable the pertinent views</strong>:</p>';
  32. $output .= '<ul>';
  33. $output .= '<li>'.l('Custom Tables View', 'admin/tripal/schema/custom_tables/views/tables/enable').'</li>';
  34. $output .= '</ul>';
  35. }
  36. return $output;
  37. }
  38. /**
  39. *
  40. */
  41. function tripal_custom_table_new_page() {
  42. $output = drupal_render(drupal_get_form('tripal_custom_tables_form'));
  43. return $output;
  44. }
  45. /**
  46. * A template function which returns markup to display details for the custom table
  47. *
  48. * @param $table_id
  49. * The unique ID of the custom table
  50. *
  51. * @ingroup tripal_core
  52. */
  53. function tripal_custom_table_view($table_id) {
  54. // get this custom_table details
  55. $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_id = :table_id";
  56. $results = db_query($sql, array(':table_id' => $table_id));
  57. $custom_table = $results->fetchObject();
  58. // create a table with each row containig stats for
  59. // an individual job in the results set.
  60. $return_url = url("admin/tripal/custom_tables/");
  61. $output .= "<p><a href=\"$return_url\">" . t("Return to list of custom tables") . "</a></p>";
  62. $output .= "<br />";
  63. $output .= "<p>Details for <b>$custom_table->table_name</b>:</p>";
  64. $output .= "<br />";
  65. $output .= "<table class=\"border-table\">";
  66. if ($custom_table->table_name) {
  67. $output .= " <tr>" .
  68. " <th>Table Name</th>" .
  69. " <td>$custom_table->table_name</td>" .
  70. " </tr>";
  71. }
  72. if ($custom_table->schema) {
  73. $output .= " <tr>" .
  74. " <th>Table Field Definitions</th>" .
  75. " <td><pre>" . var_export(unserialize($custom_table->schema), 1) . "</pre></td>" .
  76. " </tr>";
  77. }
  78. // build the URLs using the url function so we can handle installations where
  79. // clean URLs are or are not used
  80. $delete_url = url("admin/tripal/custom_tables/action/delete/$custom_table->table_id");
  81. $edit_url = url("admin/tripal/custom_tables/edit/$custom_table->table_id");
  82. $output .= "<tr><th>Actions</th>" .
  83. "<td>" .
  84. " <a href='$edit_url'>Edit</a>, " .
  85. " <a href='$delete_url'>Delete</a></td></tr>";
  86. $output .= "</table>";
  87. return $output;
  88. }
  89. /**
  90. * A template function to render a listing of all Custom tables
  91. *
  92. * @ingroup tripal_core
  93. */
  94. function tripal_custom_tables_list() {
  95. $header = array('', 'Table Name', 'Description');
  96. $rows = array();
  97. $custom_tables = db_query("SELECT * FROM {tripal_custom_tables} ORDER BY table_name");
  98. foreach ($custom_tables as $custom_table) {
  99. $rows[] = array(
  100. l(t('View'), "admin/tripal/custom_tables/view/$custom_table->table_id") . " | " .
  101. l(t('Edit'), "admin/tripal/custom_tables/edit/$custom_table->table_id") . " | " .
  102. $custom_table->table_name,
  103. $custom_table->comment,
  104. l(t('Delete'), "admin/tripal/custom_tables/action/delete/$custom_table->table_id"),
  105. );
  106. }
  107. $rows[] = array(
  108. 'data' => array(
  109. array('data' => l(t('Create a new custom table.'), "admin/tripal/custom_tables/new"),
  110. 'colspan' => 6),
  111. )
  112. );
  113. $table = array(
  114. 'header' => $header,
  115. 'rows' => $rows,
  116. 'attributes' => array(),
  117. 'sticky' => FALSE,
  118. 'caption' => '',
  119. 'colgroups' => array(),
  120. 'empty' => 'No custom tables have been added',
  121. );
  122. $page = theme_table($table);
  123. return $page;
  124. }
  125. /**
  126. * A Form to Create/Edit a Custom table
  127. *
  128. * @param $form_state
  129. * The current state of the form (Form API)
  130. * @param $table_id
  131. * The unique ID of the Custom table to Edit or NULL if creating a new table
  132. *
  133. * @return
  134. * A form array (Form API)
  135. *
  136. * @ingroup tripal_core
  137. */
  138. function tripal_custom_tables_form($form, &$form_state = NULL, $table_id = NULL) {
  139. if (!$table_id) {
  140. $action = 'Add';
  141. }
  142. else {
  143. $action = 'Edit';
  144. }
  145. // get this requested table
  146. $default_schema = '';
  147. $default_force_drop = 0;
  148. if (strcmp($action, 'Edit')==0) {
  149. $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_id = :table_id ";
  150. $results = db_query($sql, array(':table_id' => $table_id));
  151. $custom_table = $results->fetchObject();
  152. // set the default values. If there is a value set in the
  153. // form_state then let's use that, otherwise, we'll pull
  154. // the values from the database
  155. $default_schema = $form_state['values']['schema'];
  156. $default_force_drop = $form_state['values']['force_drop'];
  157. if (!$default_table_name) {
  158. $default_table = $custom_table->table_name;
  159. }
  160. if (!$default_schema) {
  161. $default_schema = var_export(unserialize($custom_table->schema), 1);
  162. $default_schema = preg_replace('/=>\s+\n\s+array/', '=> array', $default_schema);
  163. }
  164. }
  165. // Build the form
  166. $form['action'] = array(
  167. '#type' => 'value',
  168. '#value' => $action
  169. );
  170. $form['table_id'] = array(
  171. '#type' => 'value',
  172. '#value' => $table_id
  173. );
  174. $form['instructions']= array(
  175. '#type' => 'item',
  176. '#description' => t('At times it is necessary to add a custom table to the Chado schema.
  177. These are not offically sanctioned tables but may be necessary for local data requirements.
  178. Avoid creating custom tables when possible as other GMOD tools may not recognize these tables
  179. nor the data in them. Linker tables or property tables are often a good candidate for
  180. a custom table. For example a table to link stocks and libraries (e.g. library_stock) would be
  181. a good custom table. Try to model linker or propery tables after existing tables. If the
  182. table already exists it will not be modified. To force dropping and recreation of the table
  183. click the checkbox below.
  184. '),
  185. );
  186. $form['force_drop']= array(
  187. '#type' => 'checkbox',
  188. '#title' => t('Re-create table'),
  189. '#description' => t('Check this box if your table already exists and you would like to drop it and recreate it.'),
  190. '#default_value' => $default_force_drop,
  191. );
  192. $form['schema']= array(
  193. '#type' => 'textarea',
  194. '#title' => t('Schema Array'),
  195. '#description' => t('Please enter the Drupal Schema API compatible array that defines the table.'),
  196. '#required' => FALSE,
  197. '#default_value' => $default_schema,
  198. '#rows' => 25,
  199. );
  200. if ($action == 'Edit') {
  201. $value = 'Save';
  202. }
  203. if ($action == 'Add') {
  204. $value = 'Add';
  205. }
  206. $form['submit'] = array(
  207. '#type' => 'submit',
  208. '#value' => t($value),
  209. '#executes_submit_callback' => TRUE,
  210. );
  211. $form['#redirect'] = 'admin/tripal/custom_tables';
  212. $form['example']= array(
  213. '#type' => 'item',
  214. '#description' => "<br>Example library_stock table: <pre>
  215. array (
  216. 'table' => 'library_stock',
  217. 'fields' => array (
  218. 'library_stock_id' => array(
  219. 'type' => 'serial',
  220. 'not null' => TRUE,
  221. ),
  222. 'library_id' => array(
  223. 'type' => 'int',
  224. 'not null' => TRUE,
  225. ),
  226. 'stock_id' => array(
  227. 'type' => 'int',
  228. 'not null' => TRUE,
  229. ),
  230. ),
  231. 'primary key' => array(
  232. 'library_stock_id'
  233. ),
  234. 'unique keys' => array(
  235. 'library_stock_c1' => array(
  236. 'library_id',
  237. 'stock_id'
  238. ),
  239. ),
  240. 'foreign keys' => array(
  241. 'library' => array(
  242. 'table' => 'library',
  243. 'columns' => array(
  244. 'library_id' => 'library_id',
  245. ),
  246. ),
  247. 'stock' => array(
  248. 'table' => 'stock',
  249. 'columns' => array(
  250. 'stock_id' => 'stock_id',
  251. ),
  252. ),
  253. ),
  254. )
  255. </pre>",
  256. );
  257. return $form;
  258. }
  259. /**
  260. * Validate the Create/Edit custom table form
  261. * Implements hook_form_validate().
  262. *
  263. * @ingroup tripal_core
  264. */
  265. function tripal_custom_tables_form_validate($form, &$form_state) {
  266. $action = $form_state['values']['action'];
  267. $table_id = $form_state['values']['table_id'];
  268. $schema = $form_state['values']['schema'];
  269. $force_drop = $form_state['values']['force_drop'];
  270. if (!$schema) {
  271. form_set_error($form_state['values']['schema'],
  272. t('Schema array field is required.'));
  273. }
  274. // make sure the array is valid
  275. $schema_array = array();
  276. if ($schema) {
  277. $success = preg_match('/^\s*array/', $schema);
  278. if (!$success) {
  279. form_set_error($form_state['values']['schema'],
  280. t("The schema array should begin with the word 'array'."));
  281. }
  282. else {
  283. $success = eval("\$schema_array = $schema;");
  284. if ($success === FALSE) {
  285. $error = error_get_last();
  286. form_set_error($form_state['values']['schema'],
  287. t("The schema array is improperly formatted. Parse Error : " . $error["message"]));
  288. }
  289. if (is_array($schema_array) and !array_key_exists('table', $schema_array)) {
  290. form_set_error($form_state['values']['schema'],
  291. t("The schema array must have key named 'table'"));
  292. }
  293. if ($action == 'Edit') {
  294. // see if the table name has changed. If so, then check to make sure
  295. // it doesn't already exists. We don't want to drop a table we didn't mean to
  296. $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_id = :table_id";
  297. $results = db_query($sql, array(':table_id' => $table_id));
  298. $ct = $results->fetchObject();
  299. if ($ct->table_name != $schema_array['table']) {
  300. $exists = db_table_exists('chado.' . $schema_array['table']);
  301. if ($exists) {
  302. form_set_error($form_state['values']['schema'],
  303. t("The table name already exists, please choose a different name."));
  304. }
  305. }
  306. }
  307. }
  308. }
  309. }
  310. /**
  311. * Submit the Create/Edit Custom table form
  312. * Implements hook_form_submit().
  313. *
  314. * @ingroup tripal_core
  315. */
  316. function tripal_custom_tables_form_submit($form, &$form_state) {
  317. $ret = array();
  318. $action = $form_state['values']['action'];
  319. $table_id = $form_state['values']['table_id'];
  320. $schema = $form_state['values']['schema'];
  321. $force_drop = $form_state['values']['force_drop'];
  322. $skip_creation = 1;
  323. if ($force_drop) {
  324. $skip_creation = 0;
  325. }
  326. // conver the schema into a PHP array
  327. $schema_arr = array();
  328. eval("\$schema_arr = $schema;");
  329. if (strcmp($action, 'Edit') == 0) {
  330. tripal_core_edit_custom_table($table_id, $schema_arr['table'], $schema_arr, $skip_creation);
  331. }
  332. elseif (strcmp($action, 'Add') == 0) {
  333. tripal_core_create_custom_table($schema_arr['table'], $schema_arr, $skip_creation);
  334. }
  335. else {
  336. drupal_set_message(t("No action performed."));
  337. }
  338. return '';
  339. }
  340. /**
  341. * Does the specified action for the specified custom table
  342. *
  343. * @param $op
  344. * The action to be taken. Currenly only delete is available
  345. * @param $table_id
  346. * The unique ID of the custom table for the action to be performed on
  347. * @param $redirect
  348. * TRUE/FALSE depending on whether you want to redirect the user to admin/tripal/custom_tables
  349. *
  350. * @ingroup tripal_core
  351. */
  352. function tripal_custom_tables_action($op, $table_id, $redirect = FALSE) {
  353. global $user;
  354. $args = array("$table_id");
  355. if (!$table_id) {
  356. return '';
  357. }
  358. // get this table details
  359. $sql = "SELECT * FROM {tripal_custom_tables} WHERE table_id = :table_id";
  360. $results = db_query($sql, array(':table_id' => $table_id));
  361. $custom_table = $results->fetchObject();
  362. if ($op == 'delete') {
  363. // remove the entry from the tripal_custom tables table
  364. $sql = "DELETE FROM {tripal_custom_tables} " .
  365. "WHERE table_id = $table_id";
  366. db_query($sql);
  367. // drop the table from chado if it exists
  368. if (db_table_exists($custom_table->table_name)) {
  369. $success = chado_query("DROP TABLE %s", $custom_table->table_name);
  370. if ($success) {
  371. drupal_set_message(t("Custom Table '%name' dropped", array('%name' => $custom_table->table_name)));
  372. }
  373. }
  374. }
  375. // Redirect the user
  376. if ($redirect) {
  377. drupal_goto("admin/tripal/custom_tables");
  378. }
  379. }