TripalBundleUIController.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. <?php
  2. /**
  3. * @file
  4. */
  5. /**
  6. * UI controller.
  7. */
  8. class TripalBundleUIController extends EntityDefaultUIController {
  9. public function __construct($entity_type, $entity_info) {
  10. parent::__construct($entity_type, $entity_info);
  11. }
  12. /**
  13. * Overrides hook_menu() defaults.
  14. */
  15. public function hook_menu() {
  16. $items = parent::hook_menu();
  17. // Alter the Admin > Structure > Tripal Content Types menu item.
  18. $items[$this->path]['description'] = 'Manage biological content types that are
  19. added using Tripal.';
  20. // We don't want to let the user import new Tripal data types.
  21. unset($items[$this->path . '/import']);
  22. // Add an action link to Admin > Structure > Tripal Content Types for adding types.
  23. $items[$this->path . '/add'] = array(
  24. 'title' => 'Add Tripal Content Type',
  25. 'description' => 'Add new biological content',
  26. 'page callback' => 'drupal_get_form',
  27. 'page arguments' => array('tripal_entities_admin_add_type_form'),
  28. 'access arguments' => array('administer tripal data types'),
  29. 'file' => 'includes/tripal_entities.admin.inc',
  30. 'file path' => drupal_get_path('module', 'tripal_entities'),
  31. 'type' => MENU_LOCAL_ACTION,
  32. 'weight' => 2
  33. );
  34. return $items;
  35. }
  36. /**
  37. * Allows us to change the forms created by the parent class.
  38. */
  39. function hook_forms() {
  40. $forms = parent::hook_forms();
  41. // The edit form for the entity type by default expects a function,
  42. // named after the entity type but we can't dynamically create these
  43. // functions. We'll use a single form for all entity types.
  44. $forms[$this->entityType . '_form'] = array(
  45. 'callback' => 'tripal_entities_tripal_bundle_form',
  46. 'callback arguments' => array($this->entityType)
  47. );
  48. return $forms;
  49. }
  50. }
  51. /**
  52. * Tripal content type edit form.
  53. *
  54. * @param $form
  55. * The default form array. Usually empty.
  56. * @param $form_state
  57. * Build information for the form including the entity type and submitted values.
  58. * @param $entityDataType
  59. * A string indicating the entity type. This will always be TripalBundle.
  60. */
  61. function tripal_entities_tripal_bundle_form($form, &$form_state, $entityDataType) {
  62. $entity_type = $form_state['build_info']['args'][0];
  63. $term = NULL;
  64. $vocab = NULL;
  65. if (preg_match('/bio-data_(\d+)/', $entity_type->bundle, $matches)) {
  66. $term = entity_load('TripalTerm', array('id' => $matches[1]));
  67. $term = reset($term);
  68. $vocab = entity_load('TripalVocab', array('id' => $term->vocab_id));
  69. $vocab = reset($vocab);
  70. }
  71. // Add a validate and submit handler to save the data in this form.
  72. $form['#validate'] = array('tripal_entities_tripal_bundle_form_validate');
  73. $form['#submit'] = array('tripal_entities_tripal_bundle_form_submit');
  74. // @TODO: Move this into a css file.
  75. $form['#attached']['css'] = array(
  76. array(
  77. 'data' => '
  78. .form-item select, .form-item input { width:40%; }
  79. th.side-header { width: 220px; }',
  80. 'type' => 'inline',
  81. ),
  82. );
  83. if ($term) {
  84. $form['term'] = array(
  85. '#type' => 'markup',
  86. '#markup' => theme('table', array(
  87. 'header' => array(),
  88. 'rows' => array(
  89. array(array('header' => TRUE, 'data' => 'Vocabulary', 'class' => array('side-header')), $vocab->namespace),
  90. array(array('header' => TRUE, 'data' => 'Term', 'class' => array('side-header')), $term->name),
  91. )
  92. ))
  93. );
  94. }
  95. $form['label'] = array(
  96. '#type' => 'textfield',
  97. '#title' => t('Name'),
  98. '#required' => TRUE,
  99. '#description' => t('The human-readable name of this content type. This text will be
  100. displayed as part of the list on the <em>Add new content page</em>. It is recommended that
  101. this name begin with a capital letter and contain only letters, numbers, and spaces.
  102. This name must be unique.'),
  103. '#default_value' => $entity_type->label,
  104. );
  105. $form['description'] = array(
  106. '#type' => 'textarea',
  107. '#title' => t('Description'),
  108. '#required' => TRUE,
  109. '#description' => t('Describe this content type. The text will be displayed on the <em>Add new content page</em>.'),
  110. );
  111. if ($term) {
  112. $form['description']['#default_value'] = tripal_get_bundle_variable('description', $entity_type->id, $term->definition);
  113. }
  114. else {
  115. $form['description']['#default_value'] = tripal_get_bundle_variable('description', $entity_type->id, '');
  116. }
  117. $form['additional_settings'] = array(
  118. '#type' => 'vertical_tabs',
  119. '#weight' => 99,
  120. );
  121. // Set Title Format.
  122. //-------------------------
  123. $title_format = tripal_get_title_format($entity_type);
  124. $form['set_titles'] = array(
  125. '#type' => 'fieldset',
  126. '#title' => t('Page Title options'),
  127. '#collapsible' => TRUE,
  128. '#collapsed' => FALSE,
  129. '#tree' => TRUE,
  130. '#group' => 'additional_settings',
  131. );
  132. $form['set_titles']['explanation'] = array(
  133. '#type' => 'item',
  134. '#markup' => t('<p>The format below is used to determine the title displayed on content
  135. pages. This ensures all content of this type is consistent while still allowing you
  136. to indicate which data you want represented in the title (ie: which data would most
  137. identify your content).</p>
  138. <p>Keep in mind that it might be confusing to users if more than
  139. one page has the same title. We recommend you <strong>choose a combination of tokens that
  140. will uniquely identify your content</strong>.</p>'),
  141. );
  142. $form['set_titles']['title_format'] = array(
  143. '#type' => 'textarea',
  144. '#title' => t('Page Title Format'),
  145. '#description' => t('You may rearrange elements in this text box to customize the page
  146. titles. The available tokens are listed below. You can separate or include any text
  147. between the tokens.'),
  148. '#required' => TRUE,
  149. '#default_value' => $title_format,
  150. '#rows' => 1
  151. );
  152. $form['set_titles']['token_display'] = array(
  153. '#type' => 'fieldset',
  154. '#title' => t('Available Tokens'),
  155. '#description' => t('Copy the token and paste it into the "Custom Page Title" text field above.'),
  156. '#collapsible' => TRUE,
  157. '#collapsed' => TRUE
  158. );
  159. $tokens = tripal_get_tokens($entity_type);
  160. $form['set_titles']['tokens'] = array(
  161. '#type' => 'hidden',
  162. '#value' => serialize($tokens)
  163. );
  164. $form['set_titles']['token_display']['content'] = array(
  165. '#type' => 'item',
  166. '#markup' => theme_token_list($tokens)
  167. );
  168. // Submit Buttons
  169. //-------------------------
  170. $form['save'] = array(
  171. '#type' => 'submit',
  172. '#value' => t('Save Content Type'),
  173. '#weight' => 100
  174. );
  175. $form['delete'] = array(
  176. '#type' => 'submit',
  177. '#value' => t('Delete Content Type'),
  178. '#weight' => 101
  179. );
  180. return $form;
  181. }
  182. /**
  183. * Validate: Tripal content type edit form.
  184. */
  185. function tripal_entities_tripal_bundle_form_validate($form, $form_state) {
  186. $tokens_available = unserialize($form_state['values']['set_titles']['tokens']);
  187. if (preg_match_all('/(\[\w+\])/', $form_state['values']['set_titles']['title_format'], $matches)) {
  188. // The matches of the first and only pattern will be our tokens.
  189. $tokens_used = $matches[1];
  190. // Determine if any of the tokens used were not in the original list of available tokens.
  191. $tokens_missing = array_diff($tokens_used, array_keys($tokens_available));
  192. if ($tokens_missing) {
  193. $msg = t('You must only use tokens listed under available tokens. You used the following incorrect tokens: %tokens',
  194. array('%tokens' => implode(', ', $tokens_missing)));
  195. form_set_error('set_titles][title_format', $msg);
  196. }
  197. }
  198. else {
  199. $msg = t('You should use at least one token in your title format or the title for all %type pages will be the same.',
  200. array('%type' => $form_state['build_info']['args'][0]->label));
  201. form_set_error('set_titles][title_format', $msg);
  202. }
  203. }
  204. /**
  205. * Submit: Tripal content type edit form.
  206. */
  207. function tripal_entities_tripal_bundle_form_submit($form, &$form_state) {
  208. if ($form_state['triggering_element']['#value'] == 'Save Content Type') {
  209. $bundle_entity = $form_state['build_info']['args'][0];
  210. // Save the label.
  211. $bundle_entity->label = $form_state['values']['label'];
  212. $bundle_entity->save();
  213. // Save the description.
  214. tripal_set_bundle_variable('description', $bundle_entity->id, $form_state['values']['description']);
  215. // Save the page title format.
  216. tripal_save_title_format(
  217. $bundle_entity,
  218. $form_state['values']['set_titles']['title_format']
  219. );
  220. $form_state['redirect'] = 'admin/structure/bio-data';
  221. drupal_set_message(t('Successfully saved %type content type.', array('%type' => $form_state['build_info']['args'][0]->label)));
  222. }
  223. else {
  224. drupal_set_message(t('%button is not supported at this time.', array('%button' => $form_state['triggering_element']['#value'])), 'warning');
  225. }
  226. }
  227. /**
  228. * Access callback for the entity API.
  229. */
  230. function tripal_bundle_access($op, $type = NULL, $account = NULL) {
  231. return user_access('administer tripal data types', $account);
  232. }
  233. /**
  234. * Form for creating tripal data types.
  235. *
  236. * This form is available on the menu at Admin >> Structure >> Biological Data
  237. * Types. It requires that a module implmennt the vocabulary storage. Tripal
  238. * knows which vocabulary storage methods are available when a module
  239. * implements the hook_vocab_storage_info() hook.
  240. *
  241. */
  242. function tripal_entities_admin_add_type_form($form, &$form_state) {
  243. // TODO: we need some sort of administrative interface that lets the user
  244. // switch to the desired vocabulary type. For now, we'll just use the
  245. // first one in the list.
  246. $stores = module_invoke_all('vocab_storage_info');
  247. if (is_array($stores) and count($stores) > 0) {
  248. $keys = array_keys($stores);
  249. $module = $stores[$keys[0]]['module'];
  250. $function = $module . '_vocab_select_term_form';
  251. if (function_exists($function)) {
  252. $form = $function($form, $form_state);
  253. }
  254. }
  255. else {
  256. tripal_set_message('A storage backend is not enabled for managing
  257. the vocabulary terms used to create content. Please enable
  258. a module that supports storage of vocabualary terms (e.g. tripal_chado)
  259. and return to create new Tripal content types.', TRIPAL_NOTICE);
  260. }
  261. return $form;
  262. }
  263. /**
  264. * Implements hook_validate() for the tripal_entities_admin_add_type_form.
  265. *
  266. */
  267. function tripal_entities_admin_add_type_form_validate($form, &$form_state) {
  268. // TODO: we need some sort of administrative interface that lets the user
  269. // switch to the desired vocabulary type. For now, we'll just use the
  270. // first one in the list.
  271. $stores = module_invoke_all('vocab_storage_info');
  272. if (is_array($stores) and count($stores) > 0) {
  273. $keys = array_keys($stores);
  274. $module = $stores[$keys[0]]['module'];
  275. $function = $module . '_vocab_select_term_form_validate';
  276. if (function_exists($function)) {
  277. $function($form, $form_state);
  278. }
  279. }
  280. }
  281. /**
  282. * Implements hook_submit() for the tripal_entities_admin_add_type_form.
  283. *
  284. * The storage backend must set the
  285. *
  286. */
  287. function tripal_entities_admin_add_type_form_submit($form, &$form_state) {
  288. $namespace = '';
  289. $term_id = '';
  290. if (array_key_exists('storage', $form_state)) {
  291. $storage = $form_state['storage'];
  292. $namespace = array_key_exists('namespace', $storage) ? $storage['namespace'] : '';
  293. $term_id = array_key_exists('term_id', $storage) ? $storage['term_id'] : '';
  294. $term_name = array_key_exists('term_name', $storage) ? $storage['term_name'] : '';
  295. // Before we try to add this type, check to see if it already exists
  296. // as a bundle.
  297. $term = tripal_load_term_entity($namespace, $term_id);
  298. if (!$term) {
  299. $error = '';
  300. $success = tripal_create_bundle($namespace, $term_id, $term_name, $error);
  301. if (!$success) {
  302. drupal_set_message($error, 'error');
  303. $form_state['redirect'] = "admin/structure/bio-data";
  304. }
  305. else {
  306. drupal_set_message('New biological data type created. Fields are added automatically to this type.');
  307. $form_state['redirect'] = "admin/structure/bio-data";
  308. }
  309. }
  310. else {
  311. drupal_set_message('This type already exists.', 'warning');
  312. }
  313. }
  314. }