tripal_analysis.form.inc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. <?php
  2. /**
  3. * When editing or creating a new node of type 'chado_analysis' we need
  4. * a form. This function creates the form that will be used for this.
  5. *
  6. * @ingroup tripal_analysis
  7. */
  8. function chado_analysis_form($node, &$form_state) {
  9. $form = array();
  10. // if the organism is part of the node object then we are editing. If not we are inserting
  11. $analysis_id = null;
  12. if (property_exists($node, 'analysis')) {
  13. $analysis = $node->analysis;
  14. $analysis = tripal_core_expand_chado_vars($analysis, 'field', 'analysis.description');
  15. $analysis_id = $analysis->analysis_id;
  16. // get form defaults
  17. $analysisname = property_exists($node, 'analysisname') ? property_exists($node, 'analysisname') : $analysis->analysisname;
  18. $program = property_exists($node, 'program') ? property_exists($node, 'program') : $analysis->program;
  19. $programversion = property_exists($node, 'programversion') ? property_exists($node, 'programversion') : $analysis->programversion;
  20. $algorithm = property_exists($node, 'algorithm') ? property_exists($node, 'algorithm') : $analysis->algorithm;
  21. $sourcename = property_exists($node, 'sourcename') ? property_exists($node, 'sourcename') : $analysis->sourcename;
  22. $sourceversion = property_exists($node, 'sourceversion') ? property_exists($node, 'sourceversion') : $analysis->sourceversion;
  23. $sourceuri = property_exists($node, 'sourceuri') ? property_exists($node, 'sourceuri') : $analysis->sourceuri;
  24. $timeexecuted = property_exists($node, 'timeexecuted') ? property_exists($node, 'timeexecuted') : $analysis->timeexecuted;
  25. $description = property_exists($node, 'description') ? property_exists($node, 'description') : $analysis->description;
  26. // set the organism_id in the form
  27. $form['analysis_id'] = array(
  28. '#type' => 'value',
  29. '#value' => $analysis->analysis_id,
  30. );
  31. }
  32. else {
  33. $analysisname = property_exists($node, 'analysisname') ? property_exists($node, 'analysisname') : '';
  34. $program = property_exists($node, 'program') ? property_exists($node, 'program') : '';
  35. $programversion = property_exists($node, 'programversion') ? property_exists($node, 'programversion') : '';
  36. $algorithm = property_exists($node, 'algorithm') ? property_exists($node, 'algorithm') : '';
  37. $sourcename = property_exists($node, 'sourcename') ? property_exists($node, 'sourcename') : '';
  38. $sourceversion = property_exists($node, 'sourceversion') ? property_exists($node, 'sourceversion') : '';
  39. $sourceuri = property_exists($node, 'sourceuri') ? property_exists($node, 'sourceuri') : '';
  40. $timeexecuted = property_exists($node, 'timeexecuted') ? property_exists($node, 'timeexecuted') : '';
  41. $description = property_exists($node, 'description') ? property_exists($node, 'description') : '';
  42. }
  43. $form['title']= array(
  44. '#type' => 'value',
  45. '#default_value' => $node->title,
  46. );
  47. $form['analysisname']= array(
  48. '#type' => 'textfield',
  49. '#title' => t('Analysis Name'),
  50. '#required' => TRUE,
  51. '#default_value' => $analysisname,
  52. '#description' => t("This should be a brief name that
  53. describes the analysis succintly. This name will helps the user find analyses."),
  54. );
  55. $form['program']= array(
  56. '#type' => 'textfield',
  57. '#title' => t('Program'),
  58. '#required' => TRUE,
  59. '#default_value' => $program,
  60. '#description' => t("Program name, e.g. blastx, blastp, sim4, genscan."),
  61. );
  62. $form['programversion']= array(
  63. '#type' => 'textfield',
  64. '#title' => t('Program Version'),
  65. '#required' => TRUE,
  66. '#default_value' => $programversion,
  67. '#description' => t("Version description, e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]. Enter 'n/a' if no version is available."),
  68. );
  69. $form['algorithm']= array(
  70. '#type' => 'textfield',
  71. '#title' => t('Algorithm'),
  72. '#required' => FALSE,
  73. '#default_value' => $algorithm,
  74. '#description' => t("Algorithm name, e.g. blast."),
  75. );
  76. $form['sourcename']= array(
  77. '#type' => 'textfield',
  78. '#title' => t('Source Name'),
  79. '#required' => TRUE,
  80. '#default_value' => $sourcename,
  81. '#description' => t('The name of the source data. This could be a file name, data set name or a
  82. small description for how the data was collected. For long descriptions use the description field below'),
  83. );
  84. $form['sourceversion']= array(
  85. '#type' => 'textfield',
  86. '#title' => t('Source Version'),
  87. '#required' => FALSE,
  88. '#default_value' => $sourceversion,
  89. '#description' => t('If the source dataset has a version, include it here'),
  90. );
  91. $form['sourceuri']= array(
  92. '#type' => 'textfield',
  93. '#title' => t('Source URI'),
  94. '#required' => FALSE,
  95. '#default_value' => $sourceuri,
  96. '#description' => t("This is a permanent URL or URI for the source of the analysis.
  97. Someone could recreate the analysis directly by going to this URI and
  98. fetching the source data (e.g. the blast database, or the training model)."),
  99. );
  100. // Get time saved in chado
  101. $default_time = $timeexecuted;
  102. $year = preg_replace("/^(\d+)-\d+-\d+ .*/", "$1", $default_time);
  103. $month = preg_replace("/^\d+-0?(\d+)-\d+ .*/", "$1", $default_time);
  104. $day = preg_replace("/^\d+-\d+-0?(\d+) .*/", "$1", $default_time);
  105. // If the time is not set, use current time
  106. if (!$default_time) {
  107. $default_time = REQUEST_TIME;
  108. $year = format_date($default_time, 'custom', 'Y');
  109. $month = format_date($default_time, 'custom', 'n');
  110. $day = format_date($default_time, 'custom', 'j');
  111. }
  112. $form['timeexecuted']= array(
  113. '#type' => 'date',
  114. '#title' => t('Time Executed'),
  115. '#required' => TRUE,
  116. '#default_value' => array(
  117. 'year' => $year,
  118. 'month' => $month,
  119. 'day' => $day,
  120. ),
  121. );
  122. $form['description']= array(
  123. '#type' => 'textarea',
  124. '#rows' => 15,
  125. '#title' => t('Materials & Methods (Description and/or Program Settings)'),
  126. '#required' => FALSE,
  127. '#default_value' => $description,
  128. '#description' => t('Please provide all necessary information to allow
  129. someone to recreate the analysis, including materials and methods
  130. for collection of the source data and performing the analysis'),
  131. );
  132. $form['properties'] = array(
  133. '#type' => 'fieldset',
  134. '#title' => t('Analysis Details'),
  135. '#description' => t('You may add additional properties by
  136. selecting a property type from the dropdown and adding text. You may add
  137. as many properties as desired by clicking the plus button on the right. To
  138. remove a property, click the minus button. If a property is not available
  139. you may add it by ' . l('adding the term', 'admin/tripal/tripal_cv/cvterm/add') . '
  140. to the <b>analysis_property</b> vocabulary within the <b>tripal</b> database'),
  141. );
  142. $form['properties']['table'] = array(
  143. '#type' => 'markup',
  144. '#value' => '',
  145. '#prefix' => '<div id="tripal-analysis-edit-properties-table">',
  146. '#suffix' => '</div>',
  147. );
  148. // get the analysis properties
  149. $properties_select = array();
  150. $properties_select[] = 'Select a Property';
  151. $properties_list = array();
  152. $sql = "
  153. SELECT DISTINCT CVT.cvterm_id, CVT.name, CVT.definition
  154. FROM {cvterm} CVT
  155. INNER JOIN {cv} ON CVT.cv_id = CV.cv_id
  156. WHERE
  157. CV.name = 'analysis_property' AND
  158. NOT CVT.is_obsolete = 1
  159. ORDER BY CVT.name ASC
  160. ";
  161. $prop_types = chado_query($sql);
  162. while ($prop = $prop_types->fetchObject()) {
  163. $properties_select[$prop->cvterm_id] = $prop->name;
  164. $properties_list[$prop->cvterm_id] = $prop;
  165. }
  166. // initialize our arrays of properties and properties removed
  167. $d_properties = array();
  168. $d_removed = array();
  169. // on AJAX callbacks we want to keep a list of all the properties that have been removed
  170. // we'll store this info in a hidden field and retrieve it here
  171. if (array_key_exists('values', $form_state) and array_key_exists('removed', $form_state['values'])) {
  172. // add the removed item to our array and get the number of new fields that have been added
  173. $d_removed = $form_state['values']['removed'];
  174. $num_new = $form_state['values']['num_new'] ? $form_state['values']['num_new'] : 0;
  175. }
  176. // add in the properties from the Chado analysisprop table (only pertains to existing analyses)
  177. $num_properties = 0;
  178. if ($analysis_id) {
  179. $num_properties += chado_analysis_node_form_add_analysisprop_table_props($form, $form_state, $analysis_id, $d_properties, $d_removed);
  180. }
  181. // add in any new properties that have been added by the user through an AHAH callback
  182. $num_new = chado_analysis_node_form_add_new_props($form, $form_state, $d_properties, $d_removed);
  183. // add an empty row of field to allow for addition of a new property
  184. chado_analysis_node_form_add_new_empty_props($form, $form_state, $properties_select);
  185. $form['#theme'] = 'chado_analysis_form';
  186. return $form;
  187. }
  188. /**
  189. *
  190. *
  191. */
  192. function chado_analysis_node_form_add_new_empty_props(&$form, &$form_state, $properties_select) {
  193. $description = '';
  194. if (array_key_exists('values', $form_state) and
  195. array_key_exists('new_id', $form_state['values'])) {
  196. $id = $form_state['values']['new_id'];
  197. $values = array('cvterm_id' => $id);
  198. $cvterm = tripal_core_chado_select('cvterm', array('definition'), $values);
  199. if ($cvterm[0]->definition) {
  200. $description = $cvterm[0]->definition;
  201. }
  202. }
  203. // add one more blank set of property fields
  204. $form['properties']['table']['new']["new_id"] = array(
  205. '#type' => 'select',
  206. '#options' => $properties_select,
  207. '#ajax' => array(
  208. 'callback' => "tripal_analysis_property_get_description",
  209. 'wrapper' => 'tripal-analysis-new_value',
  210. 'effect' => 'fade',
  211. 'method' => 'replace',
  212. ),
  213. );
  214. $form['properties']['table']['new']["new_value"] = array(
  215. '#type' => 'textarea',
  216. '#default_value' => '',
  217. '#cols' => 5,
  218. '#rows' => 2,
  219. '#prefix' => '<div id="tripal-analysis-new_value">',
  220. '#description' => $description,
  221. '#sffix' => '</div>',
  222. );
  223. $form['properties']['table']['new']["add"] = array(
  224. '#type' => 'image_button',
  225. '#default_value' => t('Add'),
  226. '#src' => drupal_get_path('module', 'tripal_core') . '/theme/images/add.png',
  227. '#ajax' => array(
  228. 'callback' => "tripal_analysis_property_add",
  229. 'wrapper' => 'tripal-analysis-edit-properties-table',
  230. 'effect' => 'fade',
  231. 'event' => 'click',
  232. 'method' => 'replace',
  233. ),
  234. '#attributes' => array('onClick' => 'return false;'),
  235. );
  236. }
  237. /*
  238. *
  239. */
  240. function chado_analysis_node_form_add_new_props(&$form, &$form_state, &$d_properties, &$d_removed) {
  241. // first, add in all of the new properties that were added through a previous AHAH callback
  242. $j = 0;
  243. $num_properties = 0;
  244. // we need to find the
  245. if (array_key_exists('values', $form_state)) {
  246. foreach ($form_state['values'] as $element_name => $value) {
  247. if (preg_match('/new_value-(\d+)-(\d+)/', $element_name, $matches)) {
  248. $new_id = $matches[1];
  249. $rank = $matches[2];
  250. // skip any properties that the user requested to delete through a previous
  251. // AHAH callback or through the current AHAH callback
  252. if ($d_removed["$new_id-$rank"]) {
  253. continue;
  254. }
  255. if ($form_state['post']['remove-' . $new_id . '-' . $rank]) {
  256. $d_removed["$new_id-$rank"] = 1;
  257. continue;
  258. }
  259. // get this new_id information
  260. $cvterm = tripal_core_chado_select('cvterm', array('name', 'definition'), array('cvterm_id' => $new_id));
  261. // add it to the $d_properties array
  262. $d_properties[$new_id][$rank]['name'] = $cvterm->name;
  263. $d_properties[$new_id][$rank]['id'] = $new_id;
  264. $d_properties[$new_id][$rank]['value'] = $value;
  265. $d_properties[$new_id][$rank]['definition'] = $cvterm->definition;
  266. $num_properties++;
  267. // determine how many rows we need in the textarea
  268. $rows = 1;
  269. // add the new fields
  270. $form['properties']['table']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
  271. '#type' => 'item',
  272. '#value' => $cvterm[0]->name
  273. );
  274. $form['properties']['table']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
  275. '#type' => 'textarea',
  276. '#default_value' => $value,
  277. '#cols' => 50,
  278. '#rows' => $rows,
  279. '#description' => $cvterm->definition,
  280. );
  281. $form['properties']['table']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
  282. '#type' => 'image_button',
  283. '#value' => t('Remove'),
  284. '#src' => drupal_get_path('theme', 'tripal') . '/images/minus.png',
  285. '#ajax' => array(
  286. 'callback' => "tripal_analysis/properties/minus/$new_id/$rank",
  287. 'wrapper' => 'tripal-analysis-edit-properties-table',
  288. 'effect' => 'fade',
  289. 'event' => 'click',
  290. 'method' => 'replace',
  291. ),
  292. '#attributes' => array('onClick' => 'return false;'),
  293. );
  294. }
  295. }
  296. }
  297. // second add in any new properties added during this callback
  298. if (array_key_exists('post', $form_state) and array_key_exists('add', $form_state['post'])) {
  299. $new_id = $form_state['values']['new_id'];
  300. $new_value = $form_state['values']['new_value'];
  301. // get the rank by counting the number of entries
  302. $rank = count($d_properties[$new_id]);
  303. // get this new_id information
  304. $cvterm = tripal_core_chado_select('cvterm', array('name', 'definition'), array('cvterm_id' => $new_id));
  305. // add it to the $d_properties array
  306. $d_properties[$new_id][$rank]['name'] = $cvterm->name;
  307. $d_properties[$new_id][$rank]['id'] = $new_id;
  308. $d_properties[$new_id][$rank]['value'] = $value;
  309. $d_properties[$new_id][$rank]['definition'] = $cvterm->definition;
  310. $num_properties++;
  311. // determine how many rows we need in the textarea
  312. $rows = 1;
  313. // add the new fields
  314. $form['properties']['table']['new'][$new_id][$rank]["new_id-$new_id-$rank"] = array(
  315. '#type' => 'item',
  316. '#value' => $cvterm[0]->name
  317. );
  318. $form['properties']['table']['new'][$new_id][$rank]["new_value-$new_id-$rank"] = array(
  319. '#type' => 'textarea',
  320. '#default_value' => $new_value,
  321. '#cols' => 50,
  322. '#rows' => $rows,
  323. '#description' => $cvterm->definition,
  324. );
  325. $form['properties']['table']['new'][$new_id][$rank]["remove-$new_id-$rank"] = array(
  326. '#type' => 'image_button',
  327. '#value' => t('Remove'),
  328. '#src' => drupal_get_path('theme', 'tripal') . '/images/minus.png',
  329. '#ahah' => array(
  330. 'path' => "tripal_analysis/properties/minus/$new_id/$rank",
  331. 'wrapper' => 'tripal-analysis-edit-properties-table',
  332. 'event' => 'click',
  333. 'method' => 'replace',
  334. ),
  335. '#attributes' => array('onClick' => 'return false;'),
  336. );
  337. }
  338. return $num_properties;
  339. }
  340. /*
  341. *
  342. */
  343. function chado_analysis_node_form_add_analysisprop_table_props(&$form, $form_state, $analysis_id, &$d_properties, &$d_removed) {
  344. // get the properties for this analysis
  345. $num_properties = 0;
  346. if (!$analysis_id) {
  347. return $num_properties;
  348. }
  349. $sql = "
  350. SELECT CVT.cvterm_id, CVT.name, CVT.definition, PP.value, PP.rank
  351. FROM {analysisprop} PP
  352. INNER JOIN {cvterm} CVT on CVT.cvterm_id = PP.type_id
  353. INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
  354. WHERE PP.analysis_id = :analysis_id and CV.name = 'analysis_property'
  355. ORDER BY CVT.name, PP.rank
  356. ";
  357. $analysis_props = chado_query($sql, array(':analysis_id' => $analysis_id));
  358. while ($prop = $analysis_props->fetchObject()) {
  359. $type_id = $prop->cvterm_id;
  360. $rank = count($d_properties[$type_id]);
  361. // skip any properties that the user requested to delete through a previous
  362. // AHAH callback or through the current AHAH callback
  363. if ($d_removed["$type_id-$rank"]) {
  364. continue;
  365. }
  366. if ($form_state['post']['remove-' . $type_id . '-' . $rank]) {
  367. $d_removed["$type_id-$rank"] = 1;
  368. continue;
  369. }
  370. $d_properties[$type_id][$rank]['name'] = $prop->name;
  371. $d_properties[$type_id][$rank]['id'] = $type_id;
  372. $d_properties[$type_id][$rank]['value'] = $prop->value;
  373. $d_properties[$type_id][$rank]['definition'] = $prop->definition;
  374. $num_properties++;
  375. $form['properties']['table'][$type_id][$rank]["prop_id-$type_id-$rank"] = array(
  376. '#type' => 'item',
  377. '#value' => $prop->name,
  378. );
  379. $form['properties']['table'][$type_id][$rank]["prop_value-$type_id-$rank"] = array(
  380. '#type' => 'textarea',
  381. '#default_value' => $prop->value,
  382. '#cols' => 50,
  383. '#rows' => $rows,
  384. '#description' => $prop->definition,
  385. );
  386. $form['properties']['table'][$type_id][$rank]["remove-$type_id-$rank"] = array(
  387. '#type' => 'image_button',
  388. '#value' => t('Remove'),
  389. '#src' => drupal_get_path('theme', 'tripal') . '/images/minus.png',
  390. '#ahah' => array(
  391. 'path' => "tripal_analysis/properties/minus/$type_id/$rank",
  392. 'wrapper' => 'tripal-analysis-edit-properties-table',
  393. 'event' => 'click',
  394. 'method' => 'replace',
  395. ),
  396. '#attributes' => array('onClick' => 'return false;'),
  397. );
  398. }
  399. return $num_properties;
  400. }
  401. /**
  402. * Validates the user input before creating an analysis node
  403. *
  404. * @ingroup tripal_analysis
  405. */
  406. function chado_analysis_validate($node, &$form) {
  407. // use the analysis parent to validate the node
  408. tripal_analysis_validate($node, $form);
  409. }
  410. /**
  411. * This validation is being used for three activities:
  412. * CASE A: Update a node that exists in both drupal and chado
  413. * CASE B: Synchronizing a node from chado to drupal
  414. * CASE C: Inserting a new node that exists in niether drupal nor chado
  415. *
  416. * @ingroup tripal_analysis
  417. */
  418. function tripal_analysis_validate($node, &$form) {
  419. $node->analysisname = trim($node->analysisname);
  420. $node->description = trim($node->description);
  421. $node->program = trim($node->program);
  422. $node->programversion = trim($node->programversion);
  423. $node->algorithm = trim($node->algorithm);
  424. $node->sourcename = trim($node->sourcename);
  425. $node->sourceversion = trim($node->sourceversion);
  426. $node->sourceuri = trim($node->sourceuri);
  427. // Only nodes being updated will have an nid already
  428. if (!is_null($node->nid)) {
  429. // CASE A: We are validating a form for updating an existing node
  430. // get the existing node
  431. $values = array('analysis_id' => $node->analysis_id);
  432. $result = tripal_core_chado_select('analysis', array('*'), $values);
  433. $analysis = $result[0];
  434. // if the name has changed make sure it doesn't conflict with an existing name
  435. if ($analysis->name != $node->analysisname) {
  436. $values = array('name' => $node->analysisname);
  437. $result = tripal_core_chado_select('analysis', array('analysis_id'), $values);
  438. if ($result and count($result) > 0) {
  439. form_set_error('analysisname', 'Cannot update the analysis with this analysis name. An analysis with this name already exists.');
  440. return;
  441. }
  442. }
  443. // if the unique constraint has changed check to make sure it doesn't conflict with an
  444. // existing record
  445. if ($analysis->program != $node->program or $analysis->programversion != $node->programversion or
  446. $analysis->sourcename != $node->sourcename) {
  447. $values = array(
  448. 'program' => $node->program,
  449. 'programversion' => $node->programversion,
  450. 'sourcename' => $node->sourcename,
  451. );
  452. $result = tripal_core_chado_select('analysis', array('analysis_id'), $values);
  453. if ($result and count($result) > 0) {
  454. if ($analysis->program != $node->program) {
  455. $field = 'program';
  456. }
  457. if ($analysis->programversion != $node->programversion) {
  458. $field = 'programversion';
  459. }
  460. if ($analysis->sourcename != $node->sourcename) {
  461. $field = 'sourcename';
  462. }
  463. form_set_error($field, 'Cannot update the analysis with this program,
  464. program version and source name. An analysis with these values already exists.');
  465. return;
  466. }
  467. }
  468. }
  469. else {
  470. // To differentiate if we are syncing or creating a new analysis altogther, see if an
  471. // analysis_id already exists
  472. if ($node->analysis_id and $node->analysis_id != 0) {
  473. // CASE B: Synchronizing a node from chado to drupal
  474. // we don't need to do anything.
  475. }
  476. else {
  477. // CASE C: We are validating a form for inserting a new node
  478. // The unique constraint for the chado analysis table is: program, programversion, sourcename
  479. $values = array(
  480. 'program' => $node->program,
  481. 'programversion' => $node->programversion,
  482. 'sourcename' => $node->sourcename,
  483. );
  484. $analysis = tripal_core_chado_select('analysis', array('analysis_id'), $values);
  485. if ($analysis and count($analysis) > 0) {
  486. form_set_error('program', 'Cannot add the analysis with this program,
  487. program version and source name. An analysis with these values already exists.');
  488. return;
  489. }
  490. // make sure we have a unique analysis name. This is not a requirement
  491. // for the analysis table but we use the analysis name for the Drupal node
  492. // title, so it should be unique
  493. $values = array('name' => $node->analysisname);
  494. $result = tripal_core_chado_select('analysis', array('analysis_id'), $values);
  495. if ($result and count($result) > 0) {
  496. form_set_error('analysisname', 'Cannot add the analysis with this analysis name. An analysis with this name already exists.');
  497. return;
  498. }
  499. }
  500. }
  501. }
  502. /*
  503. *
  504. */
  505. function tripal_analysis_theme_node_form_properties($form) {
  506. $rows = array();
  507. if (array_key_exists('properties', $form)) {
  508. // first add in the properties derived from the analysisprop table
  509. // the array tree for these properties looks like this:
  510. // $form['properties']['table'][$type_id][$rank]["prop_id-$type_id-$rank"]
  511. foreach ($form['properties']['table'] as $type_id => $elements) {
  512. // there are other fields in the properties array so we only
  513. // want the numeric ones those are our type_id
  514. if (is_numeric($type_id)) {
  515. foreach ($elements as $rank => $element) {
  516. if (is_numeric($rank)) {
  517. $rows[] = array(
  518. drupal_render($element["prop_id-$type_id-$rank"]),
  519. drupal_render($element["prop_value-$type_id-$rank"]),
  520. drupal_render($element["remove-$type_id-$rank"]),
  521. );
  522. }
  523. }
  524. }
  525. }
  526. // second, add in any new properties added by the user through AHAH callbacks
  527. // the array tree for these properties looks like this:
  528. // $form['properties']['table']['new'][$type_id][$rank]["new_id-$new_id-$rank"]
  529. foreach ($form['properties']['table']['new'] as $type_id => $elements) {
  530. if (is_numeric($type_id)) {
  531. foreach ($elements as $rank => $element) {
  532. if (is_numeric($rank)) {
  533. $rows[] = array(
  534. drupal_render($element["new_id-$type_id-$rank"]),
  535. drupal_render($element["new_value-$type_id-$rank"]),
  536. drupal_render($element["remove-$type_id-$rank"]),
  537. );
  538. }
  539. }
  540. }
  541. }
  542. // finally add in a set of blank field for adding a new property
  543. $rows[] = array(
  544. drupal_render($form['properties']['table']['new']['new_id']),
  545. array(
  546. 'data' => drupal_render($form['properties']['table']['new']['new_value']),
  547. 'width' => '60%',
  548. ),
  549. drupal_render($form['properties']['table']['new']['add']),
  550. );
  551. }
  552. $headers = array('Property Type', 'Value', '');
  553. $table = array(
  554. 'header' => $headers,
  555. 'rows' => $rows,
  556. 'attributes' => array(
  557. 'id' => 'tripal_analysis-edit-properties-table',
  558. ),
  559. 'sticky' => TRUE,
  560. 'caption' => '',
  561. 'colgroups' => array(),
  562. 'empty' => '',
  563. );
  564. return theme_table($table);
  565. }
  566. /**
  567. * Form AJAX callback for adding a blank property row
  568. *
  569. * We only want to return the properties as that's all we'll replace with this callback
  570. */
  571. function tripal_analysis_property_add($form, $form_state) {
  572. return tripal_analysis_theme_node_form_properties($form);
  573. }
  574. /**
  575. * Form AJAX callback for deleting properties
  576. *
  577. */
  578. function tripal_analysis_property_delete($form, $form_state) {
  579. return tripal_analysis_theme_node_form_properties($form);
  580. }
  581. /**
  582. * Form AJAX callback for updating a property description. This
  583. * function only gets called when the property drop down is changed
  584. * on the bottom (empty) row of properties
  585. */
  586. function tripal_analysis_property_get_description($form, $form_state) {
  587. return $form['properties']['table']['new']["new_value"];
  588. }
  589. /**
  590. * We need to theme the analysis form so that the properties fields look good
  591. */
  592. function theme_chado_analysis_form($variables) {
  593. $form = $variables['form'];
  594. $properties_table = tripal_analysis_theme_node_form_properties($form);
  595. $markup = $properties_table;
  596. $form['properties']['table'] = array(
  597. '#markup' => $markup,
  598. '#prefix' => '<div id="tripal-analysis-edit-properties-table">',
  599. '#suffix' => '</div>',
  600. );
  601. $form['buttons']['#weight'] = 50;
  602. return drupal_render_children($form);
  603. }