tripal_bulk_loader.admin.inc 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269
  1. <?php
  2. /**
  3. * @file
  4. * Handles Create/Edit/Delete Template Admin Forms
  5. */
  6. /**
  7. * Provides a description page and quick links for the bulk loader
  8. */
  9. function tripal_bulk_loader_admin_template() {
  10. $output = '';
  11. $output .= '<br><h3>Quick Links:</h3>';
  12. $output .= l('Create a new bulk loader template', 'admin/tripal/tripal_bulk_loader_template/create') . "<br>";
  13. $output .= l('Edit a bulk loader template', 'admin/tripal/tripal_bulk_loader_template/edit') . "<br>";
  14. $output .= l('Delete a bulk loader template', 'admin/tripal/tripal_bulk_loader_template/delete') . "<br>";
  15. $output .= l('Export a bulk loader template', 'admin/tripal/tripal_bulk_loader_template/export') . "<br>";
  16. $output .= l('Import a bulk loader template', 'admin/tripal/tripal_bulk_loader_template/import') . "<br>";
  17. $output .= '<br>';
  18. $output .= '<h3>Module Description:</h3>';
  19. $output .= '<p>This module provides the ability to create loading templates for any tab-delimited '
  20. . 'data file allowing it to be loaded into chado. The Loading Templates are a direct mapping '
  21. . 'between the columns in your file and the columns in chado tables. As such to use this tool '
  22. . 'you need to be very familar with the chado schema -See '
  23. . l('Chado -Getting Started', 'http://gmod.org/wiki/Chado_-_Getting_Started')
  24. . '. The ability to add constants and specify foreign key contraints is also provided '
  25. . 'in order for the loader to fill chado columns which may be required but are not specified '
  26. . 'in your input file.</p>';
  27. $output .= '<br>';
  28. $output .= '<h3>Setup Instructions</h3>';
  29. $output .= '<p>After intallation of the bulk loader module, the following tasks should be performed:</p>';
  30. $output .= '<ol>';
  31. $output .= '<li><b>Install Theme:</b> In order for Bulk Loading pages to be displayed correctly, '
  32. .'the contents of the Tripal Bulk Loader theme directory ([drupal root]/sites/all/modules/tripal/tripal_bulk_loader/theme) '
  33. .'should be moved to the base directory of the Tripal theme ([drupal root]/sites/all/themes/tripal). '
  34. .'Finally the drupal cache should be cleared for the new theme to take effect -navigate to admin/settings/performance '
  35. .'and click the Clear Cached Data button.</li>';
  36. $output .= '</ol>';
  37. return $output;
  38. }
  39. /**
  40. * A Configuration form for this module
  41. */
  42. function tripal_bulk_loader_configuration_form($form_state = NULL) {
  43. $form = array();
  44. $form['speed'] = array(
  45. '#type' => 'fieldset',
  46. '#title' => t('Possible Speed Improvements'),
  47. );
  48. $form['speed']['prepare'] = array(
  49. '#type' => 'checkbox',
  50. '#title' => t('Use Prepared Statements'),
  51. '#description' => t('SQL Prepared Statements allow for SQL queries which will be run '
  52. .'many times to be parsed, rewritten and planned only once rather then every time '
  53. .'the query is run. In the case of the bulk loader, this ensures that planning only '
  54. .'occurs once for each "record" in your bulk loading template.'),
  55. '#default_value' => variable_get('tripal_bulk_loader_prepare', TRUE),
  56. );
  57. $form['speed']['disable_triggers'] = array(
  58. '#type' => 'checkbox',
  59. '#title' => t('Delay Constraint Checking during loading job.'),
  60. '#description' => t('This delays the constraint checking until the end of the
  61. loading proccess.'),
  62. '#default_value' => variable_get('tripal_bulk_loader_disable_triggers', TRUE),
  63. );
  64. $form['speed']['no_validate'] = array(
  65. '#type' => 'checkbox',
  66. '#title' => t('Skip Validation at the Tripal Core API level'),
  67. '#description' => t('If an error is encountered, the Tripal core API will try
  68. to provide informative error messages. With this turned off, you will not benifit
  69. from these more informative error messages; however, your job will load faster
  70. since it doesn\'t have to do the additional checking before inserting.'),
  71. '#default_value' => variable_get('tripal_bulk_loader_skip_validation', FALSE),
  72. );
  73. $form['speed']['transactions'] = array(
  74. '#type' => 'radios',
  75. '#title' => t('Transaction Rollback when an error is encountered'),
  76. '#options' => array(
  77. 'all' => t('Rollback the last constant set.'
  78. .'<div class="description"If you added more then one constant set then the
  79. successfully loaded constant sets will not be rolled back. However, once an error
  80. is encountered no further constant sets will be loaded either.</div>'),
  81. 'row' => t('Only Rollback the last line of the input file.'
  82. .'<div class="description">This option may allow you to restart the job after
  83. fixing the error (manual intervention needed).</div>'),
  84. 'none' => t('Do not use transactions<div class="description">This is not recommended.</div>')
  85. ),
  86. '#default_value' => variable_get('tripal_bulk_loader_transactions','row')
  87. );
  88. $form['speed']['lock'] = array(
  89. '#type' => 'radios',
  90. '#title' => t('Lock Type'),
  91. '#description' => t('The type of lock used by the bulk loading jobs. The lock is '
  92. .'acquired at the beginning of the job and kept till the end. A lock of the type '
  93. .'selected will be acquired for every table being inserted into.'),
  94. '#options' => array(
  95. 'ROW EXCLUSIVE' => t('ROW EXCLUSIVE: The default lock type for insert queries.'),
  96. 'EXCLUSIVE' => t('EXCLUSIVE: Only Select Queries can access the table.'),
  97. 'ACCESS EXCLUSIVE' => t('ACCESS EXCLUSIVE: No other queries can access the table.'),
  98. ),
  99. '#default_value' => variable_get('tripal_bulk_loader_lock', 'ROW EXCLUSIVE'),
  100. );
  101. $form['submit1'] = array(
  102. '#type' => 'submit',
  103. '#value' => t('Save')
  104. );
  105. return $form;
  106. }
  107. /**
  108. * A Configuration form for this module (Submit)
  109. */
  110. function tripal_bulk_loader_configuration_form_submit($form, $form_state) {
  111. variable_set('tripal_bulk_loader_prepare', $form_state['values']['prepare']);
  112. variable_set('tripal_bulk_loader_disable_triggers', $form_state['values']['disable_triggers']);
  113. variable_set('tripal_bulk_loader_skip_validation', $form_state['values']['no_validate']);
  114. variable_set('tripal_bulk_loader_transactions',$form_state['values']['transactions']);
  115. variable_set('tripal_bulk_loader_lock', $form_state['values']['lock']);
  116. }
  117. //////////////////////////////////////////////////////////////////////////////////////
  118. // Modify Template
  119. //////////////////////////////////////////////////////////////////////////////////////
  120. /**
  121. * The main form reached at admin/tripal/tripal_bulk_loader/create and /edit
  122. */
  123. function tripal_bulk_loader_modify_template_base_form($form_state = NULL, $mode) {
  124. $form = array();
  125. // get template id from path and rebuild form
  126. if ($_GET['template_id']) {
  127. if (preg_match('/^\d+$/', $_GET['template_id'])) {
  128. $form_state['storage']['template_id'] = $_GET['template_id'];
  129. }
  130. $sql = "SELECT * FROM {tripal_bulk_loader_template} WHERE template_id=%d";
  131. $result = db_fetch_object(db_query($sql, $form_state['storage']['template_id']));
  132. $form_state['storage']['template'] = unserialize($result->template_array);
  133. $form_state['storage']['template_name'] = $result->name;
  134. $form_state['storage']['record2priority'] = array();
  135. foreach ($form_state['storage']['template'] as $priority => $record_array) {
  136. if (!is_array($record_array)) {
  137. continue; }
  138. $form_state['storage']['record2priority'][$record_array['record_id']] = $priority;
  139. }
  140. }
  141. $form['mode'] = array(
  142. '#type' => 'hidden',
  143. '#value' => $mode,
  144. );
  145. if ($form_state['storage']['template_id']) {
  146. $form['template_name'] = array(
  147. '#type' => 'item',
  148. '#title' => 'Template',
  149. '#value' => $form_state['storage']['template_name'],
  150. '#weight' => 1,
  151. );
  152. }
  153. else {
  154. if (preg_match('/create/', $mode)) {
  155. $form['new_template_name'] = array(
  156. '#type' => 'textfield',
  157. '#title' => 'Template Name',
  158. '#weight' => 1,
  159. );
  160. }
  161. elseif (preg_match('/edit/', $mode)) {
  162. $sql = "SELECT * FROM {tripal_bulk_loader_template}";
  163. $resource = db_query($sql);
  164. $templates = array();
  165. $templates[''] = 'Select a Template';
  166. while ($r = db_fetch_object($resource)) {
  167. $templates[$r->template_id] = $r->name;
  168. }
  169. $form['template_id'] = array(
  170. '#title' => t('Template'),
  171. '#description' => t('Please select the template you would like to edit.'),
  172. '#type' => 'select',
  173. '#options' => $templates,
  174. '#default_value' => $form_state['storage']['template_id'],
  175. '#weight' => 0,
  176. '#required' => TRUE,
  177. '#weight' => 1,
  178. );
  179. }
  180. }
  181. $form['records'] = array(
  182. '#type' => ($form_state['storage']['template_id'])? 'fieldset' : 'hidden',
  183. '#title' => t('Current Records'),
  184. '#collapsible' => TRUE,
  185. '#weight' => 2,
  186. );
  187. $form['records']['description'] = array(
  188. '#type' => 'item',
  189. '#value' => 'Records will be inserted into the chado database in the order listed below. To '
  190. .'change this order: <ul><li>Drag the rows into the correct order OR</li><li>Enter '
  191. .'the numbers 1 and up in the Order textboxes to indicate the correct order.</li></ul>',
  192. );
  193. $form['records']['records-data'] = array(
  194. '#tree' => TRUE,
  195. );
  196. $form['records']['no_records'] = array(
  197. '#type' => 'hidden',
  198. '#value' => TRUE,
  199. );
  200. $form['records']['submit-new_record'] = array(
  201. '#type' => 'submit',
  202. '#value' => 'New Record/Field',
  203. );
  204. $form['records']['submit-reorder'] = array(
  205. '#type' => 'submit',
  206. '#value' => 'Save Order',
  207. );
  208. $form['fields'] = array(
  209. '#type' => ($form_state['storage']['template_id'])? 'fieldset' : 'hidden',
  210. '#title' => t('Current Fields'),
  211. '#collapsible' => TRUE,
  212. '#weight' => 3,
  213. );
  214. $form['fields']['fields-data'] = array(
  215. '#tree' => TRUE,
  216. );
  217. if ($form_state['storage']['template']) {
  218. // List Current Fields -------------------------------------------------------------
  219. $i=1;
  220. foreach ($form_state['storage']['template'] as $priority => $table_array) {
  221. if (!is_array($table_array)) {
  222. continue; }
  223. $form['records']['no_records']['#value'] = FALSE;
  224. $form['records']['records-data'][$priority] = array(
  225. 'title' => array(
  226. '#type' => 'markup',
  227. '#value' => $table_array['record_id'],
  228. ),
  229. 'chado_table' => array(
  230. '#type' => 'markup',
  231. '#value' => $table_array['table'],
  232. ),
  233. 'mode' => array(
  234. '#type' => 'item',
  235. '#value' => ($table_array['mode']) ? $table_array['mode'] : 'insert_unique',
  236. ),
  237. 'new_priority' => array(
  238. '#type' => 'select',
  239. '#options' => range(1, sizeof($form_state['storage']['template'])),
  240. '#default_value' => $priority,
  241. ),
  242. 'old_priority' => array(
  243. '#type' => 'hidden',
  244. '#value' => $priority,
  245. ),
  246. 'id' => array(
  247. '#type' => 'hidden',
  248. '#value' => $priority,
  249. ),
  250. 'submit-edit_record' => array(
  251. '#type' => 'submit',
  252. '#name' => (string)$priority,
  253. '#value' => 'Edit Record',
  254. ),
  255. 'submit-add_field' => array(
  256. '#type' => 'submit',
  257. '#name' => (string)$priority,
  258. '#value' => 'Add Field',
  259. ),
  260. 'submit-duplicate_record' => array(
  261. '#type' => 'submit',
  262. '#name' => (string)$priority,
  263. '#value' => 'Duplicate Record'
  264. ),
  265. );
  266. foreach ($table_array['fields'] as $field_index => $field) {
  267. $form['fields']['fields-data'][$i] = array(
  268. 'record_id' => array(
  269. '#type' => 'item',
  270. '#value' => $table_array['record_id'],
  271. ),
  272. 'priority_hidden' => array(
  273. '#type' => 'hidden',
  274. '#value' => $priority,
  275. ),
  276. 'field_name' => array(
  277. '#type' => 'item',
  278. '#value' => $field['title'],
  279. ),
  280. 'chado_table_name' => array(
  281. '#type' => 'item',
  282. '#value' => $table_array['table'],
  283. ),
  284. 'chado_table_hidden' => array(
  285. '#type' => 'hidden',
  286. '#value' => $table_array['table'],
  287. ),
  288. 'chado_field_name' => array(
  289. '#type' => 'item',
  290. '#value' => $field['field'],
  291. ),
  292. 'sheet_name' => array(
  293. '#type' => 'item',
  294. '#value' => $field['spreadsheet sheet'],
  295. ),
  296. 'column_num' => array(
  297. '#type' => 'item',
  298. '#value' => $field['spreadsheet column'],
  299. ),
  300. 'constant_value' => array(
  301. '#type' => 'item',
  302. '#value' => $field['constant value'],
  303. ),
  304. 'field_index' => array(
  305. '#type' => 'hidden',
  306. '#value' => $field_index
  307. ),
  308. 'foreign_record_id' => array(
  309. '#type' => 'item',
  310. '#value' => $field['foreign key'],
  311. ),
  312. 'edit_submit' => array(
  313. '#type' => 'submit',
  314. '#name' => (string)$i,
  315. '#value' => "Edit Field",
  316. ),
  317. 'delete_submit' => array(
  318. '#type' => 'submit',
  319. '#name' => (string)$i,
  320. '#value' => "Delete Field",
  321. ),
  322. );
  323. $i++;
  324. }
  325. }
  326. $form['fields']['total_fields'] = array(
  327. '#type' => 'item',
  328. '#value' => $i,
  329. );
  330. }
  331. if ($form['records']['no_records']['#value']) {
  332. $form['records']['description'] = array(
  333. '#type' => 'item',
  334. '#value' => 'There are currently no records.',
  335. );
  336. unset($form['records']['submit-reorder']);
  337. $form['fields']['description'] = array(
  338. '#type' => 'item',
  339. '#value' => 'There are currently no fields.',
  340. );
  341. }
  342. $mode_title = (preg_match('/create/', $mode)) ? 'Create Template' : 'Edit Template';
  343. $value = ($form_state['storage']['template_id'])? 'Save Template' : $mode_title;
  344. $form['submit'] = array(
  345. '#type' => 'submit',
  346. '#value' => $value,
  347. '#weight' => 4,
  348. );
  349. return $form;
  350. }
  351. /**
  352. * Submit for tripal_bulk_loader_modify_template_base_form
  353. */
  354. function tripal_bulk_loader_modify_template_base_form_submit($form, &$form_state) {
  355. $form_state['rebuild'] = TRUE;
  356. if ($form_state['storage']['template_id']) {
  357. $sql = "SELECT * FROM {tripal_bulk_loader_template} WHERE template_id=%d";
  358. $result = db_fetch_object(db_query($sql, $form_state['storage']['template_id']));
  359. $form_state['storage']['template'] = unserialize($result->template_array);
  360. }
  361. $op = $form_state['values'][ $form_state['clicked_button']['#name'] ];
  362. switch ($op) {
  363. // Initialize after template is chosen ----------------------------------------
  364. case 'Edit Template':
  365. $form_state['storage']['template_id'] = $form_state['values']['template_id'];
  366. $sql = "SELECT * FROM {tripal_bulk_loader_template} WHERE template_id=%d";
  367. $result = db_fetch_object(db_query($sql, $form_state['storage']['template_id']));
  368. $form_state['storage']['template'] = unserialize($result->template_array);
  369. $form_state['storage']['template_name'] = $result->name;
  370. $form_state['storage']['record2priority'] = array();
  371. foreach ($form_state['storage']['template'] as $priority => $record_array) {
  372. if (!is_array($record_array)) {
  373. continue;
  374. }
  375. $form_state['storage']['record2priority'][$record_array['record_id']] = $priority;
  376. }
  377. break;
  378. case 'Create Template':
  379. $record = array(
  380. 'name' => $form_state['values']['new_template_name'],
  381. 'template_array' => array(),
  382. );
  383. drupal_write_record('tripal_bulk_loader_template', $record);
  384. $form_state['storage']['template_id'] = $record['template_id'];
  385. $form_state['storage']['template_name'] = $record['name'];
  386. $form_state['storage']['template'] = array();
  387. break;
  388. // Save Reordered Records -----------------------------------------------------
  389. case 'Save Order':
  390. $new_template = $form_state['storage']['template'];
  391. // unset old elements
  392. $form_state['storage']['record2priority'] = array();
  393. foreach ($new_template as $priority => $record_array) {
  394. if (preg_match('/\d+/', $priority)) {
  395. unset($new_template[$priority]);
  396. }
  397. }
  398. //set elements in new order
  399. foreach ($form_state['values']['records-data'] as $item) {
  400. $new_template[$item['new_priority']] = $form_state['storage']['template'][$item['old_priority']];
  401. $record_name = $new_template[$item['new_priority']]['record_id'];
  402. $form_state['storage']['record2priority'][$record_name] = $item['new_priority'];
  403. }
  404. ksort($new_template);
  405. $form_state['storage']['template'] = $new_template;
  406. break;
  407. case 'New Record/Field':
  408. $query = array(
  409. 'template_id' => $form_state['storage']['template_id'],
  410. 'record_id' => 'NEW',
  411. );
  412. drupal_goto('admin/tripal/tripal_bulk_loader_template/add_field', $query);
  413. break;
  414. case 'Edit Record':
  415. $query = array(
  416. 'template_id' => $form_state['storage']['template_id'],
  417. 'record_id' => $form_state['clicked_button']['#name'],
  418. );
  419. drupal_goto('admin/tripal/tripal_bulk_loader_template/edit_record', $query);
  420. break;
  421. case 'Add Field':
  422. $query = array(
  423. 'template_id' => $form_state['storage']['template_id'],
  424. 'record_id' => $form_state['clicked_button']['#name'],
  425. );
  426. drupal_goto('admin/tripal/tripal_bulk_loader_template/add_field', $query);
  427. break;
  428. case 'Duplicate Record':
  429. // original record (one to be duplicated)
  430. $orig_priority = $form_state['clicked_button']['#name'];
  431. $record = $form_state['storage']['template'][ $orig_priority ];
  432. // new record
  433. $new_priority = sizeof($form_state['storage']['template']) + 1;
  434. $record['record_id'] = $record['record_id'] . '_' . date('YzHi');
  435. $form_state['storage']['template'][ $new_priority ] = $record;
  436. break;
  437. case 'Edit Field':
  438. $field_data_index = $form_state['clicked_button']['#name'];
  439. $query = array(
  440. 'template_id' => $form_state['storage']['template_id'],
  441. 'record_id' => $form_state['values']['fields-data'][$field_data_index]['priority_hidden'],
  442. 'field_index' => $form_state['values']['fields-data'][$field_data_index]['field_index'],
  443. );
  444. drupal_goto('admin/tripal/tripal_bulk_loader_template/edit_field', $query);
  445. break;
  446. case 'Delete Field':
  447. $field_data = $form_state['values']['fields-data'][$form_state['clicked_button']['#name']];
  448. $priority = $field_data['priority_hidden'];
  449. $field_key = $field_data['field_index'];
  450. unset($form_state['storage']['template'][$priority]['fields'][$field_key]);
  451. if (!$form_state['storage']['template'][$priority]['fields']) {
  452. unset($form_state['storage']['record2priority'][$form_state['storage']['template'][$priority]['record_id']]);
  453. unset($form_state['storage']['template'][$priority]);
  454. }
  455. drupal_set_message('Deleted Field from Template.');
  456. break;
  457. } //end of switch
  458. // Save Template
  459. $record = array(
  460. 'template_id' => $form_state['storage']['template_id'],
  461. 'template_array' => serialize($form_state['storage']['template'])
  462. );
  463. drupal_write_record('tripal_bulk_loader_template', $record, array('template_id'));
  464. drupal_set_message('Template Saved.');
  465. }
  466. //////////////////////////////////////////////////////////////////////////////////////
  467. // Delete Template
  468. //////////////////////////////////////////////////////////////////////////////////////
  469. /**
  470. * Delete Template Form
  471. * This form allows admin to delete already existing templates
  472. */
  473. function tripal_bulk_loader_delete_template_base_form() {
  474. $form = array();
  475. $sql = "SELECT * FROM {tripal_bulk_loader_template}";
  476. $resource = db_query($sql);
  477. $templates = array();
  478. $templates[''] = 'Select a Template';
  479. while ($r = db_fetch_object($resource)) {
  480. $templates[$r->template_id] = $r->name;
  481. }
  482. $form['template_name'] = array(
  483. '#title' => t('Template'),
  484. '#description' => t('Please select the template you would like to delete.'),
  485. '#type' => 'select',
  486. '#options' => $templates,
  487. '#weight' => 0,
  488. '#required' => TRUE,
  489. );
  490. $form['submit'] = array(
  491. '#type' => 'submit',
  492. '#value' => 'Delete Template',
  493. );
  494. return $form;
  495. }
  496. /**
  497. * Delete Template Form Submit
  498. *
  499. * @param $form
  500. * The form that was submitted
  501. * @param $form_state
  502. * The values and storage that were submitted
  503. */
  504. function tripal_bulk_loader_delete_template_base_form_submit($form, &$form_state) {
  505. $sql = "DELETE FROM {tripal_bulk_loader_template} WHERE template_id=%d";
  506. db_query($sql, $form_state['values']['template_name']);
  507. }
  508. //////////////////////////////////////////////////////////////////////////////////////
  509. // Import/Export Template
  510. //////////////////////////////////////////////////////////////////////////////////////
  511. /**
  512. * Import/Export Template Form
  513. *
  514. * On export, simply selects the serialized array from the db for a given template
  515. * and presents it to the user. On import, a serialized template array and a name is
  516. * supplied and a template record is created.
  517. *
  518. * @todo Make array presented to the user more readable. (ie: unserialize and print to the screen)
  519. *
  520. * @param $form_state
  521. * The values and storage for the form
  522. * @param $mode
  523. * Either 'import' or 'export' to indicate which function is being performed
  524. * @return
  525. * A form array to be rendered by drupal_get_form
  526. */
  527. function tripal_bulk_loader_import_export_template_form($form_state = NULL, $mode) {
  528. $form = array();
  529. $form['mode'] = array(
  530. '#type' => 'hidden',
  531. '#value' => $mode,
  532. );
  533. if (preg_match('/import/', $mode)) {
  534. $form['new_template_name'] = array(
  535. '#type' => 'textfield',
  536. '#title' => 'Template Name',
  537. '#weight' => 1,
  538. );
  539. }
  540. elseif (preg_match('/export/', $mode)) {
  541. $sql = "SELECT * FROM {tripal_bulk_loader_template}";
  542. $resource = db_query($sql);
  543. $templates = array();
  544. $templates[''] = 'Select a Template';
  545. while ($r = db_fetch_object($resource)) {
  546. $templates[$r->template_id] = $r->name;
  547. }
  548. $form['template_id'] = array(
  549. '#title' => t('Template'),
  550. '#description' => t('Please select the template you would like to edit.'),
  551. '#type' => 'select',
  552. '#options' => $templates,
  553. '#default_value' => $form_state['storage']['template_id'],
  554. '#weight' => 0,
  555. '#required' => TRUE,
  556. '#weight' => 1,
  557. );
  558. }
  559. $form['template_array'] = array(
  560. '#type' => 'textarea',
  561. '#title' => 'Template Array',
  562. '#default_value' => $form_state['storage']['template_array'],
  563. '#weight' => 2,
  564. );
  565. $form['submit'] = array(
  566. '#type' => 'submit',
  567. '#value' => 'Submit',
  568. '#weight' => 10,
  569. );
  570. return $form;
  571. }
  572. /**
  573. * Import/Export Template Form Submit
  574. *
  575. * @param $form
  576. * The form that was submitted
  577. * @param $form_state
  578. * The values and storage that were submitted
  579. */
  580. function tripal_bulk_loader_import_export_template_form_submit($form, &$form_state) {
  581. switch ($form_state['values']['mode']) {
  582. case 'export':
  583. $record = db_fetch_object(db_query("SELECT * FROM {tripal_bulk_loader_template} WHERE template_id=%d", $form_state['values']['template_id']));
  584. $form_state['storage']['template_array'] = $record->template_array;
  585. $form_state['storage']['template_id'] = $form_state['values']['template_id'];
  586. break;
  587. case 'import':
  588. $record = array(
  589. 'name' => $form_state['values']['new_template_name'],
  590. 'template_array' => $form_state['values']['template_array'],
  591. );
  592. drupal_write_record('tripal_bulk_loader_template', $record);
  593. if ($record->template_id) {
  594. drupal_set_message('Successfully imported Tripal Bulk Loader Template.');
  595. }
  596. break;
  597. }
  598. }
  599. //////////////////////////////////////////////////////////////////////////////////////
  600. // Edit Record Form
  601. //////////////////////////////////////////////////////////////////////////////////////
  602. /**
  603. * Edit Record Form
  604. *
  605. * This form is meant to be called from a bulk loader form. The following should be set
  606. * in the query section of the path:
  607. * - template_id=\d+: the template which the edited record is part of
  608. * - record_id=\d+: the priority or key in the template array of the record to be edited
  609. *
  610. * @param $form_state
  611. * Contains the values and storage for the form
  612. * @return
  613. * A form array to be rendered by drupal_get_form
  614. */
  615. function tripal_bulk_loader_edit_template_record_form(&$form_state = NULL) {
  616. $form['#cache'] = TRUE; // Make sure the form is cached.
  617. // get template id from path
  618. $template_id = ($_GET['template_id'] !== NULL) ? $_GET['template_id'] : $form_state['values']['template_id'];
  619. // if there is no template supplied don't return rest of form
  620. if (!$template_id) {
  621. return $form;
  622. }
  623. // Pre-process values/defaults ---------------------------
  624. // If this is the first load of the form (no form state) we need to initialize some variables
  625. if (!$form_state['storage']['template']) {
  626. $sql = "SELECT * FROM {tripal_bulk_loader_template} WHERE template_id=%d";
  627. $template = db_fetch_object(db_query($sql, $template_id));
  628. $form_state['storage']['template_array'] = unserialize($template->template_array);
  629. $form_state['storage']['template'] = $template;
  630. $form_state['storage']['record2priority'] = array();
  631. foreach ($form_state['storage']['template_array'] as $priority => $record_array) {
  632. if (!is_array($record_array)) {
  633. continue;
  634. }
  635. $form_state['storage']['record2priority'][$record_array['record_id']] = $priority;
  636. }
  637. $form_state['storage']['referring URL'] = $_SERVER["HTTP_REFERER"];
  638. }
  639. else {
  640. $template = $form_state['storage']['template'];
  641. }
  642. // get the record_id from the path
  643. if ($_GET['record_id'] !== NULL) {
  644. $form_state['values']['field_group'] = $_GET['record_id'];
  645. $form_state['storage']['original_priority'] = $_GET['record_id'];
  646. }
  647. // Tables and default table
  648. $tables = tripal_core_get_chado_tables();
  649. if ($form_state['values']['chado_table']) {
  650. $table = $form_state['values']['chado_table'];
  651. }
  652. else {
  653. $table = $form_state['storage']['template_array'][$form_state['storage']['original_priority']]['table'];
  654. }
  655. //dpm($form_state, 'form state');
  656. // Form Proper -------------------------------------------
  657. $form['template_name'] = array(
  658. '#type' => 'item',
  659. '#title' => 'Template',
  660. '#value' => $template->name,
  661. );
  662. $form['template_id'] = array(
  663. '#type' => 'hidden',
  664. '#value' => $template_id,
  665. );
  666. $form['edit_record'] = array(
  667. '#type' => 'fieldset',
  668. );
  669. // check template array for records then add one more
  670. if (!$form_state['storage']['record2priority']) {
  671. $groups = array();
  672. }
  673. else {
  674. $groups = array_flip($form_state['storage']['record2priority']);
  675. }
  676. $priority_default = $form_state['values']['field_group'];
  677. $form['edit_record']['field_group'] = array(
  678. '#type' => 'select',
  679. '#title' => 'Record',
  680. '#description' => 'By Changing the record here, you can move all the fields from the current record into the selected record.',
  681. '#options' => $groups,
  682. '#default_value' => $priority_default,
  683. '#required' => TRUE,
  684. );
  685. $form['edit_record']['record_name'] = array(
  686. '#type' => 'textfield',
  687. '#title' => 'Unique Record Name',
  688. '#default_value' => $groups[$priority_default],
  689. );
  690. $form['edit_record']['chado_table'] = array(
  691. '#type' => 'select',
  692. '#title' => t('Chado Table'),
  693. '#description' => 'This changes the chado table for all fields in this record.',
  694. '#options' => $tables,
  695. '#default_value' => $table,
  696. );
  697. $form['edit_record']['mode'] = array(
  698. '#type' => 'radios',
  699. '#title' => 'Action to take when Loading Record',
  700. '#options' => array(
  701. 'select' => 'SELECT: Don\'t insert this record: it\'s used to define a foreign key in another record',
  702. 'insert' => 'INSERT: Insert the record',
  703. 'optional' => 'OPTIONAL: Record will only be inserted if all required data is filled in',
  704. 'insert_once' => 'INSERT ONCE: Record will be inserted once for the entire spreadsheet',
  705. 'insert_unique' => 'INSERT UNIQUE: Only insert record if there isn\'t a record with the same values',
  706. ),
  707. '#default_value' => 'insert_unique'
  708. );
  709. $form['edit_record']['submit-edit_record'] = array(
  710. '#type' => 'submit',
  711. '#value' => 'Edit Record'
  712. );
  713. $form['edit_record']['submit-cancel'] = array(
  714. '#type' => 'submit',
  715. '#value' => 'Cancel'
  716. );
  717. return $form;
  718. }
  719. /**
  720. * Edit Record Form Submit
  721. *
  722. * @param $form
  723. * The form that was submitted
  724. * @param $form_state
  725. * Contains the values and storage for the form
  726. */
  727. function tripal_bulk_loader_edit_template_record_form_submit($form, &$form_state) {
  728. //dpm($form_state, 'form state -start submit');
  729. if (!$form_state['ahah_submission']) {
  730. if ($form_state['values']['op'] == 'Edit Record') {
  731. $template = $form_state['storage']['template_array'];
  732. // Edit Record
  733. $record = $template[ $form_state['storage']['original_priority'] ];
  734. $record['record_id'] = $form_state['values']['record_name'];
  735. $record['mode'] = $form_state['values']['mode'];
  736. $record['table'] = $form_state['values']['chado_table'];
  737. if ($form_state['storage']['original_priority'] != $form_state['values']['field_group']) {
  738. $record['fields'] = array_merge($record['fields'], $template[ $form_state['values']['field_group'] ]['fields']);
  739. $template[ $form_state['values']['field_group'] ] = $record;
  740. unset($template[ $form_state['storage']['original_priority'] ]);
  741. }
  742. else {
  743. $template[ $form_state['storage']['original_priority'] ] = $record;
  744. }
  745. // Save Template
  746. $form_state['storage']['template']->template_array = serialize($template);
  747. $success = drupal_write_record('tripal_bulk_loader_template', $form_state['storage']['template'], array('template_id'));
  748. if ($success) {
  749. drupal_set_message('Successfully Updated Template Record');
  750. drupal_set_message('Template Saved.');
  751. $path = explode('?', $form_state['storage']['referring URL']);
  752. parse_str($path[1], $query);
  753. $query['template_id'] = $form_state['storage']['template']->template_id;
  754. drupal_goto($path[0], $query);
  755. }
  756. else {
  757. drupal_set_message('Unable to Save Template!', 'error');
  758. watchdog('T_bulk_loader',
  759. 'Unable to save bulk loader template: %template',
  760. array('%template' => print_r($form_state['storage']['template'], TRUE)),
  761. WATCHDOG_ERROR
  762. );
  763. }
  764. }
  765. elseif ($form_state['values']['op'] == 'Cancel') {
  766. $path = explode('?', $form_state['storage']['referring URL']);
  767. parse_str($path[1], $query);
  768. $query['template_id'] = $form_state['storage']['template']->template_id;
  769. //dpm('Redirecting to: '.$path[0].'?'.print_r($query,TRUE).' where the referring URL:'.$form_state['storage']['referring URL']);
  770. drupal_goto($path[0], $query);
  771. }
  772. }
  773. }
  774. //////////////////////////////////////////////////////////////////////////////////////
  775. // Add/Edit Field Forms
  776. //////////////////////////////////////////////////////////////////////////////////////
  777. /**
  778. * Add Field Form
  779. *
  780. * This form is meant to be called from a bulk loader form. Blank Defaults are in place but you
  781. * can use the following in the query of the path to set defaults for a given template:
  782. * - template_id=\d+: the template to add the field to
  783. * - record_id=\d+: the priority or key in the template array of the record to add the field to
  784. *
  785. * @param $form_state
  786. * Contains the values and storage for the form
  787. * @return
  788. * A form array to be rendered by drupal_get_form
  789. */
  790. function tripal_bulk_loader_add_template_field_form(&$form_state = NULL) {
  791. $form = array();
  792. $form['#cache'] = TRUE; // Make sure the form is cached.
  793. // get template id from path
  794. $template_id = ($_GET['template_id']) ? $_GET['template_id'] : $form_state['values']['template_id'];
  795. // if there is no template supplied don't return rest of form
  796. if (!$template_id) {
  797. return $form;
  798. }
  799. // Pre-set Variables needed for form proper------------------------------------------
  800. // If this is the first load of the form (no form state) we need to initialize some variables
  801. if (!$form_state['storage']['template']) {
  802. $sql = "SELECT * FROM {tripal_bulk_loader_template} WHERE template_id=%d";
  803. $template = db_fetch_object(db_query($sql, $template_id));
  804. $form_state['storage']['template_array'] = unserialize($template->template_array);
  805. $form_state['storage']['template'] = $template;
  806. $form_state['storage']['record2priority'] = array();
  807. foreach ($form_state['storage']['template_array'] as $priority => $record_array) {
  808. if (!is_array($record_array)) {
  809. continue;
  810. }
  811. $form_state['storage']['record2priority'][$record_array['record_id']] = $priority;
  812. }
  813. $form_state['storage']['referring URL'] = $_SERVER["HTTP_REFERER"];
  814. }
  815. else {
  816. $template = $form_state['storage']['template'];
  817. }
  818. $field_type = ($form_state['values']['field_type'])? $form_state['values']['field_type'] : 'table field';
  819. // Tables and default table
  820. $tables = tripal_core_get_chado_tables();
  821. if ($form_state['values']) {
  822. if (!preg_match('/^' . current($tables) . '$/', $form_state['values']['chado_table'])) {
  823. $table = $form_state['values']['chado_table'];
  824. }
  825. elseif ($form_state['values']['record_name']) {
  826. $record_name = $form_state['values']['record_name'];
  827. $priority = $form_state['storage']['record2priority'][$record_name];
  828. $table = $form_state['storage']['template_array'][$priority]['table'];
  829. }
  830. else {
  831. $priority = $form_state['values']['field_group'];
  832. $table = $form_state['storage']['template_array'][$priority]['table'];
  833. }
  834. }
  835. if (!$table) {
  836. $table = reset($tables);
  837. }
  838. // get the record_id from the path
  839. if ($_GET['record_id'] !== NULL) {
  840. $form_state['values']['field_group'] = $_GET['record_id'];
  841. if (preg_match('/\d+/', $_GET['record_id'])) {
  842. $priority = $form_state['values']['field_group'];
  843. $table = $form_state['storage']['template_array'][$priority]['table'];
  844. }
  845. }
  846. // Fields and foreign key mappings
  847. $chado_fields = array();
  848. $fk_options = array();
  849. $fk_options['NULL'] = 'None';
  850. $table_description = module_invoke_all('chado_' . $table . '_schema');
  851. //dpm($table_description, 'table description for |'.$table.'|');
  852. if ($field_type == 'foreign key') {
  853. $foreign_field2table = array();
  854. foreach ($table_description['foreign keys'] as $key_table => $key_array) {
  855. foreach ($key_array['columns'] as $left_field => $right_field) {
  856. $chado_fields[$left_field] = $left_field;
  857. $foreign_field2table[$left_field] = $key_table;
  858. }
  859. }
  860. reset($chado_fields);
  861. // set default field
  862. if (empty($chado_fields)) {
  863. $field = NULL;
  864. }
  865. elseif ($chado_fields[$form_state['values']['chado_field']]) {
  866. $field = $form_state['values']['chado_field'];
  867. }
  868. else {
  869. $field = current($chado_fields);
  870. }
  871. // Foreign key options
  872. $foreign_table = $foreign_field2table[$field];
  873. if ($foreign_table) {
  874. foreach ($form_state['storage']['record2priority'] as $record_name => $priority ) {
  875. if (preg_match('/^' . $foreign_table . '$/', $form_state['storage']['template_array'][$priority]['table'])) {
  876. $fk_options[$record_name] = $record_name;
  877. }
  878. }
  879. }
  880. }
  881. else {
  882. foreach ($table_description['fields'] as $field_name => $field_array) {
  883. $chado_fields[$field_name] = $field_name;
  884. }
  885. }
  886. $variables = array(
  887. 'form_state' => $form_state,
  888. 'tables' => $tables,
  889. 'default table' => $table,
  890. 'fields' => $chado_fields,
  891. 'default_field' => $field,
  892. 'priority' => $priority,
  893. 'record_name' => $record_name,
  894. 'table description' => $table_description,
  895. 'foreign key options' => $fk_options,
  896. 'foreign field=>table' => $foreign_field2table,
  897. 'foreign table' => $foreign_table,
  898. );
  899. //dpm($variables, 'variables');
  900. // Start of Form Proper--------------------------------------------------------------
  901. //dpm($form_state, 'Form State');
  902. $form['template_name'] = array(
  903. '#type' => 'item',
  904. '#title' => 'Template',
  905. '#value' => $template->name,
  906. );
  907. $form['template_id'] = array(
  908. '#type' => 'hidden',
  909. '#value' => $template_id,
  910. );
  911. $form['add_fields'] = array(
  912. '#type' => 'fieldset',
  913. '#prefix' => '<div id="tripal_bulk_loader_template-add_field">',
  914. '#suffix' => '</div>',
  915. );
  916. $form['add_fields']['field_type'] = array(
  917. '#type' => 'radios',
  918. '#title' => t('Type of Field'),
  919. '#options' => array(
  920. 'table field' => t('Spreadsheet: Fields which maps to a Spreadsheet Column'),
  921. 'constant' => t('Constant: Field which remains Constant throughout the Spreadsheet'),
  922. 'foreign key' => t('Foreign Key: Fields which map to a record in another table'),
  923. ),
  924. '#required' => TRUE,
  925. '#default_value' => $field_type,
  926. '#ahah' => array(
  927. 'path' => 'admin/tripal/tripal_bulk_loader_template/add_field_ahah',
  928. 'wrapper' => 'tripal_bulk_loader_template-add_field',
  929. 'effect' => 'fade'
  930. ),
  931. );
  932. // check template array for records then add one more
  933. if (!$form_state['storage']['record2priority']) {
  934. $groups = array();
  935. }
  936. else {
  937. $groups = array_flip($form_state['storage']['record2priority']);
  938. }
  939. $groups['NONE'] = 'Select a Record';
  940. $groups['NEW'] = 'New Record';
  941. $form['add_fields']['field_group'] = array(
  942. '#type' => 'select',
  943. '#title' => 'Record',
  944. '#description' => 'This is used to group a set of fields together allowing '
  945. .'multiple records to be inserted into the same table per line of the spreadsheet',
  946. '#options' => $groups,
  947. '#default_value' => (preg_match('/\w+.*/', $form_state['values']['field_group'])) ? $form_state['values']['field_group'] : 'NONE',
  948. '#ahah' => array(
  949. 'path' => 'admin/tripal/tripal_bulk_loader_template/add_field_ahah',
  950. 'wrapper' => 'tripal_bulk_loader_template-add_field',
  951. 'effect' => 'fade'
  952. ),
  953. '#required' => TRUE,
  954. );
  955. $form['add_fields']['record_name'] = array(
  956. '#type' => (preg_match('/NEW/', $form_state['values']['field_group'])) ? 'textfield' : 'hidden',
  957. '#title' => 'Unique Record Name',
  958. '#prefix' => '<div id="tripal_bulk_loader_template-add_record">',
  959. '#suffix' => '</div>',
  960. '#default_value' => $form_state['values']['record_name'],
  961. );
  962. $form['add_fields']['field_title'] = array(
  963. '#type' => 'textfield',
  964. '#title' => t('Human-readable Title for Field'),
  965. '#default_value' => $form_state['values']['field_title'],
  966. );
  967. // Spreadsheet column
  968. $form['add_fields']['columns'] = array(
  969. '#type' => 'fieldset',
  970. '#title' => t('Spreadsheet Column'),
  971. '#collapsible' => TRUE,
  972. '#collapsed' => ($field_type == 'table field')? FALSE : TRUE,
  973. );
  974. $form['add_fields']['columns']['sheet_name'] = array(
  975. '#type' => 'textfield',
  976. '#title' => t('Worksheet'),
  977. '#description' => t('Specify the name of the worksheet.'),
  978. '#size' => 5,
  979. '#default_value' => ($form_state['values']['sheet_name'])? $form_state['values']['sheet_name'] : 'Sheet1',
  980. );
  981. $form['add_fields']['columns']['column_number'] = array(
  982. '#type' => 'textfield',
  983. '#title' => t('Column'),
  984. '#description' => t('Specify the column in the spreadsheet that this field maps to where the first column is 1.'),
  985. '#size' => 5,
  986. '#default_value' => $form_state['values']['column_number'],
  987. );
  988. $form['add_fields']['columns']['column_exposed'] = array(
  989. '#type' => 'checkbox',
  990. '#title' => t('Allow Column to be set for each Bulk Loading Job'),
  991. '#description' => t('Adds a textbox field to the Bulk Loader Page to allow users to set this value.'),
  992. '#default_value' => ($form_state['values']['column_exposed']) ? $form_state['values']['column_exposed'] : $template_field['exposed'],
  993. );
  994. $form['add_fields']['columns']['column_exposed_desc'] = array(
  995. '#type' => 'textfield',
  996. '#title' => t('Description for exposed field on bulk loading job'),
  997. '#description' => t('This description should tell the user what column should be entered here.'),
  998. '#default_value' => ($form_state['values']['column_exposed_desc']) ? $form_state['values']['column_exposed_desc'] : $template_field['exposed_description'],
  999. );
  1000. // Global Value
  1001. $form['add_fields']['constant'] = array(
  1002. '#type' => 'fieldset',
  1003. '#title' => t('Constant'),
  1004. '#collapsible' => TRUE,
  1005. '#collapsed' => ($field_type == 'constant')? FALSE : TRUE,
  1006. );
  1007. $form['add_fields']['constant']['constant_value'] = array(
  1008. '#type' => 'textfield',
  1009. '#title' => t('Constant Value'),
  1010. '#description' => t('Specify the value you wish this field to have regardless of spreadsheet data.'),
  1011. '#default_value' => $form_state['values']['constant_value']
  1012. );
  1013. $form['add_fields']['constant']['constant_exposed'] = array(
  1014. '#type' => 'checkbox',
  1015. '#title' => t('Allow Constant to be set for each Bulk Loading Job'),
  1016. '#description' => t('Adds a textbox field to the Create Bulk Loader Form to allow users to set this value.')
  1017. );
  1018. $form['add_fields']['constant']['constant_validate'] = array(
  1019. '#type' => 'checkbox',
  1020. '#title' => t('Ensure value is in table'),
  1021. '#description' => t('Checks the database when a bulk loading job is created to ensure the value entered already exists in the database.'),
  1022. );
  1023. // Foreign Key
  1024. $form['add_fields']['foreign_key'] = array(
  1025. '#type' => 'fieldset',
  1026. '#title' => 'Foreign Key',
  1027. '#collapsible' => TRUE,
  1028. '#collapsed' => ($field_type == 'foreign key')? FALSE : TRUE,
  1029. );
  1030. $form['add_fields']['foreign_key']['foreign_record'] = array(
  1031. '#type' => 'select',
  1032. '#title' => 'Record to refer to',
  1033. '#descripion' => 'Select the record that this foreign key shouold refer to. The record needs to already exist and be of the correct table.',
  1034. '#options' => $fk_options,
  1035. );
  1036. // Chado Field
  1037. $form['add_fields']['chado'] = array(
  1038. '#type' => 'fieldset',
  1039. '#title' => t('Chado Field/Column Details'),
  1040. '#description' => t('Specify the Table/Field in chado that this field maps to.'),
  1041. );
  1042. $form['add_fields']['chado']['chado_table'] = array(
  1043. '#type' => 'select',
  1044. '#title' => t('Chado Table'),
  1045. '#options' => $tables,
  1046. '#default_value' => $table,
  1047. '#ahah' => array(
  1048. 'path' => 'admin/tripal/tripal_bulk_loader_template/add_field_ahah',
  1049. 'wrapper' => 'tripal_bulk_loader_template-add_field',
  1050. 'effect' => 'fade'
  1051. ),
  1052. );
  1053. $form['add_fields']['chado']['chado_field'] = array(
  1054. '#type' => 'select',
  1055. '#title' => t('Chado Field/Column'),
  1056. '#options' => $chado_fields,
  1057. '#default_value' => $form_state['values']['chado_field'],
  1058. '#ahah' => array(
  1059. 'path' => 'admin/tripal/tripal_bulk_loader_template/add_field_ahah',
  1060. 'wrapper' => 'tripal_bulk_loader_template-add_field',
  1061. 'effect' => 'fade'
  1062. ),
  1063. );
  1064. $form['add_fields']['additional'] = array(
  1065. '#type' => 'fieldset',
  1066. '#title' => 'Additional Options',
  1067. );
  1068. $form['add_fields']['additional']['required'] = array(
  1069. '#type' => 'checkbox',
  1070. '#title' => 'Make this file required',
  1071. );
  1072. $form['add_fields']['additional']['regex_transform'] = array(
  1073. '#type' => 'fieldset',
  1074. '#title' => 'Transform Spreadsheet Value Rules',
  1075. '#collapsible' => TRUE,
  1076. '#collapsed' => (!$form_state['storage']['regex']['pattern']) ? TRUE : FALSE,
  1077. );
  1078. $form['add_fields']['additional']['regex_transform']['regex_description'] = array(
  1079. '#type' => 'item',
  1080. '#value' => 'A transformation rule allows you to transform the original value '
  1081. .'(usually from a user submitted spreadsheet) into the form you would like it stored '
  1082. .'in the chado database. Each rule consists of a match pattern (a php regular expression '
  1083. .'which determines which replacement patterns are applied and captures regions of the '
  1084. .'original value) and a replacement pattern (a string which may contain capture references '
  1085. .'that describes what the new value should be). Each rule is applied to the result of the '
  1086. .'previous rule.'
  1087. );
  1088. $form['add_fields']['additional']['regex_transform']['regex-data'] = array(
  1089. '#tree' => TRUE,
  1090. );
  1091. if (!$form_state['storage']['regex']['pattern']) {
  1092. $form_state['storage']['regex']['pattern'] = array();
  1093. }
  1094. foreach ($form_state['storage']['regex']['pattern'] as $index => $pattern) {
  1095. $data_element = array(
  1096. 'pattern' => array(
  1097. '#type' => 'item',
  1098. '#value' => $pattern,
  1099. ),
  1100. 'replace' => array(
  1101. '#type' => 'item',
  1102. '#value' => $form_state['storage']['regex']['replace'][$index],
  1103. ),
  1104. 'old_index' => array(
  1105. '#type' => 'hidden',
  1106. '#value' => $index,
  1107. ),
  1108. 'new_index' => array(
  1109. '#type' => 'select',
  1110. '#options' => range(0, sizeof($form_state['storage']['regex']['pattern'])-1),
  1111. '#default_value' => $index,
  1112. ),
  1113. 'id' => array(
  1114. '#type' => 'hidden',
  1115. '#value' => $index,
  1116. ),
  1117. 'submit-delete' => array(
  1118. '#type' => 'submit',
  1119. '#value' => 'Delete Transformation',
  1120. '#name' => $index,
  1121. ),
  1122. );
  1123. $form['add_fields']['additional']['regex_transform']['regex-data'][$index] = $data_element;
  1124. }
  1125. $form['add_fields']['additional']['regex_transform']['submit-reorder_regex'] = array(
  1126. '#type' => ($form_state['storage']['regex']['pattern']) ? 'submit' : 'hidden',
  1127. '#value' => 'Save Transformation Rule Order'
  1128. );
  1129. $form['add_fields']['additional']['regex_transform']['new_regex'] = array(
  1130. '#type' => 'fieldset',
  1131. '#title' => 'Add a new Transformation Rule',
  1132. );
  1133. $form['add_fields']['additional']['regex_transform']['new_regex']['pattern'] = array(
  1134. '#type' => 'textfield',
  1135. '#title' => 'Match Pattern',
  1136. '#description' => 'You can use standard php regular expressions in this field to specify a '
  1137. .'pattern. Only if this pattern matches the value in the spreadsheet does the replacement '
  1138. .'pattern get applied to the value. To capture a section of your value for use in the '
  1139. .'replacement patten surround with round brackets. For example, <i>GI:(\d+)</i> will match '
  1140. .' NCBI gi numbers and will capture the numerical digits for use in the replacement pattern. '
  1141. .' To match and capture any value use <i>.*</i>',
  1142. );
  1143. $form['add_fields']['additional']['regex_transform']['new_regex']['replace'] = array(
  1144. '#type' => 'textfield',
  1145. '#title' => 'Replacement Pattern',
  1146. '#description' => 'This pattern should contain the text you want to replace the match pattern '
  1147. .'mentioned above. It can include references of the form \n where n is the number of the '
  1148. .'capture in the match pattern. For example, \1 will be replaced with the text matched in your '
  1149. .'first set of round brackets.',
  1150. );
  1151. if ($field_type == 'table field') {
  1152. $tab = '&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp';
  1153. $form['add_fields']['additional']['regex_transform']['new_regex']['replace']['#description'] .= '<p>'
  1154. .'The following references are also available for spreadsheet fields: <b><#column:<i>number</i>#></b>. '
  1155. .'This allows you to substitute other spreadsheet values into the current field. For example, '
  1156. .'if you had the following line:<br>'
  1157. . $tab . 'SNP' . $tab . '15-Jan-2011' . $tab . '1' . $tab . '54' . $tab . 'Contig34355'
  1158. .'<br> and your current field is for column #1 and you\'re inserting into the chado field '
  1159. .'feature.uniquename then you might want to add in the data to ensure your uniquename is '
  1160. .'unique. The Match Pattern is (.*) to select all the first column and the Replacement '
  1161. .'Pattern could be \1_<#column:2#> which would insert SNP_15-Jan-2011 into the database.</p>';
  1162. }
  1163. $form['add_fields']['additional']['regex_transform']['new_regex']['submit-add_transform'] = array(
  1164. '#type' => 'submit',
  1165. '#value' => 'Add Transformation',
  1166. );
  1167. $form['add_fields']['additional']['regex_transform']['test_regex'] = array(
  1168. '#type' => 'fieldset',
  1169. '#title' => 'Test Transformation Rules',
  1170. );
  1171. $form['add_fields']['additional']['regex_transform']['test_regex']['test_string'] = array(
  1172. '#type' => 'textfield',
  1173. '#title' => 'Test Value',
  1174. '#description' => 'This should be a value that you expect the above transformation rules '
  1175. .'to be applied to.',
  1176. '#default_value' => $form_state['storage']['test_regex_test'],
  1177. );
  1178. $form['add_fields']['additional']['regex_transform']['test_regex']['test_result'] = array(
  1179. '#type' => 'textfield',
  1180. '#title' => 'Test Result',
  1181. '#description' => 'This is the value that would be saved to the database after the above transformation '
  1182. .'riles were applied to the Test Value.',
  1183. '#default_value' => $form_state['storage']['test_regex_result'],
  1184. );
  1185. $form['add_fields']['additional']['regex_transform']['test_regex']['submit-test'] = array(
  1186. '#type' => 'submit',
  1187. '#value' => 'Test Transformation Rules'
  1188. );
  1189. $form['add_fields']['submit-add_field'] = array(
  1190. '#type' => 'submit',
  1191. '#value' => 'Add Field'
  1192. );
  1193. $form['add_fields']['submit-cancel'] = array(
  1194. '#type' => 'submit',
  1195. '#value' => 'Cancel'
  1196. );
  1197. return $form;
  1198. }
  1199. /**
  1200. * Add Field Submit
  1201. *
  1202. * @param $form
  1203. * The form that was submitted
  1204. * @param $form_state
  1205. * The values and storage for the form
  1206. */
  1207. function tripal_bulk_loader_add_template_field_form_submit($form, &$form_state) {
  1208. $op = $form_state['values'][ $form_state['clicked_button']['#name'] ];
  1209. if (!$form_state['ahah_submission']) {
  1210. if ($op == 'Add Field') {
  1211. $template = $form_state['storage']['template_array'];
  1212. // If new record
  1213. if (preg_match('/NEW/', $form_state['values']['field_group'])) {
  1214. $record_name = $form_state['values']['record_name'];
  1215. $priority = sizeof($form_state['storage']['template_array']) + 1;
  1216. $record2priority[$record_name] = $priority;
  1217. $template[$priority]['table'] = $form_state['values']['chado_table'];
  1218. $template[$priority]['record_id'] = $record_name;
  1219. }
  1220. else {
  1221. $priority = $form_state['values']['field_group'];
  1222. $record_name = $record2priority[$priority];
  1223. }
  1224. // Add field to template array
  1225. if ($form_state['values']['field_type'] == 'table field') {
  1226. $field = array(
  1227. 'type' => 'table field',
  1228. 'title' => $form_state['values']['field_title'],
  1229. 'field' => $form_state['values']['chado_field'],
  1230. 'required' => $form_state['values']['required'],
  1231. //'allowed values' => empty by default,
  1232. 'spreadsheet sheet' => $form_state['values']['sheet_name'],
  1233. 'spreadsheet column' => $form_state['values']['column_number'],
  1234. 'exposed' => $form_state['values']['column_exposed'],
  1235. 'exposed_description' => $form_state['values']['column_exposed_desc'],
  1236. );
  1237. }
  1238. elseif ($form_state['values']['field_type'] == 'constant') {
  1239. $field = array(
  1240. 'type' => 'constant',
  1241. 'title' => $form_state['values']['field_title'],
  1242. 'field' => $form_state['values']['chado_field'],
  1243. 'required' => $form_state['values']['required'],
  1244. //'allowed values' => empty by default,
  1245. 'constant value' => $form_state['values']['constant_value'],
  1246. 'exposed' => $form_state['values']['constant_exposed'],
  1247. 'exposed_validate' => $form_state['values']['constant_validate'],
  1248. );
  1249. }
  1250. elseif ($form_state['values']['field_type'] == 'foreign key') {
  1251. $field = array(
  1252. 'type' => 'foreign key',
  1253. 'title' => $form_state['values']['field_title'],
  1254. 'field' => $form_state['values']['chado_field'],
  1255. 'foreign key' => $form_state['values']['foreign_record'],
  1256. 'required' => $form_state['values']['required'],
  1257. );
  1258. }
  1259. // Deal with any additional options
  1260. if ($form_state['storage']['regex']) {
  1261. $field['regex'] = $form_state['storage']['regex'];
  1262. }
  1263. // Save Template
  1264. $template[$priority]['fields'][] = $field;
  1265. $form_state['storage']['template']->template_array = serialize($template);
  1266. $success = drupal_write_record('tripal_bulk_loader_template', $form_state['storage']['template'], array('template_id'));
  1267. if ($success) {
  1268. drupal_set_message('Successfully Added Field to Template');
  1269. drupal_set_message('Template Saved.');
  1270. $path = explode('?', $form_state['storage']['referring URL']);
  1271. parse_str($path[1], $query);
  1272. $query['template_id'] = $form_state['storage']['template']->template_id;
  1273. drupal_goto($path[0], $query);
  1274. }
  1275. else {
  1276. drupal_set_message('Unable to Save Template!', 'error');
  1277. watchdog('T_bulk_loader',
  1278. 'Unable to save bulk loader template: %template',
  1279. array('%template' => print_r($form_state['storage']['template'], TRUE)),
  1280. WATCHDOG_ERROR
  1281. );
  1282. }
  1283. }
  1284. elseif ($op == 'Cancel') {
  1285. $path = explode('?', $form_state['storage']['referring URL']);
  1286. parse_str($path[1], $query);
  1287. $query['template_id'] = $form_state['storage']['template']->template_id;
  1288. drupal_goto($path[0], $query);
  1289. }
  1290. elseif ($op == 'Add Transformation') {
  1291. // Add transformation rule to original field
  1292. $form_state['storage']['regex']['pattern'][] = '/' . $form_state['values']['pattern'] . '/';
  1293. $form_state['storage']['regex']['replace'][] = $form_state['values']['replace'];
  1294. drupal_set_message('Successfully Added Transformation Rule');
  1295. }
  1296. elseif ($op == 'Save Transformation Rule Order') {
  1297. // Generate new regex array
  1298. $new_regex = array();
  1299. $old_regex = $form_state['storage']['regex'];
  1300. foreach ($form_state['values']['regex-data'] as $key => $element) {
  1301. $new_regex['pattern'][ $element['new_index'] ] = $old_regex['pattern'][ $element['old_index'] ];
  1302. $new_regex['replace'][ $element['new_index'] ] = $old_regex['replace'][ $element['old_index'] ];
  1303. }
  1304. // sort new regex arrays
  1305. asort($new_regex['pattern']);
  1306. asort($new_regex['replace']);
  1307. $form_state['storage']['regex'] = $new_regex;
  1308. }
  1309. elseif ($op == 'Delete Transformation') {
  1310. // Unset regex rule
  1311. $index = $form_state['clicked_button']['#name'];
  1312. unset($form_state['storage']['regex']['pattern'][$index]);
  1313. unset($form_state['storage']['regex']['replace'][$index]);
  1314. }
  1315. elseif ($op == 'Test Transformation Rules') {
  1316. $patterns = $form_state['storage']['regex']['pattern'];
  1317. $replaces = $form_state['storage']['regex']['replace'];
  1318. $test_string = $form_state['values']['test_string'];
  1319. $form_state['storage']['test_regex_result'] = preg_replace($patterns, $replaces, $test_string);
  1320. $form_state['storage']['test_regex_test'] = $test_string;
  1321. }
  1322. }
  1323. }
  1324. /**
  1325. * Edit Field Form
  1326. *
  1327. * This form is meant to be called from a bulk loader form. The following should be set
  1328. * in the query section of the path:
  1329. * - template_id=\d+: the template which the edited field is part of
  1330. * - record_id=\d+: the priority or key in the template array of the record the field
  1331. * is currently part of
  1332. * - field_index=\d+: the key of the field in the fields array of the previously
  1333. * specified record
  1334. *
  1335. * @param $form_state
  1336. * Contains the values and storage for the form
  1337. * @return
  1338. * A form array to be rendered by drupal_get_form
  1339. */
  1340. function tripal_bulk_loader_edit_template_field_form(&$form_state = NULL) {
  1341. $form = array();
  1342. $form['#cache'] = TRUE; // Make sure the form is cached.
  1343. // get template id from path
  1344. $template_id = ($_GET['template_id']) ? $_GET['template_id'] : $form_state['values']['template_id'];
  1345. // if there is no template supplied don't return rest of form
  1346. if (!$template_id) {
  1347. return $form;
  1348. }
  1349. // Pre-set Variables needed for form proper------------------------------------------
  1350. // If this is the first load of the form (no form state) we need to initialize some variables
  1351. if (!$form_state['storage']['template']) {
  1352. $sql = "SELECT * FROM {tripal_bulk_loader_template} WHERE template_id=%d";
  1353. $template = db_fetch_object(db_query($sql, $template_id));
  1354. $form_state['storage']['template_array'] = unserialize($template->template_array);
  1355. $form_state['storage']['template'] = $template;
  1356. $form_state['storage']['record2priority'] = array();
  1357. foreach ($form_state['storage']['template_array'] as $priority => $record_array) {
  1358. if (!is_array($record_array)) {
  1359. continue;
  1360. }
  1361. $form_state['storage']['record2priority'][$record_array['record_id']] = $priority;
  1362. }
  1363. $form_state['storage']['referring URL'] = $_SERVER["HTTP_REFERER"];
  1364. }
  1365. else {
  1366. $template = $form_state['storage']['template'];
  1367. }
  1368. // get the field from the path
  1369. if (!($_GET['record_id']===NULL || $_GET['field_index']===NULL)) {
  1370. $priority = $_GET['record_id'];
  1371. $field_index = $_GET['field_index'];
  1372. $template_field = $form_state['storage']['template_array'][$priority]['fields'][$field_index];
  1373. $form_state['storage']['original_field'] = $template_field;
  1374. $form_state['storage']['original_field']['priority'] = $priority;
  1375. $form_state['storage']['original_field']['field_index'] = $field_index;
  1376. }
  1377. $field_type = ($form_state['values']['field_type'])? $form_state['values']['field_type'] : $template_field['type'];
  1378. // Tables and default table
  1379. $tables = tripal_core_get_chado_tables();
  1380. if ($form_state['values']) {
  1381. $table = $form_state['values']['chado_table'];
  1382. }
  1383. else {
  1384. $table = $form_state['storage']['template_array'][$priority]['table'];
  1385. }
  1386. // Fields and foreign key mappings
  1387. $chado_fields = array();
  1388. $fk_options = array();
  1389. $fk_options['NULL'] = 'None';
  1390. $table_description = module_invoke_all('chado_' . $table . '_schema');
  1391. if ($field_type == 'foreign key') {
  1392. $foreign_field2table = array();
  1393. foreach ($table_description['foreign keys'] as $key_table => $key_array) {
  1394. foreach ($key_array['columns'] as $left_field => $right_field) {
  1395. $chado_fields[$left_field] = $left_field;
  1396. $foreign_field2table[$left_field] = $key_table;
  1397. }
  1398. }
  1399. reset($chado_fields);
  1400. // set default field
  1401. if (empty($chado_fields)) {
  1402. $field = NULL;
  1403. }
  1404. elseif ($chado_fields[$form_state['values']['chado_field']]) {
  1405. $field = $form_state['values']['chado_field'];
  1406. }
  1407. elseif ($template_field['field']) {
  1408. $field = $template_field['field'];
  1409. }
  1410. else {
  1411. $field = current($chado_fields);
  1412. }
  1413. //dpm($field, 'field');
  1414. // Foreign key options
  1415. $foreign_table = $foreign_field2table[$field];
  1416. if ($foreign_table) {
  1417. foreach ($form_state['storage']['record2priority'] as $record_name_ => $priority_ ) {
  1418. if (preg_match('/^' . $foreign_table . '$/', $form_state['storage']['template_array'][$priority_]['table'])) {
  1419. $fk_options[$record_name_] = $record_name_;
  1420. }
  1421. }
  1422. }
  1423. }
  1424. else {
  1425. foreach ($table_description['fields'] as $field_name => $field_array) {
  1426. $chado_fields[$field_name] = $field_name;
  1427. }
  1428. }
  1429. // dpm(array( 'tables' => $tables, 'default table' => $table, 'record name' => $record_name, 'priority' => $priority,
  1430. // 'fields' => $chad_fields, 'default field' => $field, 'foreign field=>table' => $foreign_field2table,
  1431. // 'table desc' => $table_description, 'foreign record options' => $fk_options, 'foreign table' => $foreign_table
  1432. // ), 'Variables');
  1433. // Start of Form Proper--------------------------------------------------------------
  1434. $form['template_name'] = array(
  1435. '#type' => 'item',
  1436. '#title' => 'Template',
  1437. '#value' => $template->name,
  1438. );
  1439. $form['template_id'] = array(
  1440. '#type' => 'hidden',
  1441. '#value' => $template_id,
  1442. );
  1443. $form['edit_fields'] = array(
  1444. '#type' => 'fieldset',
  1445. '#prefix' => '<div id="tripal_bulk_loader_template-edit_field">',
  1446. '#suffix' => '</div>',
  1447. );
  1448. $form['edit_fields']['field_type'] = array(
  1449. '#type' => 'radios',
  1450. '#title' => t('Type of Field'),
  1451. '#options' => array(
  1452. 'table field' => t('Spreadsheet: Fields which maps to a Spreadsheet Column'),
  1453. 'constant' => t('Constant: Field which remains Constant throughout the Spreadsheet'),
  1454. 'foreign key' => t('Foreign Key: Fields which map to a record in another table'),
  1455. ),
  1456. '#required' => TRUE,
  1457. '#default_value' => $field_type,
  1458. '#ahah' => array(
  1459. 'path' => 'admin/tripal/tripal_bulk_loader_template/edit_field_ahah',
  1460. 'wrapper' => 'tripal_bulk_loader_template-edit_field',
  1461. 'effect' => 'fade'
  1462. ),
  1463. );
  1464. // check template array for records then edit one more
  1465. if (!$form_state['storage']['record2priority']) {
  1466. $groups = array();
  1467. }
  1468. else {
  1469. $groups = array_flip($form_state['storage']['record2priority']);
  1470. }
  1471. $groups['NONE'] = 'Select a Record';
  1472. $groups['NEW'] = 'New Record';
  1473. $form['edit_fields']['field_group'] = array(
  1474. '#type' => 'select',
  1475. '#title' => 'Record',
  1476. '#description' => 'This is used to group a set of fields together allowing '
  1477. .'multiple records to be inserted into the same table per line of the spreadsheet',
  1478. '#options' => $groups,
  1479. '#default_value' => (preg_match('/(\d+|\w+)/', $form_state['values']['field_group'])) ? $form_state['values']['field_group'] : $priority,
  1480. '#ahah' => array(
  1481. 'path' => 'admin/tripal/tripal_bulk_loader_template/edit_field_ahah',
  1482. 'wrapper' => 'tripal_bulk_loader_template-edit_field',
  1483. 'effect' => 'fade'
  1484. ),
  1485. '#required' => TRUE,
  1486. );
  1487. $form['edit_fields']['record_name'] = array(
  1488. '#type' => (preg_match('/NEW/', $form_state['values']['field_group'])) ? 'textfield' : 'hidden',
  1489. '#title' => 'Unique Record Name',
  1490. '#prefix' => '<div id="tripal_bulk_loader_template-edit_record">',
  1491. '#suffix' => '</div>',
  1492. '#default_value' => $form_state['values']['record_name'],
  1493. );
  1494. $form['edit_fields']['field_title'] = array(
  1495. '#type' => 'textfield',
  1496. '#title' => t('Human-readable Title for Field'),
  1497. '#default_value' => ($form_state['values']['field_title']) ? $form_state['values']['field_title'] : $template_field['title'],
  1498. );
  1499. // Spreadsheet column
  1500. $form['edit_fields']['columns'] = array(
  1501. '#type' => 'fieldset',
  1502. '#title' => t('Spreadsheet Column'),
  1503. '#collapsible' => TRUE,
  1504. '#collapsed' => ($field_type == 'table field')? FALSE : TRUE,
  1505. );
  1506. $form['edit_fields']['columns']['sheet_name'] = array(
  1507. '#type' => 'textfield',
  1508. '#title' => t('Worksheet'),
  1509. '#description' => t('Specify the name of the worksheet.'),
  1510. '#size' => 5,
  1511. '#default_value' => ($form_state['values']['sheet_name'])? $form_state['values']['sheet_name'] : $template_field['spreadsheet sheet'],
  1512. );
  1513. $form['edit_fields']['columns']['column_number'] = array(
  1514. '#type' => 'textfield',
  1515. '#title' => t('Column'),
  1516. '#description' => t('Specify the column in the spreadsheet that this field maps to where the first column is 1.'),
  1517. '#size' => 5,
  1518. '#default_value' => ($form_state['values']['column_number']) ? $form_state['values']['column_number'] : $template_field['spreadsheet column'],
  1519. );
  1520. $form['edit_fields']['columns']['column_exposed'] = array(
  1521. '#type' => 'checkbox',
  1522. '#title' => t('Allow Column to be set for each Bulk Loading Job'),
  1523. '#description' => t('Adds a textbox field to the Bulk Loader Page to allow users to set this value.'),
  1524. '#default_value' => ($form_state['values']['column_exposed']) ? $form_state['values']['column_exposed'] : $template_field['exposed'],
  1525. );
  1526. $form['edit_fields']['columns']['column_exposed_desc'] = array(
  1527. '#type' => 'textfield',
  1528. '#title' => t('Description for exposed field on bulk loading job'),
  1529. '#description' => t('This description should tell the user what column should be entered here.'),
  1530. '#default_value' => ($form_state['values']['column_exposed_desc']) ? $form_state['values']['column_exposed_desc'] : $template_field['exposed_description'],
  1531. );
  1532. // Global Value
  1533. $form['edit_fields']['constant'] = array(
  1534. '#type' => 'fieldset',
  1535. '#title' => t('Constant'),
  1536. '#collapsible' => TRUE,
  1537. '#collapsed' => ($field_type == 'constant')? FALSE : TRUE,
  1538. );
  1539. $form['edit_fields']['constant']['constant_value'] = array(
  1540. '#type' => 'textfield',
  1541. '#title' => t('Constant Value'),
  1542. '#description' => t('Specify the value you wish this field to have regardless of spreadsheet data.'),
  1543. '#default_value' => ($form_state['values']['constant_value']) ? $form_state['values']['constant_value'] : $template_field['constant value'],
  1544. );
  1545. $form['edit_fields']['constant']['constant_exposed'] = array(
  1546. '#type' => 'checkbox',
  1547. '#title' => t('Allow Constant to be set for each Bulk Loading Job'),
  1548. '#description' => t('Adds a textbox field to the Create Bulk Loader Form to allow users to set this value.'),
  1549. '#default_value' => ($form_state['values']['constant_exposed']) ? $form_state['values']['constant_exposed'] : $template_field['exposed'],
  1550. );
  1551. $form['edit_fields']['constant']['constant_validate'] = array(
  1552. '#type' => 'checkbox',
  1553. '#title' => t('Ensure value is in table'),
  1554. '#description' => t('Checks the database when a bulk loading job is created to ensure the value entered already exists in the database.'),
  1555. '#default_value' => ($form_state['values']['constant_validate']) ? $form_state['values']['constant_validate'] : $template_field['exposed_validate'],
  1556. );
  1557. // Foreign Key
  1558. $form['edit_fields']['foreign_key'] = array(
  1559. '#type' => 'fieldset',
  1560. '#title' => 'Foreign Key',
  1561. '#collapsible' => TRUE,
  1562. '#collapsed' => ($field_type == 'foreign key')? FALSE : TRUE,
  1563. );
  1564. $form['edit_fields']['foreign_key']['foreign_record'] = array(
  1565. '#type' => 'select',
  1566. '#title' => 'Record to refer to',
  1567. '#descripion' => 'Select the record that this foreign key shouold refer to. The record needs to already exist and be of the correct table.',
  1568. '#options' => $fk_options,
  1569. );
  1570. // Chado Field
  1571. $form['edit_fields']['chado'] = array(
  1572. '#type' => 'fieldset',
  1573. '#title' => t('Chado Field/Column Details'),
  1574. '#description' => t('Specify the Table/Field in chado that this field maps to.'),
  1575. );
  1576. $form['edit_fields']['chado']['chado_table'] = array(
  1577. '#type' => 'select',
  1578. '#title' => t('Chado Table'),
  1579. '#options' => $tables,
  1580. '#default_value' => $table,
  1581. '#ahah' => array(
  1582. 'path' => 'admin/tripal/tripal_bulk_loader_template/edit_field_ahah',
  1583. 'wrapper' => 'tripal_bulk_loader_template-edit_field',
  1584. 'effect' => 'fade'
  1585. ),
  1586. );
  1587. $form['edit_fields']['chado']['chado_field'] = array(
  1588. '#type' => 'select',
  1589. '#title' => t('Chado Field/Column'),
  1590. '#options' => $chado_fields,
  1591. '#default_value' => ($form_state['values']['chado_field']) ? $form_state['values']['chado_field'] : $template_field['field'],
  1592. '#ahah' => array(
  1593. 'path' => 'admin/tripal/tripal_bulk_loader_template/edit_field_ahah',
  1594. 'wrapper' => 'tripal_bulk_loader_template-edit_field',
  1595. 'effect' => 'fade'
  1596. ),
  1597. );
  1598. $form['edit_fields']['additional'] = array(
  1599. '#type' => 'fieldset',
  1600. '#title' => 'Additional Options',
  1601. );
  1602. $form['edit_fields']['additional']['required'] = array(
  1603. '#type' => 'checkbox',
  1604. '#title' => 'Make this file required',
  1605. '#default_value' => $template_field['required'],
  1606. );
  1607. $form['edit_fields']['additional']['regex_transform'] = array(
  1608. '#type' => 'fieldset',
  1609. '#title' => 'Transform Spreadsheet Value Rules',
  1610. '#collapsible' => TRUE,
  1611. '#collapsed' => (!$template_field['regex']['pattern']) ? TRUE : FALSE,
  1612. );
  1613. $transformation_msg = '<p>A transformation rule allows you to transform the original value '
  1614. .'(usually from a user submitted spreadsheet) into the form you would like it stored '
  1615. .'in the chado database. Each rule consists of a match pattern (a php regular expression '
  1616. .'which determines which replacement patterns are applied and captures regions of the '
  1617. .'original value) and a replacement pattern (a string which may contain capture references '
  1618. .'that describes what the new value should be). Each rule is applied to the result of the '
  1619. .'previous rule.<p>';
  1620. $form['edit_fields']['additional']['regex_transform']['regex_description'] = array(
  1621. '#type' => 'item',
  1622. '#value' => $transformation_msg,
  1623. );
  1624. $form['edit_fields']['additional']['regex_transform']['regex-data'] = array(
  1625. '#tree' => TRUE,
  1626. );
  1627. foreach ($template_field['regex']['pattern'] as $index => $pattern) {
  1628. $data_element = array(
  1629. 'pattern' => array(
  1630. '#type' => 'item',
  1631. '#value' => $pattern,
  1632. ),
  1633. 'replace' => array(
  1634. '#type' => 'item',
  1635. '#value' => $template_field['regex']['replace'][$index],
  1636. ),
  1637. 'old_index' => array(
  1638. '#type' => 'hidden',
  1639. '#value' => $index,
  1640. ),
  1641. 'new_index' => array(
  1642. '#type' => 'select',
  1643. '#options' => range(0, sizeof($template_field['regex']['pattern'])-1),
  1644. '#default_value' => $index,
  1645. ),
  1646. 'id' => array(
  1647. '#type' => 'hidden',
  1648. '#value' => $index,
  1649. ),
  1650. 'submit-delete' => array(
  1651. '#type' => 'submit',
  1652. '#value' => 'Delete Transformation',
  1653. '#name' => $index,
  1654. ),
  1655. );
  1656. $form['edit_fields']['additional']['regex_transform']['regex-data'][$index] = $data_element;
  1657. }
  1658. $form['edit_fields']['additional']['regex_transform']['submit-reorder_regex'] = array(
  1659. '#type' => 'submit',
  1660. '#value' => 'Save Transformation Rule Order'
  1661. );
  1662. $form['edit_fields']['additional']['regex_transform']['new_regex'] = array(
  1663. '#type' => 'fieldset',
  1664. '#title' => 'Add a new Transformation Rule',
  1665. );
  1666. $form['edit_fields']['additional']['regex_transform']['new_regex']['pattern'] = array(
  1667. '#type' => 'textfield',
  1668. '#title' => 'Match Pattern',
  1669. '#description' => 'You can use standard <b>php regular expressions</b> in this field to specify a '
  1670. .'pattern. Only if this pattern matches the value in the spreadsheet does the replacement '
  1671. .'pattern get applied to the value. To capture a section of your value for use in the '
  1672. .'replacement patten surround with round brackets. For example, <i>GI:(\d+)</i> will match '
  1673. .' NCBI gi numbers and will capture the numerical digits for use in the replacement pattern. '
  1674. .' To match and capture any value use <i>.*</i>',
  1675. );
  1676. $form['edit_fields']['additional']['regex_transform']['new_regex']['replace'] = array(
  1677. '#type' => 'textfield',
  1678. '#title' => 'Replacement Pattern',
  1679. '#description' => '<p>This pattern should contain the text you want to replace the match pattern '
  1680. .'mentioned above. It can include references of the form <b>\n</b> where n is the number of the '
  1681. .'capture in the match pattern. For example, \1 will be replaced with the text matched in your '
  1682. .'first set of round brackets.</p>',
  1683. );
  1684. if ($field_type == 'table field') {
  1685. $tab = '&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp';
  1686. $form['edit_fields']['additional']['regex_transform']['new_regex']['replace']['#description'] .= '<p>'
  1687. .'The following references are also available for spreadsheet fields: <b><#column:<i>number</i>#></b>. '
  1688. .'This allows you to substitute other spreadsheet values into the current field. For example, '
  1689. .'if you had the following line:<br>'
  1690. . $tab . 'SNP' . $tab . '15-Jan-2011' . $tab . '1' . $tab . '54' . $tab . 'Contig34355'
  1691. .'<br> and your current field is for column #1 and you\'re inserting into the chado field '
  1692. .'feature.uniquename then you might want to add in the data to ensure your uniquename is '
  1693. .'unique. The Match Pattern is (.*) to select all the first column and the Replacement '
  1694. .'Pattern could be \1_<#column:2#> which would insert SNP_15-Jan-2011 into the database.</p>';
  1695. }
  1696. $form['edit_fields']['additional']['regex_transform']['new_regex']['submit-add_transform'] = array(
  1697. '#type' => 'submit',
  1698. '#value' => 'Add Transformation',
  1699. );
  1700. $form['edit_fields']['additional']['regex_transform']['test_regex'] = array(
  1701. '#type' => 'fieldset',
  1702. '#title' => 'Test Transformation Rules',
  1703. );
  1704. $form['edit_fields']['additional']['regex_transform']['test_regex']['test_string'] = array(
  1705. '#type' => 'textfield',
  1706. '#title' => 'Test Value',
  1707. '#description' => 'This should be a value that you expect the above transformation rules '
  1708. .'to be applied to.',
  1709. '#default_value' => $form_state['storage']['test_regex_test'],
  1710. );
  1711. $form['edit_fields']['additional']['regex_transform']['test_regex']['test_result'] = array(
  1712. '#type' => 'textfield',
  1713. '#title' => 'Test Result',
  1714. '#description' => 'This is the value that would be saved to the database after the above transformation '
  1715. .'riles were applied to the Test Value.',
  1716. '#default_value' => $form_state['storage']['test_regex_result'],
  1717. );
  1718. $form['edit_fields']['additional']['regex_transform']['test_regex']['submit-test'] = array(
  1719. '#type' => 'submit',
  1720. '#value' => 'Test Transformation Rules'
  1721. );
  1722. $form['edit_fields']['submit-edit_field'] = array(
  1723. '#type' => 'submit',
  1724. '#value' => 'Edit Field'
  1725. );
  1726. $form['edit_fields']['submit-cancel'] = array(
  1727. '#type' => 'submit',
  1728. '#value' => 'Cancel'
  1729. );
  1730. return $form;
  1731. }
  1732. /**
  1733. * Edit Field Form Submit
  1734. *
  1735. * @param $form
  1736. * The form that was submitted
  1737. * @param $form_state
  1738. * The values and storage for the form
  1739. */
  1740. function tripal_bulk_loader_edit_template_field_form_submit($form, &$form_state) {
  1741. $op = $form_state['values'][ $form_state['clicked_button']['#name'] ];
  1742. //dpm($op, 'Operation Submitted');
  1743. //Clear Test
  1744. $form_state['storage']['test_regex_result'] = NULL;
  1745. $form_state['storage']['test_regex_test'] = NULL;
  1746. if (!$form_state['ahah_submission']) {
  1747. if ($op == 'Edit Field') {
  1748. // If new record
  1749. if (preg_match('/NEW/', $form_state['values']['field_group'])) {
  1750. // add new record
  1751. $record_name = $form_state['values']['record_name'];
  1752. $priority = sizeof($form_state['storage']['template_array']) + 1;
  1753. $old_priority = $form_state['storage']['original_field']['priority'];
  1754. $field_index = $form_state['storage']['original_field']['field_index'];
  1755. $form_state['storage']['record2priority'][$record_name] = $priority;
  1756. $form_state['storage']['template_array'][$priority]['table'] = $form_state['values']['chado_table'];
  1757. $form_state['storage']['template_array'][$priority]['record_id'] = $record_name;
  1758. }
  1759. else {
  1760. $priority = $form_state['values']['field_group'];
  1761. $old_priority = $form_state['storage']['original_field']['priority'];
  1762. $field_index = $form_state['storage']['original_field']['field_index'];
  1763. $record_name = $form_state['storage']['record2priority'][$priority];
  1764. }
  1765. $field = $form_state['storage']['original_field'];
  1766. if ($form_state['values']['field_type'] == 'table field') {
  1767. $field['type'] = 'table field';
  1768. $field['title'] = $form_state['values']['field_title'];
  1769. $field['field'] = $form_state['values']['chado_field'];
  1770. $field['required'] = $form_state['values']['required'];
  1771. //$field['allowed values'] = empty by default;
  1772. $field['spreadsheet sheet'] = $form_state['values']['sheet_name'];
  1773. $field['spreadsheet column'] = $form_state['values']['column_number'];
  1774. $field['exposed'] = $form_state['values']['column_exposed'];
  1775. $field['exposed_description'] = $form_state['values']['column_exposed_desc'];
  1776. }
  1777. elseif ($form_state['values']['field_type'] == 'constant') {
  1778. $field['type'] = 'constant';
  1779. $field['title'] = $form_state['values']['field_title'];
  1780. $field['field'] = $form_state['values']['chado_field'];
  1781. $field['required'] = $form_state['values']['required'];
  1782. //$field['allowed values'] = empty by default;
  1783. $field['constant value'] = $form_state['values']['constant_value'];
  1784. $field['exposed_validate'] = $form_state['values']['constant_validate'];
  1785. $field['exposed'] = $form_state['values']['constant_exposed'];
  1786. }
  1787. elseif ($form_state['values']['field_type'] == 'foreign key') {
  1788. $field['type'] = 'foreign key';
  1789. $field['title'] = $form_state['values']['field_title'];
  1790. $field['field'] = $form_state['values']['chado_field'];
  1791. $field['foreign key'] = $form_state['values']['foreign_record'];
  1792. $field['required'] = $form_state['values']['required'];
  1793. }
  1794. // Deal with any additional options
  1795. // if the record has changed...
  1796. $form_state['storage']['template_array'][$priority]['table'] = $form_state['values']['chado_table'];
  1797. if ($old_priority != $priority) {
  1798. $form_state['storage']['template_array'][$priority]['fields'][] = $field;
  1799. unset($form_state['storage']['template_array'][$old_priority]['fields'][$field_index]);
  1800. // if there are no fields left delete the old record
  1801. if (!$form_state['storage']['template_array'][$old_priority]['fields']) {
  1802. unset($form_state['storage']['template_array'][$old_priority]);
  1803. }
  1804. }
  1805. else {
  1806. $form_state['storage']['template_array'][$priority]['fields'][$field_index] = $field;
  1807. }
  1808. // Save Template
  1809. $form_state['storage']['template']->template_array = serialize($form_state['storage']['template_array']);
  1810. $success = drupal_write_record('tripal_bulk_loader_template', $form_state['storage']['template'], array('template_id'));
  1811. if ($success) {
  1812. drupal_set_message('Successfully Updated Field');
  1813. drupal_set_message('Template Saved.');
  1814. $path = explode('?', $form_state['storage']['referring URL']);
  1815. parse_str($path[1], $query);
  1816. $query['template_id'] = $form_state['storage']['template']->template_id;
  1817. drupal_goto($path[0], $query);
  1818. }
  1819. else {
  1820. drupal_set_message('Unable to Save Template!', 'error');
  1821. watchdog('T_bulk_loader',
  1822. 'Unable to save bulk loader template: %template',
  1823. array('%template' => print_r($form_state['storage']['template'], TRUE)),
  1824. WATCHDOG_ERROR
  1825. );
  1826. }
  1827. }
  1828. elseif ($op == 'Cancel') {
  1829. $path = explode('?', $form_state['storage']['referring URL']);
  1830. parse_str($path[1], $query);
  1831. $query['template_id'] = $form_state['storage']['template']->template_id;
  1832. drupal_goto($path[0], $query);
  1833. }
  1834. elseif ($op == 'Add Transformation') {
  1835. // Add transformation rule to original field
  1836. $form_state['storage']['original_field']['regex']['pattern'][] = '/' . $form_state['values']['pattern'] . '/';
  1837. $form_state['storage']['original_field']['regex']['replace'][] = $form_state['values']['replace'];
  1838. // Add original field back into template
  1839. $priority = $form_state['storage']['original_field']['priority'];
  1840. $field_index = $form_state['storage']['original_field']['field_index'];
  1841. $form_state['storage']['template_array'][$priority]['fields'][$field_index] = $form_state['storage']['original_field'];
  1842. // Save Template
  1843. $form_state['storage']['template']->template_array = serialize($form_state['storage']['template_array']);
  1844. $success = drupal_write_record('tripal_bulk_loader_template', $form_state['storage']['template'], array('template_id'));
  1845. if ($success) {
  1846. drupal_set_message('Successfully Added Transformation Rule');
  1847. drupal_set_message('Template Saved.');
  1848. }
  1849. else {
  1850. drupal_set_message('Unable to Save Template!', 'error');
  1851. watchdog('T_bulk_loader',
  1852. 'Unable to save bulk loader template: %template',
  1853. array('%template' => print_r($form_state['storage']['template'], TRUE)),
  1854. WATCHDOG_ERROR
  1855. );
  1856. }
  1857. }
  1858. elseif ($op == 'Save Transformation Rule Order') {
  1859. // Generate new regex array
  1860. $new_regex = array();
  1861. $old_regex = $form_state['storage']['original_field']['regex'];
  1862. foreach ($form_state['values']['regex-data'] as $key => $element) {
  1863. $new_regex['pattern'][ $element['new_index'] ] = $old_regex['pattern'][ $element['old_index'] ];
  1864. $new_regex['replace'][ $element['new_index'] ] = $old_regex['replace'][ $element['old_index'] ];
  1865. }
  1866. // sort new regex arrays
  1867. asort($new_regex['pattern']);
  1868. asort($new_regex['replace']);
  1869. // Add back to original field
  1870. $form_state['storage']['original_field']['regex'] = $new_regex;
  1871. $priority = $form_state['storage']['original_field']['priority'];
  1872. $field_index = $form_state['storage']['original_field']['field_index'];
  1873. $form_state['storage']['template_array'][$priority]['fields'][$field_index] = $form_state['storage']['original_field'];
  1874. // Save Template
  1875. $form_state['storage']['template']->template_array = serialize($form_state['storage']['template_array']);
  1876. $success = drupal_write_record('tripal_bulk_loader_template', $form_state['storage']['template'], array('template_id'));
  1877. if ($success) {
  1878. drupal_set_message('Successfully Reordered Transformation Rules');
  1879. drupal_set_message('Template Saved.');
  1880. }
  1881. else {
  1882. drupal_set_message('Unable to Save Template!', 'error');
  1883. watchdog('T_bulk_loader',
  1884. 'Unable to save bulk loader template: %template',
  1885. array('%template' => print_r($form_state['storage']['template'], TRUE)),
  1886. WATCHDOG_ERROR
  1887. );
  1888. }
  1889. }
  1890. elseif ($op == 'Delete Transformation') {
  1891. // Unset regex rule
  1892. $index = $form_state['clicked_button']['#name'];
  1893. unset($form_state['storage']['original_field']['regex']['pattern'][$index]);
  1894. unset($form_state['storage']['original_field']['regex']['replace'][$index]);
  1895. $priority = $form_state['storage']['original_field']['priority'];
  1896. $field_index = $form_state['storage']['original_field']['field_index'];
  1897. $form_state['storage']['template_array'][$priority]['fields'][$field_index] = $form_state['storage']['original_field'];
  1898. // Save Template
  1899. $form_state['storage']['template']->template_array = serialize($form_state['storage']['template_array']);
  1900. $success = drupal_write_record('tripal_bulk_loader_template', $form_state['storage']['template'], array('template_id'));
  1901. if ($success) {
  1902. drupal_set_message('Successfully Reordered Transformation Rules');
  1903. drupal_set_message('Template Saved.');
  1904. }
  1905. else {
  1906. drupal_set_message('Unable to Save Template!', 'error');
  1907. watchdog('T_bulk_loader',
  1908. 'Unable to save bulk loader template: %template',
  1909. array('%template' => print_r($form_state['storage']['template'], TRUE)),
  1910. WATCHDOG_ERROR
  1911. );
  1912. }
  1913. }
  1914. elseif ($op == 'Test Transformation Rules') {
  1915. $patterns = $form_state['storage']['original_field']['regex']['pattern'];
  1916. $replaces = $form_state['storage']['original_field']['regex']['replace'];
  1917. $test_string = $form_state['values']['test_string'];
  1918. $form_state['storage']['test_regex_result'] = preg_replace($patterns, $replaces, $test_string);
  1919. $form_state['storage']['test_regex_test'] = $test_string;
  1920. }
  1921. }
  1922. }
  1923. //////////////////////////////////////////////////////////////////////////////////////
  1924. // AHAH Callbacks
  1925. //////////////////////////////////////////////////////////////////////////////////////
  1926. /**
  1927. * AHAH Function: Replace $form['add_fields'] in tripal_bulk_loader_add_template_field_form
  1928. *
  1929. * @return
  1930. * JSON Data printed to the screen
  1931. */
  1932. function tripal_bulk_loader_add_field_ahah() {
  1933. $form_state = array('storage' => NULL, 'submitted' => FALSE);
  1934. $form_build_id = $_POST['form_build_id'];
  1935. $form = form_get_cache($form_build_id, $form_state);
  1936. $args = $form['#parameters'];
  1937. $form_id = array_shift($args);
  1938. $form_state['post'] = $form['#post'] = $_POST;
  1939. // Enable the submit/validate handlers to determine whether AHAH-submittted.
  1940. $form_state['ahah_submission'] = TRUE;
  1941. $form['#programmed'] = $form['#redirect'] = FALSE;
  1942. drupal_process_form($form_id, $form, $form_state);
  1943. $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
  1944. $form_element = $form['add_fields'];
  1945. // Remove the wrapper so we don't double it up.
  1946. //unset($form_element['#prefix'], $form_element['#suffix']);
  1947. $output = theme('status_messages');
  1948. $output .= drupal_render($form_element);
  1949. // Final rendering callback.
  1950. print drupal_json(array('status' => TRUE, 'data' => $output));
  1951. exit();
  1952. }
  1953. /**
  1954. * AHAH Function: Replace $form['edit_fields'] in tripal_bulk_loader_edit_template_field_form
  1955. *
  1956. * @return
  1957. * JSON Data printed to the screen
  1958. */
  1959. function tripal_bulk_loader_edit_field_ahah() {
  1960. $form_state = array('storage' => NULL, 'submitted' => FALSE);
  1961. $form_build_id = $_POST['form_build_id'];
  1962. $form = form_get_cache($form_build_id, $form_state);
  1963. $args = $form['#parameters'];
  1964. $form_id = array_shift($args);
  1965. $form_state['post'] = $form['#post'] = $_POST;
  1966. // Enable the submit/validate handlers to determine whether AHAH-submittted.
  1967. $form_state['ahah_submission'] = TRUE;
  1968. $form['#programmed'] = $form['#redirect'] = FALSE;
  1969. drupal_process_form($form_id, $form, $form_state);
  1970. $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
  1971. $form_element = $form['edit_fields'];
  1972. // Remove the wrapper so we don't double it up.
  1973. unset($form_element['#prefix'], $form_element['#suffix']);
  1974. $output = theme('status_messages');
  1975. $output .= drupal_render($form_element);
  1976. // Final rendering callback.
  1977. print drupal_json(array('status' => TRUE, 'data' => $output));
  1978. exit();
  1979. }