tripal_ds.ds.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <?php
  2. /**
  3. * Sorts a multidimensional array into alphabetical order.
  4. *
  5. * @param $key .
  6. *
  7. * @return \Closure
  8. */
  9. function tripal_ds_sort_array($key) {
  10. return function ($a, $b) use ($key) {
  11. return strnatcmp($a[$key], $b[$key]);
  12. };
  13. }
  14. /**
  15. * Sorts a multidimensional array of objects into alphabetical order.
  16. *
  17. * @param $key .
  18. *
  19. * @return \Closure
  20. */
  21. function tripal_ds_sort_object($key) {
  22. return function ($a, $b) use ($key) {
  23. return strnatcmp($a->$key, $b->$key);
  24. };
  25. }
  26. /**
  27. * Builds the tripal_ds layout for all content types other than Publications.
  28. *
  29. * @param $bundle_name
  30. * Machine name of bundle, example bio_data_1
  31. * @param $instances
  32. *
  33. * @return bool
  34. */
  35. function _ds_layout_settings_info($bundle_name, $instances) {
  36. $region_right = [];
  37. $region_left = [];
  38. $prop_fields = [];
  39. $summary_fields = [];
  40. $data_sequence_fields = [];
  41. $all_other_fields = [];
  42. $fields_with_regions = [];
  43. $i = 0;
  44. $all_fields = [];
  45. try {
  46. // Get the bundle and term objects.
  47. $bundle = tripal_load_bundle_entity(['name' => $bundle_name]);
  48. $term = tripal_load_term_entity(['term_id' => $bundle->term_id]);
  49. // Build one large multidimensional array of all instances to sort in alpha
  50. // order to display fields in label alpha order.
  51. foreach ($instances as $key => $instance) {
  52. $all_fields[$i] = $instance;
  53. $i++;
  54. }
  55. usort($all_fields, tripal_ds_sort_array('label'));
  56. // Iterate through the fields of this bundle.
  57. foreach ($all_fields as $key => $instance) {
  58. $instance_name = $instance['field_name'];
  59. if ($instance_name == "rdfs__type") {
  60. array_push($summary_fields, $instance_name);
  61. }
  62. else {
  63. //TODO: How do we handle non-chado dbs, placement of fields within
  64. // tripal panes might need to be done in a hook.
  65. $instance_base_table = array_key_exists('base_table', $instance['settings']) ? $instance['settings']['base_table'] : '';
  66. $instance_base_chado = array_key_exists('chado_table', $instance['settings']) ? $instance['settings']['chado_table'] : '';
  67. $prop_table = strpos($instance_base_chado, 'prop');
  68. $data_sequence_record = strpos($instance_name, 'data__sequence_record');
  69. $data_sequence = strpos($instance_name, 'data__sequence');
  70. if ($instance_base_chado && $instance_base_table) {
  71. if ($instance_base_chado == $instance_base_table) {
  72. if ($data_sequence_record !== FALSE) {
  73. array_push($data_sequence_fields, $instance_name);
  74. }
  75. elseif ($data_sequence !== FALSE or $instance_name == 'so__cds' or $instance_name == 'data__protein_sequence') {
  76. // Do nothing as these chado column sequence fields
  77. // should be hidden by default.
  78. }
  79. elseif ($prop_table !== FALSE) {
  80. array_push($prop_fields, $instance_name);
  81. }
  82. else {
  83. array_push($summary_fields, $instance_name);
  84. }
  85. }
  86. elseif ($instance_base_chado != $instance_base_table) {
  87. if ($data_sequence_record !== FALSE) {
  88. array_push($data_sequence_fields, $instance_name);
  89. }
  90. elseif ($data_sequence !== FALSE or $instance_name == 'so__cds' or $instance_name == 'data__protein_sequence') {
  91. // Do nothing as these chado column sequence fields
  92. // should be hidden by default.
  93. }
  94. elseif ($prop_table !== FALSE) {
  95. array_push($prop_fields, $instance_name);
  96. }
  97. else {
  98. array_push($all_other_fields, $instance);
  99. // Update the display settings so that the title is hidden.
  100. $instance['display']['default']['label'] = 'hidden';
  101. field_update_instance($instance);
  102. }
  103. }
  104. }
  105. else {
  106. // The tripal_chado module adds an image to the organism content
  107. // type so we want to make sure that image goes in the summary.
  108. // It is not a TripalField so it won't have a chado table.
  109. if ($instance_name == 'data__image' and $term->name == 'organism') {
  110. array_push($summary_fields, $instance_name);
  111. }
  112. }
  113. }
  114. }
  115. // Consolidate the field sets.
  116. if (!empty($summary_fields)) {
  117. _summary_field_group_info($bundle_name, $summary_fields);
  118. }
  119. if (!empty($prop_fields)) {
  120. _prop_field_group_info($bundle_name, $prop_fields);
  121. }
  122. if (!empty($data_sequence_fields)) {
  123. _data_sequence_field_group_info($bundle_name, $data_sequence_fields);
  124. }
  125. if (!empty($all_other_fields)) {
  126. foreach ($all_other_fields as $key => $other_field) {
  127. $group_field_name = 'gp_' . $other_field['field_name'];
  128. // Need to truncate the names because of database field size restrictions,
  129. // updating fields here to ensure name consistency.
  130. $group_field_name = substr($group_field_name, 0, 27);
  131. // Add random numbers to ensure the field name is unique within the 32
  132. // character limit of the field.
  133. $group_field_name = $group_field_name . rand(0, 99999);
  134. tripal_ds_additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $other_field['field_name']);
  135. }
  136. }
  137. // Build one large multidimensional array of all instances to sort in alpha
  138. // order to display fields in label alpha order.
  139. $right_fields = [];
  140. $all_field_groups = field_group_info_groups('TripalEntity', $bundle_name);
  141. if (!empty($all_field_groups)) {
  142. if (is_array($all_field_groups)) {
  143. if (!isset($all_field_groups['default'])) {
  144. $all_field_groups['default'] = [];
  145. }
  146. foreach ($all_field_groups['default'] as $key => $field_name) {
  147. $right_fields[$key] = $field_name;
  148. }
  149. usort($right_fields, tripal_ds_sort_object('label'));
  150. }
  151. }
  152. elseif (empty($all_field_groups)) {
  153. //Add the original instances that were passed and the field_groups that
  154. //were created.
  155. $field_group_fields = db_select('field_group', 'fg')
  156. ->fields('fg', ['group_name', 'data'])
  157. ->condition('bundle', $bundle_name, '=')
  158. ->execute()
  159. ->fetchAll();
  160. $instance_names = [];
  161. $field_group_names = [];
  162. foreach ($all_fields as $key => $instance) {
  163. $instance_names[$key]['field_name'] = $instance['field_name'];
  164. $instance_names[$key]['label'] = $instance['label'];
  165. }
  166. foreach ($field_group_fields as $key => $field_group_name) {
  167. $data = unserialize($field_group_name->data);
  168. $field_group_names[$key]['field_name'] = $field_group_name->group_name;
  169. $field_group_names[$key]['label'] = $data['format_settings']['label'];
  170. }
  171. $all_field_groups = array_merge($instance_names, $field_group_names);
  172. usort($all_field_groups, tripal_ds_sort_array('label'));
  173. }
  174. // Now build the $region_right array and the fields array.
  175. $i = 0;
  176. if (empty($right_fields)) {
  177. foreach ($all_field_groups as $index => $field) {
  178. $region_right[$i] = $field['field_name'];
  179. $i++;
  180. tripal_ds_field_group_update_weight($field['field_name'], $bundle_name, $i);
  181. }
  182. }
  183. elseif (!empty($right_fields)) {
  184. foreach ($right_fields as $index => $field) {
  185. // Check if the child is already present which is a problem when groups
  186. // are nested within groups.
  187. if (in_array($field->group_name, $region_right)) {
  188. // Still need to check for children and add them.
  189. if (!empty($field->children)) {
  190. foreach ($field->children as $index => $child) {
  191. $region_right[$i] = $child;
  192. $i++;
  193. }
  194. }
  195. }
  196. else {
  197. $region_right[$i] = $field->group_name;
  198. if (!empty($field->children)) {
  199. foreach ($field->children as $index => $child) {
  200. $i++;
  201. $region_right[$i] = $child;
  202. }
  203. }
  204. $i++;
  205. }
  206. // Now update the weights of the field_groups.
  207. tripal_ds_field_group_update_weight($field->group_name, $bundle_name, $i);
  208. }
  209. }
  210. foreach ($region_right as $index => $field) {
  211. $fields_with_regions[$field] = 'right';
  212. }
  213. // Add blocks to $region_left and build the toc field that is placed within.
  214. _ds_fields_info_write($bundle_name);
  215. $region_left = ['toc'];
  216. $fields_with_regions += ['toc' => 'left'];
  217. // Build the ds layout.
  218. $record = new stdClass;
  219. $record->id = 'TripalEntity|' . $bundle_name . '|default';
  220. $record->entity_type = 'TripalEntity';
  221. $record->bundle = $bundle_name;
  222. $record->view_mode = 'default';
  223. $record->layout = 'tripal_ds_feature';
  224. $settings = [
  225. 'regions' => [
  226. 'left' =>
  227. $region_left,
  228. 'right' =>
  229. $region_right,
  230. ],
  231. 'fields' =>
  232. $fields_with_regions,
  233. 'classes' => [],
  234. 'wrappers' => [
  235. 'left' => 'div',
  236. 'right' => 'div',
  237. ],
  238. 'layout_wrapper' => 'div',
  239. 'layout_attributes' => '',
  240. 'layout_attributes_merge' => 1,
  241. 'layout_link_attribute' => '',
  242. 'layout_link_custom' => '',
  243. 'layout_disable_css' => 0,
  244. ];
  245. $record->settings = $settings;
  246. drupal_write_record('ds_layout_settings', $record);
  247. // Clear the Drupal cache.
  248. drupal_flush_all_caches();
  249. } catch (Exception $e) {
  250. watchdog_exception('tripal_ds', $e);
  251. return FALSE;
  252. }
  253. return TRUE;
  254. }
  255. /**
  256. * Builds the tripal_ds layout for Publications.
  257. *
  258. * @param $bundle_name
  259. * Machine name of bundle, example bio_data_1
  260. * @param $instances
  261. *
  262. * @return bool
  263. */
  264. function _ds_layout_pub_settings_info($bundle_name, $instances) {
  265. $region_right = [];
  266. $region_left = [];
  267. $properties = [];
  268. $all_fields = [];
  269. $instances_for_field_groups = [];
  270. $disabled_instances = [];
  271. try {
  272. // Add Abstract, Citation, DB Cross Reference, Properties.
  273. $all_fields['tpub__abstract'] = 'right';
  274. $all_fields['tpub__citation'] = 'right';
  275. $all_fields['sbo__database_cross_reference'] = 'right';
  276. $all_fields['schema__additional_type'] = 'right';
  277. $all_fields['tpub__doi'] = 'right';
  278. $all_fields['tpub__publication_date'] = 'right';
  279. $all_fields['sio__references'] = 'right';
  280. // Iterate through the fields of this bundle.
  281. foreach ($instances as $key => $instance) {
  282. $instance_name = $instance['field_name'];
  283. if ($instance_name == 'sbo__database_cross_reference'
  284. || $instance_name == 'sio__references') {
  285. array_push($instances_for_field_groups, $instance);
  286. // Update the display settings so that the title is hidden.
  287. $instance['display']['default']['label'] = 'hidden';
  288. field_update_instance($instance);
  289. }
  290. elseif ($instance_name == 'schema__additional_type' || $instance_name == 'tpub__doi'
  291. || $instance_name == 'tpub__publication_date' || $instance_name == 'tpub__abstract' ||
  292. $instance_name == 'tpub__citation') {
  293. array_push($properties, $instance_name);
  294. }
  295. else {
  296. array_push($disabled_instances, $instance_name);
  297. }
  298. }
  299. //Publication fields that are not going in the properties table.
  300. foreach ($instances_for_field_groups as $key => $other_field) {
  301. // Temporary field names.
  302. $temporary_field = [];
  303. $group_field_name = 'gp_' . $other_field['field_name'];
  304. // Need to truncate the names because of database field size restrictions,
  305. // updating fields here to ensure name consistency.
  306. $group_field_name = substr($group_field_name, 0, 27);
  307. // Add random numbers to ensure the field name is unique within the 32
  308. // character limit of the field.
  309. $group_field_name = $group_field_name . rand(0, 99999);
  310. // Build the field group.
  311. tripal_ds_additional_fields_field_group_info($bundle_name, $other_field['label'], $group_field_name, $other_field['field_name']);
  312. // Update arrays.
  313. array_push($temporary_field, $group_field_name, $other_field['field_name']);
  314. $region_right = array_merge($region_right, $temporary_field);
  315. $all_fields += [$group_field_name => 'right',];
  316. }
  317. //Properties table fields.
  318. if (!empty($properties)) {
  319. _publication_prop_field_group_info($bundle_name, $properties);
  320. array_unshift($properties, 'group_summary_tripalpane', 'group_summary_table');
  321. $region_right = array_merge($region_right, $properties);
  322. $all_fields += [
  323. 'group_summary_tripalpane' => 'right',
  324. 'group_summary_table' => 'right',
  325. ];
  326. }
  327. if (!empty($all_fields)) {
  328. foreach ($disabled_instances as $disabled_field) {
  329. $all_fields += [$disabled_field => 'disabled'];
  330. }
  331. }
  332. // Add blocks to $region_left and build the toc field that is placed within.
  333. _ds_fields_info_write($bundle_name);
  334. $region_left += ['toc'];
  335. $all_fields += ['toc' => 'left'];
  336. // Build the ds layout.
  337. $record = new stdClass;
  338. $record->id = 'TripalEntity|' . $bundle_name . '|default';
  339. $record->entity_type = 'TripalEntity';
  340. $record->bundle = $bundle_name;
  341. $record->view_mode = 'default';
  342. $record->layout = 'tripal_ds_feature';
  343. $settings = [
  344. 'regions' => [
  345. 'left' =>
  346. $region_left,
  347. 'right' =>
  348. $region_right,
  349. ],
  350. 'fields' =>
  351. $all_fields,
  352. 'classes' => [],
  353. 'wrappers' => [
  354. 'left' => 'div',
  355. 'right' => 'div',
  356. ],
  357. 'layout_wrapper' => 'div',
  358. 'layout_attributes' => '',
  359. 'layout_attributes_merge' => 1,
  360. 'layout_link_attribute' => '',
  361. 'layout_link_custom' => '',
  362. 'layout_disable_css' => 0,
  363. ];
  364. $record->settings = $settings;
  365. drupal_write_record('ds_layout_settings', $record);
  366. // Clear the Drpual chace
  367. drupal_flush_all_caches();
  368. } catch (Exception $e) {
  369. watchdog_exception('tripal_ds', $e);
  370. return FALSE;
  371. }
  372. return TRUE;
  373. }
  374. /**
  375. * Implements hook_ds_fields_info().
  376. * Creates the Table of Contents field.
  377. *
  378. * $param $entity_type
  379. */
  380. function tripal_ds_ds_fields_info($entity_type) {
  381. $fields = [];
  382. $fields['toc'] = [
  383. 'title' => t('Table of Contents'),
  384. 'field_type' => DS_FIELD_TYPE_FUNCTION,
  385. 'function' => 'tripal_ds_toc_block',
  386. ];
  387. return ['TripalEntity' => $fields];
  388. }
  389. /**
  390. * Adds the content the to Table of Contents block.
  391. *
  392. * @param $entity_type
  393. *
  394. * @return Object
  395. */
  396. function tripal_ds_toc_block($entity_type) {
  397. $bundle_name = $entity_type['bundle'];
  398. $toc = views_embed_view('tripal_content_type_toc', 'block', $bundle_name);
  399. return $toc;
  400. }
  401. /**
  402. * Creates the field_group for the Table of Contents.
  403. *
  404. * @param $bundle_name
  405. * Machine name of bundle, example bio_data_1
  406. */
  407. function _ds_fields_info_write($bundle_name) {
  408. $fields = new stdClass;
  409. $fields->id = 'TripalEntity|' . $bundle_name . '|default';
  410. $fields->entity_type = 'TripalEntity';
  411. $fields->bundle = $bundle_name;
  412. $fields->view_mode = 'default';
  413. $fields->settings = [
  414. 'toc' => [
  415. 'weight' => 0,
  416. 'label' => 'hidden',
  417. 'format' => 'default',
  418. ],
  419. ];
  420. drupal_write_record('ds_field_settings', $fields);
  421. }