tripal_ds.module 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. <?php
  2. require_once "includes/tripal_ds.inc";
  3. require_once "includes/tripal_ds.ds.inc";
  4. require_once "includes/tripal_ds.field_group.inc";
  5. require_once "includes/tripal_ds.field_formatter.inc";
  6. function tripal_ds_init() {
  7. drupal_add_css(drupal_get_path('module', 'tripal_ds') . '/theme/css/tripaldsfeature.css');
  8. drupal_add_js(drupal_get_path('module', 'tripal_ds') . '/theme/js/tripal_ds.js');
  9. $theme_dir = url(drupal_get_path('module', 'tripal_ds') . '/theme');
  10. drupal_add_js("var ds_theme_dir = '$theme_dir';", 'inline', 'header');
  11. }
  12. /**
  13. * Implements hook_views_api().
  14. */
  15. function tripal_ds_views_api() {
  16. return array(
  17. 'api' => 3,
  18. 'path' => drupal_get_path('module', 'tripal_ds') . '/includes/views',
  19. );
  20. }
  21. /**
  22. * Implements hook_menu().
  23. * Defines all menu items needed by Tripal DS
  24. *
  25. */
  26. function tripal_ds_menu() {
  27. $items = array();
  28. // Adds a +Apply Tripal Display Suite option to 'Tripal Content Types' page.
  29. $items['admin/structure/bio_data/manage/%/display/apply'] = array(
  30. 'title' => 'Apply Default Tripal Layout (will reset current layout)',
  31. 'description' => t('Apply the Tripal Display Suite settings to this content type.'),
  32. 'page callback' => 'drupal_get_form',
  33. 'access arguments' => array('administer tripal'),
  34. 'page arguments' => array('tripal_ds_update_layout_form', 4),
  35. 'type' => MENU_LOCAL_ACTION,
  36. );
  37. // Adds a +Add Tripal Pane button to 'Tripal Content Types' page.
  38. $items['admin/structure/bio_data/manage/%/display/create'] = array(
  39. 'title' => 'Create an empty Tripal Pane',
  40. 'description' => t('Create a new empty tripal pane.'),
  41. 'page callback' => 'drupal_get_form',
  42. 'access arguments' => array('administer tripal'),
  43. 'page arguments' => array('tripal_ds_pane_addition_button_form', 4),
  44. 'type' => MENU_LOCAL_ACTION,
  45. );
  46. return $items;
  47. }
  48. /**
  49. * Implements hook_bundle_postcreate().
  50. *
  51. * This is a Triapl defined hook and is called in the TripalBundle::create()
  52. * function to allow modules to perform tasks when a bundle is created.
  53. */
  54. function tripal_ds_bundle_postcreate($bundle) {
  55. $bundle_name = $bundle->name;
  56. $bundle_data_table = $bundle->data_table;
  57. $instances = field_info_instances('TripalEntity', $bundle_name);
  58. if($bundle_data_table == 'pub'){
  59. _ds_layout_pub_settings_info($bundle_name, $instances);
  60. }
  61. else {
  62. _ds_layout_settings_info($bundle_name, $instances);
  63. }
  64. }
  65. /**
  66. * Update the tripal_ds table when a tripal pane is deleted.
  67. */
  68. function tripal_ds_table_column_delete($bundle){
  69. $bundle_name = $bundle->name;
  70. db_delete('tripal_ds')
  71. ->condition('bundle', $bundle_name, '=')
  72. ->execute();
  73. }
  74. /**
  75. * Trigger the update to the tripal_ds table when a tripal pane is deleted.
  76. */
  77. function tripal_ds_bundle_delete($bundle){
  78. tripal_ds_table_column_delete($bundle);
  79. }
  80. /**
  81. * Implements hook_ds_field_settings_alter()
  82. */
  83. function tripal_ds_ds_field_settings_alter(&$field_settings, $form, $form_state){
  84. // Get the form info from the bundle about to be saved.
  85. $tripal_entity_object = $form_state['build_info']['args']['1'];
  86. // Grab the bundle.
  87. $bundle_id = $tripal_entity_object->name;
  88. // Grab the field groups from the bundle.
  89. $updated_field_groups = $form_state['field_group'];
  90. // Grab the fields from the bundle.
  91. $fields = $form_state['values']['fields'];
  92. // Delete the menu items associated with the bundle id.
  93. db_delete('tripal_ds')
  94. ->condition('bundle', $bundle_id, '=')
  95. ->execute();
  96. // Traverse the updated field_groups grabbing the tripal pane items.
  97. $tripal_pane_field_groups = array();
  98. $i = 0;
  99. foreach($updated_field_groups as $updated_field_group){
  100. if($updated_field_group->format_type == 'tripalpane'){
  101. $tripal_pane_field_groups += [ $i => $updated_field_group->group_name];
  102. $i++;
  103. }
  104. }
  105. // Now grab the labels of the tripalpane.
  106. foreach($updated_field_groups as $updated_field_group){
  107. foreach($tripal_pane_field_groups as $tripal_pane_field_group){
  108. if($updated_field_group->group_name == $tripal_pane_field_group){
  109. if($fields[$tripal_pane_field_group]['region'] !== 'hidden'){
  110. tripal_ds_bundle_menu_item($bundle_id, $updated_field_group->label, $tripal_pane_field_group, 'tripalentity');
  111. }
  112. }
  113. }
  114. }
  115. // Update the menu items weight.
  116. tripal_ds_toc_order($bundle_id, $form_state['values']['fields']);
  117. }
  118. /**
  119. * Implements hook_field_group_pre_render().
  120. *
  121. * This function gives you the oppertunity to create the given
  122. * wrapper element that can contain the fields.
  123. * In the example beneath, some variables are prepared and used when building the
  124. * actual wrapper element. All elements in drupal fapi can be used.
  125. *
  126. * Note that at this point, the field group has no notion of the fields in it.
  127. *
  128. * There is also an alternative way of handling this. The default implementation
  129. * within field_group calls "field_group_pre_render_<format_type>".
  130. * @see field_group_pre_render_fieldset.
  131. *
  132. * @param Array $elements by address.
  133. * @param Object $group The Field group info.
  134. function tripal_ds_field_group_pre_render(& $element, $group, & $form) {
  135. watchdog('debug', '<pre>tripal_ds_preprocess_TripalEntity $group: '. print_r($group, TRUE) .'</pre>');
  136. if ($group->format_settings['formatter'] != 'open') {
  137. $add['#prefix'] = '<div class="field-group-format ' . $classes . '">
  138. <span class="field-group-format-toggler">' . check_plain(t($group->label)) . '</span>
  139. <div class="field-group-format-wrapper" style="display: none;">';
  140. $add['#suffix'] = '</div></div>';
  141. }
  142. }
  143. */
  144. /**
  145. *
  146. * Trigger the update to the tripal_ds table when a tripal pane is deleted.
  147. *
  148. * @param $bundle_name
  149. * @param $field_label
  150. * @param $field_name
  151. * @param $entity_type
  152. */
  153. function tripal_ds_bundle_menu_item($bundle_name, $field_label, $field_name, $entity_type){
  154. //Check the record does not already exist
  155. $tripal_ds_rows = db_select('tripal_ds', 'ds')
  156. ->fields('ds', array('tripal_ds_field_name', 'tripal_ds_field_label'))
  157. ->condition('bundle', $bundle_name, '=')
  158. ->condition('tripal_ds_field_label', $field_label, '=')
  159. ->condition('tripal_ds_field_name', $field_name, '=')
  160. ->execute()->fetchAll();
  161. if(!empty($tripal_ds_rows)){
  162. foreach ($tripal_ds_rows as $tripal_ds_row){
  163. if(($field_label == $tripal_ds_row->tripal_ds_field_label) && ($field_name == $tripal_ds_row->tripal_ds_field_name) && ($bundle_name == $tripal_ds_rows->bundle)) {
  164. // Do not write the field to the table
  165. drupal_set_message("Could not update the bundle menu because that field already exists.", 'error');
  166. }
  167. }
  168. }
  169. else {
  170. //Write to the tripal_ds table to record the new tripal pane.
  171. $field_for_table = new stdClass();
  172. $field_for_table->tripal_ds_field_name = $field_name;
  173. $field_for_table->tripal_ds_field_label = $field_label;
  174. $field_for_table->entity_type = $entity_type;
  175. $field_for_table->bundle = $bundle_name;
  176. drupal_write_record('tripal_ds', $field_for_table);
  177. }
  178. }
  179. /**
  180. * Implements hook_ds_layout_info() to define layouts from code in a module for
  181. * display suite
  182. */
  183. function tripal_ds_ds_layout_info() {
  184. $path = drupal_get_path('module', 'tripal_ds');
  185. $layouts = array(
  186. 'tripal_ds_feature' => array(
  187. 'label' => t('Tripal Feature Layout'),
  188. 'path' => $path . '/theme/templates',
  189. 'regions' => array(
  190. 'left' => t('Left'),
  191. 'right' => t('Right'),
  192. ),
  193. 'css' => TRUE,
  194. ),
  195. );
  196. return $layouts;
  197. }
  198. /**
  199. * Implements hook_form()
  200. *
  201. * Adds a confirmation message to applying default layout option in 'Manage
  202. * Display'
  203. *
  204. * @param $form
  205. * @param $form_state
  206. * @param $bundle_name
  207. *
  208. * @return mixed
  209. */
  210. function tripal_ds_update_layout_form($form, &$form_state, $bundle_name) {
  211. $form = array();
  212. $form['bundle_name'] = array(
  213. '#type' => 'value',
  214. '#value' => $bundle_name,
  215. );
  216. $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
  217. $bundle_label = $bundle->label;
  218. return confirm_form($form,
  219. t('Please confirm you would like to apply this layout: ' . $bundle_label),
  220. 'admin/structure/bio_data/manage/' . $bundle_name . '/display',
  221. t('This action cannot be undone.'),
  222. t('Yes, apply layout'),
  223. t('No, cancel')
  224. );
  225. }
  226. /**
  227. * Implements hook_form_submit()
  228. *
  229. * @param $form_state
  230. * @param $form
  231. */
  232. function tripal_ds_update_layout_form_submit($form, &$form_state) {
  233. $bundle_name = $form_state['build_info']['args'][0];
  234. $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
  235. //Build the identifier to check against ds_layout_settings.
  236. $ds_identifier = 'TripalEntity|'.$bundle_name.'|default';
  237. //Check to see if the layout already exists.
  238. $result = db_select('ds_layout_settings', 'ds')
  239. ->fields('ds')
  240. ->condition('id', $ds_identifier, '=')
  241. ->execute()
  242. ->fetchField();
  243. //Check to see if there are any field groups associated with the bundle.
  244. $result_fg = db_select('field_group', 'fg')
  245. ->fields('fg')
  246. ->condition('bundle', $bundle_name, '=')
  247. ->execute()
  248. ->fetchField();
  249. //Check to see if there are any tripal ds fields associated with the bundle.
  250. $result_tds = db_select('tripal_ds', 'tds')
  251. ->fields('tds')
  252. ->condition('bundle', $bundle_name, '=')
  253. ->execute();
  254. //Check to see if there are any field settings associated with the bundle.
  255. $result_fs = db_select('ds_field_settings', 'fs')
  256. ->fields('fs')
  257. ->condition('bundle', $bundle_name, '=')
  258. ->execute();
  259. //If the layout exists, delete it.
  260. if(!empty($result)) {
  261. db_delete('ds_layout_settings')
  262. ->condition('id', $ds_identifier, '=')
  263. ->execute();
  264. }
  265. //Then delete the field_group_fields associated with the identifier.
  266. if(!empty($result_fg)) {
  267. db_delete('field_group')
  268. ->condition('bundle', $bundle_name, '=')
  269. ->execute();
  270. }
  271. //Then delete the ds_field_settings associated with the identifier.
  272. if(!empty($result_tds)) {
  273. db_delete('ds_field_settings')
  274. ->condition('bundle', $bundle_name, '=')
  275. ->execute();
  276. }
  277. //Then delete the tripal_ds menu item.
  278. if(!empty($result_fs)) {
  279. db_delete('tripal_ds')
  280. ->condition('bundle', $bundle_name, '=')
  281. ->execute();
  282. }
  283. //Now you can build the layout fresh.
  284. $instances = field_info_instances('TripalEntity', $bundle_name);
  285. $bundle_data_table = $bundle->data_table;
  286. if($bundle_data_table == 'pub'){
  287. $success = _ds_layout_pub_settings_info($bundle_name, $instances);
  288. }
  289. else {
  290. $success = _ds_layout_settings_info($bundle_name, $instances);
  291. }
  292. if ($success) {
  293. drupal_set_message("Layout applied successfully and saved.");
  294. }
  295. else {
  296. drupal_set_message("Could not apply layout.", 'error');
  297. }
  298. drupal_goto("admin/structure/bio_data/manage/$bundle_name/display");
  299. }
  300. /**
  301. * @param $field
  302. * @param $bundle_name
  303. function tripal_ds_field_create_field($field, $bundle_name) {
  304. //Build the rest of the passes parameters.
  305. $field_name = str_replace('field_', '', $field['field_name']);
  306. $group_field_name = 'gp_'.$field['field_name'];
  307. //Create the field groups.
  308. _additional_fields_field_group_info($bundle_name, $field_name, $group_field_name, $field_name);
  309. //Place the field groups in the layout.
  310. tripal_ds_update_ds_layout($bundle_name, $field_name, $group_field_name);
  311. }
  312. */
  313. /**
  314. * Implements hook_form()
  315. *
  316. * Creates the button that creates an empty tripal pane.
  317. *
  318. * @param $form
  319. * @param $form_state
  320. * @param $bundle_name
  321. * @return mixed
  322. */
  323. function tripal_ds_pane_addition_button_form($form, &$form_state, $bundle_name) {
  324. $form = array();
  325. $form['bundle_name'] = array(
  326. '#type' => 'value',
  327. '#value' => $bundle_name,
  328. );
  329. $form['field_name'] = array(
  330. '#type' => 'textfield',
  331. '#title' => t('Tripal Panel Label'),
  332. '#required' => TRUE,
  333. '#description' => "Please enter the label for the new Tripal Pane",
  334. '#size' => 20,
  335. '#maxlength' => 50,
  336. );
  337. $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
  338. $bundle_label = $bundle->label;
  339. return confirm_form($form,
  340. t('Please confirm you would like to create a new field for: ' . $bundle_label),
  341. 'admin/structure/bio_data/manage/' . $bundle_name . '/display',
  342. t('Create new Tripal Pane'),
  343. t('Yes'),
  344. t('No, cancel')
  345. );
  346. }
  347. /**
  348. * Implements hook_form_submit()
  349. *
  350. * @param $form_state
  351. * @param $form
  352. */
  353. function tripal_ds_pane_addition_button_form_submit($form, &$form_state) {
  354. $bundle_name = $form_state['build_info']['args'][0];
  355. //Build the rest of the passed variables.
  356. $field_name = $form_state['input']['field_name'];
  357. $group_field_name = 'gp_'.$form_state['input']['field_name'];
  358. //Create the field groups, last passed parameter is NULL because there are no
  359. //children.
  360. _additional_fields_field_group_info($bundle_name, $field_name, $group_field_name, NULL);
  361. //Place the field groups in the layout.
  362. tripal_ds_update_ds_layout($bundle_name, NULL, $group_field_name);
  363. drupal_goto("admin/structure/bio_data/manage/$bundle_name/display");
  364. }
  365. /**
  366. * @param $bundle_name
  367. */
  368. function tripal_ds_update_ds_layout($bundle_name, $field_name, $tripal_pane_name) {
  369. //Build the identifier to check against ds_layout_settings.
  370. $ds_identifier = 'TripalEntity|'.$bundle_name.'|default';
  371. //Check to see if the layout already exists.
  372. $result = db_select('ds_layout_settings', 'ds')
  373. ->fields('ds', array('settings'))
  374. ->condition('ds.id', $ds_identifier, '=')
  375. ->execute()
  376. ->fetchObject();
  377. //If the layout exists unserialize it.
  378. if(!empty($result)) {
  379. $layout_info = $result->settings;
  380. $layout_info = unserialize($layout_info);
  381. //Count the number of rows in the region and add the field to the region.
  382. $index = count($layout_info['regions']['right']);
  383. //Now add the tripal pane and field to the right region and field array.
  384. if(!empty($field_name)){
  385. $layout_info['regions']['right'][$index] = $field_name;
  386. $incremented_index = $index++;
  387. $layout_info['fields'][$field_name] = 'right';
  388. }
  389. if(!empty($tripal_pane_name)){
  390. if(!empty($incremented_index)){
  391. $layout_info['regions']['right'][$incremented_index] = $tripal_pane_name;
  392. $layout_info['fields'][$tripal_pane_name] = 'right';
  393. }
  394. else {
  395. $layout_info['regions']['right'][$index] = $tripal_pane_name;
  396. $layout_info['fields'][$tripal_pane_name] = 'right';
  397. }
  398. }
  399. //Update the ds_layout_settings table with the new layout info.
  400. drupal_write_record('ds_layout_settings', $layout_info);
  401. }
  402. }
  403. /*
  404. * Code for the view of the menu items
  405. //get tripal entity id from url then run it against tripal entity db
  406. //and grab the bundle id, then pass bundle id to view
  407. $url = current_path();
  408. $url_exploded = explode("/", $url);
  409. $tripal_entity_id = (int)$url_exploded[1];
  410. $result = db_select('tripal_entity', 'te')
  411. ->fields('te', array('bundle'))
  412. ->condition('id', $tripal_entity_id, '=')
  413. ->execute()
  414. ->fetchField();
  415. */
  416. /**
  417. * Implements hook_field_display_alter().
  418. * @param $display
  419. * @param $context
  420. */
  421. function tripal_ds_field_display_alter(&$display, $context){
  422. $field_name = $context['field']['field_name'];
  423. $bundle = $context['entity']->bundle;
  424. $bundle_info = tripal_load_bundle_entity(array('name' => $bundle));
  425. $hide_variable = tripal_get_bundle_variable('hide_empty_field', $bundle_info->id, 'hide');
  426. if ($field_name && ($hide_variable == 'hide')) {
  427. $item = field_get_items('TripalEntity', $context['entity'], $field_name);
  428. $field = field_info_field($field_name);
  429. if ($item) {
  430. if (tripal_field_is_empty($item[0], $field)) {
  431. $parent_field_info = tripal_ds_find_field_group_parent($field_name, 'TripalEntity', $bundle, $context);
  432. if (!empty($parent_field_info)) {
  433. foreach ($parent_field_info as $parent_key => $parent_field){
  434. // Stop the right rail element from rendering.
  435. drupal_add_css('.' . $parent_field_info[$parent_key] . ' {display:none;}', 'inline');
  436. // Hide any associated menu links.
  437. drupal_add_css('#' . $parent_field_info[$parent_key] . ' {display:none;}', 'inline');
  438. }
  439. }
  440. }
  441. }
  442. }
  443. }
  444. /*
  445. */
  446. /**
  447. * Identifies field_group parents to find tripal_panes and return that
  448. * information to the function that calls it.
  449. *
  450. * @param $field_name
  451. * @param $entity_type
  452. * @param $bundle
  453. *
  454. * @return array
  455. */
  456. function tripal_ds_find_field_group_parent($field_name, $entity_type, $bundle, $context){
  457. $field_groups_to_hide = array();
  458. $increment = 0;
  459. // Get the field groups associated with this bundle.
  460. $fg_for_bundle = db_select('field_group', 'fg')
  461. ->fields('fg')
  462. ->condition('bundle', $bundle, '=')
  463. ->condition('entity_type', $entity_type, '=')
  464. ->execute()->fetchAll();
  465. // Run through the field groups looking for the provided $field_name
  466. foreach ($fg_for_bundle as $field_groups => $field_group) {
  467. $field_group_data = unserialize($field_group->data);
  468. // There is a separate function to deal with tables, so disregard.
  469. if ($field_group_data['format_type'] == 'table'){
  470. // Do nothing
  471. }
  472. elseif (!empty($field_group_data['children'][0])) {
  473. $children = $field_group_data['children'];
  474. //If there is more than one child all need to be checked.
  475. if (count($children) > 1) {
  476. foreach ($children as $kids => $child) {
  477. // Now check if each child if empty.
  478. $item = field_get_items('TripalEntity', $context['entity'], $child);
  479. $field = field_info_fild($child);
  480. if(!tripal_field_is_empty($item[0], $field)){
  481. //If any of the fields are not empty do not add the parent.
  482. break 2;
  483. }
  484. else {
  485. continue;
  486. }
  487. }
  488. $field_groups_to_hide[$increment] = $field_group->group_name;
  489. }
  490. elseif($children[0] == $field_name) {
  491. $field_groups_to_hide[$increment] = $field_group->group_name;
  492. }
  493. }
  494. $increment++;
  495. }
  496. // Remove duplicate values.
  497. $field_groups_to_hide = array_unique($field_groups_to_hide);
  498. return $field_groups_to_hide;
  499. }
  500. /**
  501. * @param $bundle
  502. * @param array $fields
  503. */
  504. function tripal_ds_toc_order($bundle, $fields = array()){
  505. // On bundle save grab the #ds_layout->settings ->regions->right array
  506. // then use the index of each 'group' && 'tripalpane, and 'gp_*' to update
  507. // the weight of the item in the tripal_ds table.
  508. // Don't forget to update the view.
  509. // Find all menu items associated with the bundle id.
  510. $menu_items = db_select('tripal_ds', 'ds')
  511. ->fields('ds')
  512. ->condition('bundle', $bundle, '=')
  513. ->execute()->fetchAll();
  514. // Now find all menu items in the $fields array
  515. foreach ($menu_items as $menu_items => $menu_item) {
  516. $toc_field_name = $menu_item->tripal_ds_field_name;
  517. // Compare the field name from the table with the fields in the array.
  518. if (array_key_exists($toc_field_name, $fields)) {
  519. $weight = $fields[$toc_field_name]['weight'];
  520. //If a weight is returned update the tripal_ds table.
  521. if(!empty($weight)){
  522. watchdog('debug', '<pre>$weight: '. print_r($weight, TRUE) .'</pre>');
  523. db_update('tripal_ds')
  524. ->fields(array(
  525. 'weight' => $weight,
  526. ))
  527. ->condition('bundle', $bundle, '=')
  528. ->condition('tripal_ds_field_name', $toc_field_name, '=')
  529. ->execute();
  530. }
  531. }
  532. }
  533. }