tripal.module 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  1. <?php
  2. /**
  3. * @file
  4. * The Tripal Core module
  5. */
  6. // Import the full Tripal API into scope.
  7. tripal_import_api();
  8. require_once "includes/tripal.field_storage.inc";
  9. require_once "includes/tripal.fields.inc";
  10. require_once "includes/tripal.entity.inc";
  11. require_once "includes/TripalVocab.inc";
  12. require_once "includes/TripalVocabController.inc";
  13. require_once "includes/TripalVocabViewsController.inc";
  14. require_once "includes/TripalTerm.inc";
  15. require_once "includes/TripalTermController.inc";
  16. require_once "includes/TripalTermViewsController.inc";
  17. require_once "includes/TripalEntity.inc";
  18. require_once "includes/TripalEntityController.inc";
  19. require_once "includes/TripalEntityUIController.inc";
  20. require_once "includes/TripalEntityViewsController.inc";
  21. require_once "includes/TripalBundle.inc";
  22. require_once "includes/TripalBundleController.inc";
  23. require_once "includes/TripalBundleUIController.inc";
  24. require_once "includes/TripalBundleViewsController.inc";
  25. require_once "includes/TripalFields/TripalField.inc";
  26. require_once "includes/TripalFields/TripalFieldWidget.inc";
  27. require_once "includes/TripalFields/TripalFieldFormatter.inc";
  28. require_once "includes/TripalFieldQuery.inc";
  29. require_once "includes/TripalJob.inc";
  30. require_once "includes/TripalImporter.inc";
  31. /**
  32. * @defgroup tripal Tripal Core Module
  33. * @ingroup tripal_modules
  34. * @{
  35. * Functionality useful for all other Tripal modules including the Tripal jobs, files,
  36. * materialized views and custom table functions.
  37. * @}
  38. */
  39. /**
  40. * Implements hook_views_api().
  41. */
  42. function tripal_views_api() {
  43. return array(
  44. 'api' => 3,
  45. );
  46. }
  47. /**
  48. * Implements hook_init().
  49. *
  50. * @ingroup tripal
  51. */
  52. function tripal_init() {
  53. global $base_url;
  54. // add some variables for all javasript to use for building URLs
  55. $clean_urls = variable_get('clean_url', 0);
  56. $tripal_path = url(drupal_get_path('module', 'tripal'));
  57. drupal_add_js("
  58. var baseurl = '$base_url';
  59. var isClean = $clean_urls;
  60. var tripal_path = '$tripal_path';",
  61. 'inline', 'header');
  62. // make sure the date time settings are the way Tripal will insert them
  63. // otherwise PostgreSQL version that may have a different datestyle setting
  64. // will fail when inserting or updating a date column in a table.
  65. db_query("SET DATESTYLE TO :style", array(':style' => 'MDY'));
  66. }
  67. function tripal_menu_alter(&$items) {
  68. //drupal_debug($items);
  69. }
  70. /**
  71. * Implements hook_menu().
  72. * Defines all menu items needed by Tripal Core
  73. *
  74. * @ingroup tripal
  75. */
  76. function tripal_menu() {
  77. $items = array();
  78. // Tripal setting groups
  79. $items['admin/tripal'] = array(
  80. 'title' => 'Tripal',
  81. 'description' => t("Manage the behavior or Tripal and its various modules."),
  82. 'weight' => -8,
  83. 'page callback' => 'system_admin_menu_block_page',
  84. 'access arguments' => array('administer tripal'),
  85. 'file' => 'system.admin.inc',
  86. 'file path' => drupal_get_path('module', 'system'),
  87. );
  88. $items['admin/tripal/storage'] = array(
  89. 'title' => 'Data Storage',
  90. 'description' => t("Tripal is designed to access biological
  91. data in any data storage back-end. A storage back-end must have a
  92. module that can be installed that interfaces with Tripal. By default
  93. the base Tripal package provides The Tripal Chado module for storing
  94. data in the GMOD Chado database schema. All available storage backends
  95. and their administrative tools are found here."),
  96. 'weight' => 8,
  97. 'access arguments' => array('administer tripal'),
  98. );
  99. $items['admin/tripal/dashboard'] = array(
  100. 'title' => 'Dashboard',
  101. 'description' => t("A dashboard view of Tripal including new fields for entities."),
  102. 'weight' => 0,
  103. 'page callback' => 'tripal_admin_usage_page',
  104. 'access arguments' => array('administer tripal'),
  105. 'type' => MENU_NORMAL_ITEM,
  106. 'file' => 'includes/tripal_admin_usage_page.inc',
  107. 'file path' => drupal_get_path('module', 'tripal'),
  108. );
  109. // $items['admin/tripal/loaders/obo_loader'] = array(
  110. // 'title' => 'OBO Controlled Vocabulary Loader',
  111. // 'description' => t("Import vocabularies and terms in OBO format."),
  112. // 'access arguments' => array('administer tripal'),
  113. // 'page callback' => 'drupal_get_form',
  114. // 'page arguments' => array('tripal_vocabulary_import_form'),
  115. // 'file' => 'includes/tripal.admin.inc',
  116. // 'file path' => drupal_get_path('module', 'tripal'),
  117. // 'type' => MENU_NORMAL_ITEM,
  118. // );
  119. $items['admin/tripal/extension'] = array(
  120. 'title' => 'Extensions',
  121. 'description' => t("Configuration and management pages for Tripal extension modules."),
  122. 'weight' => 8,
  123. 'access arguments' => array('administer tripal'),
  124. );
  125. // Menu items for facilitating import of extension modules.
  126. $items['admin/tripal/extension/available'] = array(
  127. 'title' => 'Available Extensions',
  128. 'description' => t('Look for extensions to add new functionality to this
  129. site. Tripal can be extended with new functionality developed
  130. by other Tripal site developers. These include modules with new or
  131. different functionality, bulk loading templates, or materialized
  132. views. Anyone can create new extensions and share those for
  133. others to use. Once shared they will appear in this list.'),
  134. 'access arguments' => array('administer tripal'),
  135. 'page callback' => 'drupal_get_form',
  136. 'page arguments' => array('tripal_extensions_form'),
  137. 'type' => MENU_NORMAL_ITEM,
  138. 'file' => 'includes/tripal.extensions.inc',
  139. 'file path' => drupal_get_path('module', 'tripal'),
  140. 'weight' => -100
  141. );
  142. // $items['admin/tripal/extension/import'] = array(
  143. // 'title' => 'Import Extensions',
  144. // 'description' => 'Provides a list of the available extensions that are registered at the tripal.info site. From this page you can easily import or install extensions to your site.',
  145. // 'page callback' => 'drupal_get_form',
  146. // 'page arguments' => array('tripal_extensions_form'),
  147. // 'access arguments' => array('administer tripal'),
  148. // 'type' => MENU_NORMAL_ITEM,
  149. // 'file' => 'includes/tripal.extensions.inc',
  150. // 'file path' => drupal_get_path('module', 'tripal'),
  151. // 'weight' => -100,
  152. // );
  153. // Jobs Management
  154. $items['admin/tripal/tripal_jobs'] = array(
  155. 'title' => 'Jobs',
  156. 'description' => t('Provides tools for managing jobs submitted to Tripal. In some
  157. cases, long-running tasks are too slow to complete within a single
  158. browser session. The Tripal jobs system allows long-running tasks
  159. to be submitted to a queue that can be executed manually by the
  160. site admin or automatically using a module such as the ') .
  161. l('Tripal Daemon', 'https://www.drupal.org/project/tripal_daemon', array('attributes' => array('target' => '_blank'))) .
  162. ' extension module.',
  163. 'page callback' => 'tripal_jobs_admin_view',
  164. 'access arguments' => array('administer tripal'),
  165. 'type' => MENU_NORMAL_ITEM,
  166. 'weight' => 0,
  167. 'file' => 'includes/tripal.jobs.inc',
  168. );
  169. $items['admin/tripal/tripal_jobs/help'] = array(
  170. 'title' => 'Help',
  171. 'description' => t('Help for the tripal job management system'),
  172. 'page callback' => 'theme',
  173. 'page arguments' => array('tripal_job_help'),
  174. 'access arguments' => array('administer tripal'),
  175. 'type' => MENU_LOCAL_TASK,
  176. 'weight' => 10
  177. );
  178. $items['admin/tripal/tripal_jobs/cancel/%'] = array(
  179. 'title' => 'Jobs',
  180. 'description' => t('Cancel a pending job'),
  181. 'page callback' => 'tripal_cancel_job',
  182. 'page arguments' => array(4),
  183. 'access arguments' => array('administer tripal'),
  184. 'type' => MENU_CALLBACK,
  185. 'file' => 'api/tripal.jobs.api.inc',
  186. );
  187. $items['admin/tripal/tripal_jobs/status/%'] = array(
  188. 'page callback' => 'tripal_jobs_status_view',
  189. 'page arguments' => array(4),
  190. 'access arguments' => array('administer tripal'),
  191. 'type' => MENU_CALLBACK,
  192. 'file' => 'includes/tripal.jobs.inc',
  193. );
  194. $items['admin/tripal/tripal_jobs/rerun/%'] = array(
  195. 'title' => 'Jobs',
  196. 'description' => t('Re-run an existing job.'),
  197. 'page callback' => 'tripal_rerun_job',
  198. 'page arguments' => array(4),
  199. 'access arguments' => array('administer tripal'),
  200. 'type' => MENU_CALLBACK,
  201. 'file' => 'includes/tripal.jobs.inc',
  202. );
  203. $items['admin/tripal/tripal_jobs/view/%'] = array(
  204. 'title' => 'Jobs Details',
  205. 'description' => t('View job details.'),
  206. 'page callback' => 'tripal_jobs_view',
  207. 'page arguments' => array(4),
  208. 'access arguments' => array('administer tripal'),
  209. 'type' => MENU_CALLBACK,
  210. 'file' => 'includes/tripal.jobs.inc',
  211. );
  212. $items['admin/tripal/tripal_jobs/views/jobs/enable'] = array(
  213. 'title' => 'Enable Jobs Administrative View',
  214. 'page callback' => 'tripal_enable_view',
  215. 'page arguments' => array('tripal_admin_jobs', 'admin/tripal/tripal_jobs'),
  216. 'access arguments' => array('administer tripal'),
  217. 'type' => MENU_CALLBACK,
  218. 'file' => 'includes/tripal.jobs.inc',
  219. );
  220. /*
  221. * AJAX Callbacks.
  222. */
  223. $items['bio_data/ajax/field_attach/%'] = array(
  224. 'page callback' => 'tripal_ajax_attach_field',
  225. 'page arguments' => array(3),
  226. 'access arguments' => array('access content'),
  227. 'type' => MENU_CALLBACK,
  228. 'file' => 'includes/tripal.entity.inc',
  229. 'file path' => drupal_get_path('module', 'tripal'),
  230. );
  231. /*
  232. * Dashboard Action Item callbacks.
  233. */
  234. $items['admin/disable/notification/%'] = array(
  235. 'page callback' => 'tripal_disable_admin_notification',
  236. 'page arguments' => array(3),
  237. 'access arguments' => array('access content'),
  238. 'type' => MENU_CALLBACK,
  239. 'file' => 'includes/tripal_admin_usage_page.inc',
  240. 'file path' => drupal_get_path('module', 'tripal'),
  241. );
  242. $items['admin/import/field/%/%/%/%'] = array(
  243. 'page callback' => 'tripal_admin_notification_import_field',
  244. 'page arguments' => array(3, 4, 5, 6),
  245. 'access arguments' => array('access content'),
  246. 'type' => MENU_CALLBACK,
  247. 'file' => 'includes/tripal_admin_usage_page.inc',
  248. 'file path' => drupal_get_path('module', 'tripal'),
  249. );
  250. /*
  251. * Term Lookup
  252. */
  253. // TODO: finish this menu callback.
  254. // $items['cv/lookup'] = array(
  255. // 'title' => 'Vocabulary Lookup',
  256. // 'description' => t("Provides a tool to discover controlled vocabularies and their terms used by this site."),
  257. // 'access arguments' => array('access content'),
  258. // 'page callback' => 'drupal_get_form',
  259. // 'page arguments' => array('tripal_vocabulary_lookup_form'),
  260. // 'file' => 'includes/tripal.term_lookup.inc',
  261. // 'file path' => drupal_get_path('module', 'tripal'),
  262. // 'type' => MENU_NORMAL_ITEM,
  263. // );
  264. $items['cv/lookup/%/%'] = array(
  265. 'title' => 'Vocabulary Lookup',
  266. 'description' => t("Provides a tool to discover controlled vocabularies and their terms used by this site."),
  267. 'access arguments' => array('access content'),
  268. 'page callback' => 'tripal_vocabulary_lookup_term_page',
  269. 'page arguments' => array(2, 3),
  270. 'file' => 'includes/tripal.term_lookup.inc',
  271. 'file path' => drupal_get_path('module', 'tripal'),
  272. 'type' => MENU_CALLBACK,
  273. );
  274. // Adds a +Check for new fields link on the 'Tripal Content Types' page.
  275. $items['admin/structure/bio_data/manage/%/fields/check'] = array(
  276. 'title' => 'Check for new fields',
  277. 'description' => t('Check if new fields should be added to this content type.'),
  278. 'page callback' => 'tripal_check_new_fields',
  279. 'page arguments' => array(4),
  280. 'access arguments' => array('administer tripal'),
  281. 'file' => 'api/tripal.entities.api.inc',
  282. 'file path' => drupal_get_path('module', 'tripal'),
  283. 'type' => MENU_LOCAL_ACTION,
  284. );
  285. $items['tripal/upload'] = array(
  286. 'page callback' => 'tripal_file_upload',
  287. 'access arguments' => array('upload files'),
  288. 'file' => '/includes/tripal.upload.inc',
  289. 'type' => MENU_CALLBACK,
  290. );
  291. // Add in the loaders
  292. $importers = tripal_get_importers();
  293. foreach ($importers as $class_name) {
  294. tripal_load_include_importer_class($class_name);
  295. if (class_exists($class_name)) {
  296. $items['admin/tripal/loaders/' . $class_name::$machine_name] = array(
  297. 'title' => $class_name::$name,
  298. 'description' => $class_name::$description,
  299. 'page callback' => 'drupal_get_form',
  300. 'page arguments' => array('tripal_get_importer_form', $class_name),
  301. 'access arguments' => array('administer tripal'),
  302. 'type' => MENU_NORMAL_ITEM,
  303. 'file' => 'includes/tripal.importer.inc',
  304. 'file path' => drupal_get_path('module', 'tripal'),
  305. );
  306. }
  307. }
  308. return $items;
  309. }
  310. /**
  311. * Implements hook_permission().
  312. */
  313. function tripal_permission() {
  314. $permissions = array(
  315. 'administer tripal' => array(
  316. 'title' => t('Administer Tripal'),
  317. 'description' => t('Allow the user to access administrative pages of Tripal. This includes management of jobs, the storage systems, extensions and the controlled vocabularies.'),
  318. 'restrict access' => TRUE,
  319. ),
  320. 'access tripal content overview' => array(
  321. 'title' => t('Access the Tripal content overview page'),
  322. 'description' => t('Get an overview of all Tripal content'),
  323. 'restrict access' => TRUE,
  324. ),
  325. 'manage tripal content types' => array(
  326. 'title' => t('Manage Tripal content types'),
  327. 'description' => t('Allows the user to create, update and delete Tripal content types.'),
  328. 'restrict access' => TRUE,
  329. ),
  330. 'upload files' => array(
  331. 'title' => t('Upload Files'),
  332. 'description' => t('Allows the user to upload files using Tripal\'s HTML5 loader.'),
  333. ),
  334. 'view dev helps' => array(
  335. 'title' => t('View Developer Hints'),
  336. 'description' => t('Tripal will provide blue shaded boxes that provide
  337. instructions for how to customize or setup specific pages on a
  338. site. This permission should be enabled for developers. But can
  339. be disabled once developers are accustomed to these hints.'),
  340. 'restrict access' => TRUE,
  341. ),
  342. );
  343. // Add permissions for each content type.
  344. $bundles = tripal_get_content_types();
  345. foreach ($bundles as $bundle) {
  346. $permissions['view ' . $bundle->name] = array(
  347. 'title' => t('%label: View Content', array('%label' => $bundle->label)),
  348. 'description' => t('Allow the user to view %label content', array('%label' => $bundle->label)),
  349. );
  350. $permissions['create ' . $bundle->name] = array(
  351. 'title' => t('%label: Create Content', array('%label' => $bundle->label)),
  352. 'description' => t('Allow the user to create %label content', array('%label' => $bundle->label)),
  353. 'restrict access' => TRUE,
  354. );
  355. $permissions['edit ' . $bundle->name] = array(
  356. 'title' => t('%label: Edit Content', array('%label' => $bundle->label)),
  357. 'description' => t('Allow the user to edit %label content', array('%label' => $bundle->label)),
  358. 'restrict access' => TRUE,
  359. );
  360. $permissions['delete ' . $bundle->name] = array(
  361. 'title' => t('%label: Delete Content', array('%label' => $bundle->label)),
  362. 'description' => t('Allow the user to delete %label content', array('%label' => $bundle->label)),
  363. 'restrict access' => TRUE,
  364. );
  365. }
  366. return $permissions;
  367. }
  368. /**
  369. * Implements hook_theme().
  370. * Registers template files/functions used by this module.
  371. *
  372. * @ingroup tripal
  373. */
  374. function tripal_theme($existing, $type, $theme, $path) {
  375. $themes = array(
  376. // Admin messages theme
  377. 'tripal_admin_message' => array(
  378. 'function' => 'theme_tripal_admin_message',
  379. 'variables' => array('message' => NULL),
  380. ),
  381. 'tripal_entity' => array(
  382. 'render element' => 'elements',
  383. 'template' => 'tripal_entity',
  384. 'path' => "$path/theme/templates"
  385. ),
  386. 'tripal_add_list' => array(
  387. 'variables' => array('content' => NULL),
  388. ),
  389. // Themeing for all fields.
  390. 'tripal_field_default' => array(
  391. 'render element' => 'element',
  392. 'file' => 'includes/tripal.fields.inc',
  393. ),
  394. );
  395. return $themes;
  396. }
  397. /**
  398. * Implements hook_coder_ignore().
  399. * Defines the path to the file (tripal.coder_ignores.txt) where ignore rules for coder are stored
  400. */
  401. function tripal_coder_ignore() {
  402. return array(
  403. 'path' => drupal_get_path('module', 'tripal'),
  404. 'line prefix' => drupal_get_path('module', 'tripal'),
  405. );
  406. }
  407. /**
  408. * Implements hook_libraries_info().
  409. */
  410. function tripal_libraries_info() {
  411. $libraries = array();
  412. $libraries['d3'] = array(
  413. 'name' => 'D3.js',
  414. 'vendor url' => 'http://d3js.org/',
  415. 'download url' => 'https://github.com/mbostock/d3',
  416. 'version arguments' => array(
  417. 'file' => 'd3.js',
  418. 'pattern' => '/\s*version: "(\d+\.\d+\.\d+)"/',
  419. ),
  420. 'files' => array(
  421. 'js' => array(
  422. 'd3.min.js',
  423. ),
  424. ),
  425. );
  426. return $libraries;
  427. }
  428. /**
  429. * Implements hook_admin_paths().
  430. * Define administrative paths.
  431. */
  432. function tripal_admin_paths() {
  433. if (variable_get('node_admin_theme')) {
  434. $paths = array(
  435. 'bio_data/*/edit' => TRUE,
  436. 'bio_data/*/delete' => TRUE,
  437. 'bio_data/add' => TRUE,
  438. 'bio_data/add/*' => TRUE,
  439. );
  440. return $paths;
  441. }
  442. }
  443. /**
  444. * Implements hook_menu_local_tasks_alter().
  445. *
  446. * Used to add action links to pages.
  447. */
  448. function tripal_menu_local_tasks_alter(&$data, $router_item, $root_path) {
  449. // Add an "Add Tripal Content" action link to the Admin >> Content >>
  450. // Biological Content page.
  451. if ($root_path == 'admin/content/bio_data') {
  452. $item = menu_get_item('bio_data/add');
  453. if ($item['access']) {
  454. $data['actions']['output'][] = array(
  455. '#theme' => 'menu_local_action',
  456. '#link' => $item,
  457. );
  458. }
  459. }
  460. }
  461. /**
  462. * Implements hook_shortcut_default_set().
  463. * Modify the shortcut menu to include Biological content links.
  464. *
  465. * @param object $account
  466. * The user account whose default shortcut set will be returned. If not provided, the
  467. * function will return the currently logged-in user's default shortcut set.
  468. *
  469. * @return
  470. * An object representing the default shortcut set.
  471. */
  472. function tripal_shortcut_default_set($account) {
  473. $sets = shortcut_sets();
  474. $found = FALSE;
  475. foreach ($sets as $set) {
  476. if ($set->title == 'TripalDefault') {
  477. $found = TRUE;
  478. }
  479. }
  480. if (!$found) {
  481. $t = get_t();
  482. // Create an initial default shortcut set.
  483. $shortcut_set = new stdClass();
  484. $shortcut_set->title = $t('TripalDefault');
  485. $shortcut_set->links = array(
  486. array(
  487. 'link_path' => 'node/add',
  488. 'link_title' => $t('Add content'),
  489. 'weight' => -35,
  490. ),
  491. array(
  492. 'link_path' => 'bio_data/add',
  493. 'link_title' => 'Add Tripal Content',
  494. 'weight' => -30,
  495. ),
  496. array(
  497. 'link_path' => 'admin/content',
  498. 'link_title' => $t('Find content'),
  499. 'weight' => -25,
  500. ),
  501. array(
  502. 'link_path' => 'admin/content/bio_data',
  503. 'link_title' => 'Find Tripal Content',
  504. 'weight' => -20,
  505. ),
  506. );
  507. shortcut_set_save($shortcut_set);
  508. }
  509. $sets = shortcut_sets();
  510. foreach ($sets as $set) {
  511. if ($set->title == 'TripalDefault') {
  512. return $set->set_name;
  513. }
  514. }
  515. }
  516. /**
  517. * Menu argument loader; Load a tripal data type by string.
  518. *
  519. * This function is not meant to be used as an API function. It is only meant
  520. * for use in the menu to resolve the %tripal_bundle wildcard.
  521. *
  522. * @param $type
  523. * The machine-readable name of a tripal data type to load.
  524. * @return
  525. * A tripal data type array or FALSE if $type does not exist.
  526. */
  527. function TripalBundle_load($bundle_type, $reset = FALSE) {
  528. // Get the type of entity by the ID.
  529. $bundle = db_select('tripal_bundle', 'tdt')
  530. ->fields('tdt')
  531. ->condition('name', $bundle_type)
  532. ->execute()
  533. ->fetchObject();
  534. if ($bundle) {
  535. $entity = entity_load('TripalBundle', array($bundle->id), array(), $reset);
  536. return reset($entity);
  537. }
  538. return FALSE;
  539. }
  540. /**
  541. * Allows the menu system to use a wildcard to fetch the entity.
  542. *
  543. * Make sure that the wildcard you choose in the tripal_entity entity
  544. * definition fits the function name here.
  545. *
  546. * This function is not meant to be used as an API function. It is only meant
  547. * for use in the menu to resolve the %tripal_entity wildcard.
  548. *
  549. * @param $id
  550. * Integer specifying the tripal_entity id.
  551. * @param $reset
  552. * A boolean indicating that the internal cache should be reset.
  553. * @return
  554. * A fully-loaded $tripal_entity object or FALSE if it cannot be loaded.
  555. *
  556. * @see tripal_entity_load_multiple()
  557. */
  558. function TripalEntity_load($id, $reset = FALSE) {
  559. // $entity = entity_load('TripalEntity', array($id), array(), $reset);
  560. $entity = tripal_load_entity('TripalEntity', array($id), $reset);
  561. return reset($entity);
  562. }
  563. /**
  564. * Imports all of the Tripal API into scope.
  565. *
  566. * Typically this function call is not necessary as all of the API is
  567. * automaticaly included by the tripal module. However this function can
  568. * be useful in the .install files during a site upgrade when the tripal
  569. * module is not enabld.
  570. *
  571. * Example usage:
  572. * @code
  573. * module_load_include('module', 'tripal', 'tripal');
  574. * tripal_import_api();
  575. * @endcode
  576. *
  577. */
  578. function tripal_import_api() {
  579. module_load_include('inc', 'tripal', 'api/tripal.d3js.api');
  580. module_load_include('inc', 'tripal', 'api/tripal.fields.api');
  581. module_load_include('inc', 'tripal', 'api/tripal.importer.api');
  582. module_load_include('inc', 'tripal', 'api/tripal.terms.api');
  583. module_load_include('inc', 'tripal', 'api/tripal.entities.api');
  584. module_load_include('inc', 'tripal', 'api/tripal.files.api');
  585. module_load_include('inc', 'tripal', 'api/tripal.jobs.api');
  586. module_load_include('inc', 'tripal', 'api/tripal.notice.api');
  587. module_load_include('inc', 'tripal', 'api/tripal.variables.api');
  588. module_load_include('inc', 'tripal', 'api/tripal.DEPRECATED.api');
  589. }
  590. /**
  591. * Implements hook_form_alter().
  592. */
  593. function tripal_form_alter(&$form, $form_state, $form_id) {
  594. // If this is the field_ui_field_edit_form (i.e. the form that appears
  595. // when editing a field that is attached to an entity). Then we want
  596. // to add term settings for any field attached to a TripalEntity
  597. // content type.
  598. if ($form_id == 'field_ui_field_edit_form' and $form['#instance']['entity_type'] == 'TripalEntity') {
  599. tripal_field_instance_settings_form_alter($form, $form_state);
  600. }
  601. }
  602. function tripal_check_new_fields($bundle_name) {
  603. tripal_refresh_bundle_fields($bundle_name);
  604. drupal_goto("admin/structure/bio_data/manage/$bundle_name/fields");
  605. }
  606. /**
  607. * Implements hook_block_info().
  608. */
  609. function tripal_block_info() {
  610. $blocks = array();
  611. $blocks['notifications_block'] = array(
  612. 'info' => t('Dashboard Notifications'),
  613. 'visibility' => BLOCK_VISIBILITY_LISTED,
  614. 'pages' => 'admin/tripal/dashboard',
  615. 'status' => TRUE,
  616. 'region' => 'content',
  617. 'properties' => array(
  618. 'administrative' => TRUE,
  619. ),
  620. );
  621. $blocks['powered_by_tripal'] = array(
  622. 'info' => t('Powered by Tripal'),
  623. 'cache' => DRUPAL_NO_CACHE,
  624. );
  625. return $blocks;
  626. }
  627. /**
  628. * Implements hook_block_view().
  629. */
  630. function tripal_block_view($delta = ''){
  631. global $base_path;
  632. // The $delta parameter tells us which block is being requested.
  633. switch ($delta) {
  634. case 'powered_by_tripal':
  635. $size = variable_get('powered_by_tripal_size', 'small');
  636. $type = variable_get('powered_by_tripal_type', 'bw');
  637. $image = 'powered_by_tripal_bw_small.png';
  638. if ($size == 'small' and $type == 'col') {
  639. $image = 'powered_by_tripal_small.png';
  640. }
  641. if ($size == 'large' and $type == 'bw') {
  642. $image = 'powered_by_tripal_bw.png';
  643. }
  644. if ($size == 'large' and $type == 'col') {
  645. $image = 'powered_by_tripal.png';
  646. }
  647. $block['title'] = '';
  648. $block['content'] = array(
  649. '#markup' => '<a href="http://tripal.info"><img border="0" src="' . $base_path . drupal_get_path('module', 'tripal') . '/theme/images/' . $image . '"></a>',
  650. );
  651. break;
  652. case 'notifications_block':
  653. // Create your block content here
  654. $block['content'] = '';
  655. // Prepare table header
  656. $header = array(
  657. 'title' => array('data' => t('Title')),
  658. 'details' => array('data' => t('Details')),
  659. 'type' => array('data' => t('Type'), 'field' => 'tan.type'),
  660. 'actions' => array('data' => t('Actions'))
  661. );
  662. $query = db_select('tripal_admin_notfications', 'tan')
  663. ->extend('TableSort');
  664. $results = $query->fields('tan')
  665. ->condition('enabled', 1, '=')
  666. ->orderByHeader($header)
  667. ->execute()->fetchAll();
  668. $rows = array();
  669. foreach($results as $result){
  670. $data['operation'] = ' | ';
  671. $data['operation'] .= l(t('Dismiss Notification'), 'admin/disable/notification/' . $result->note_id);
  672. $actions = unserialize($result->actions);
  673. foreach($actions as $action){
  674. $label = key($actions);
  675. $link = $action;
  676. }
  677. $rows[] = array(
  678. 'Title' => $result->title,
  679. 'Details' => $result->details,
  680. 'Type' => $result->type,
  681. 'Actions' => l(t($label), $link) . $data['operation'],
  682. );
  683. }
  684. if(!empty($rows)) {
  685. //Number of records shown in per page
  686. $per_page = 10;
  687. $current_page = pager_default_initialize(count($rows), $per_page);
  688. $chunks = array_chunk($rows, $per_page, TRUE);
  689. // Output of table with the paging
  690. $table = theme('table',
  691. array(
  692. "header" => $header,
  693. "rows" => $chunks[ $current_page ],
  694. "attributes" => array(),
  695. "sticky" => TRUE,
  696. "caption" => "",
  697. "colgroups" => array(),
  698. "empty" => t("No notifications.")
  699. )
  700. );
  701. $table .= theme('pager', array('quantity', count($rows)));
  702. $fieldset_table = array(
  703. '#title' => t('Notifications'),
  704. '#collapsed' => FALSE,
  705. '#collapsible' => TRUE,
  706. '#attributes' => array('class' => array('collapsible')),
  707. '#children' => $table,
  708. );
  709. //return pager with limited number of records.
  710. $block['content'] = theme('fieldset', array('element' => $fieldset_table));
  711. }
  712. else {
  713. $block['content'] = 'There are no notifications at this time.';
  714. }
  715. break;
  716. }
  717. return $block;
  718. }
  719. /**
  720. * Implements hook_block_save().
  721. */
  722. function tripal_block_save($delta = '', $edit = array()) {
  723. switch ($delta) {
  724. case 'powered_by_tripal':
  725. if (!empty($edit['logo_size'])) {
  726. variable_set('powered_by_tripal_size', $edit['logo_size']);
  727. }
  728. if (!empty($edit['logo_type'])) {
  729. variable_set('powered_by_tripal_type', $edit['logo_type']);
  730. }
  731. }
  732. }
  733. /**
  734. * Implements hook_block_configure().
  735. */
  736. function tripal_block_configure ($delta = '') {
  737. $form = array();
  738. switch ($delta) {
  739. case 'powered_by_tripal':
  740. $form['logo_size'] = array(
  741. '#type' => 'radios',
  742. '#title' => t('Logo Size'),
  743. '#default_value' => variable_get('powered_by_tripal_size', 'small'),
  744. '#options' => array(
  745. 'large' => t('Large'),
  746. 'small' => t('Small')
  747. ),
  748. '#description' => t('Select if you would like a small or large "Powered by Tripal" logo.'),
  749. );
  750. $form['logo_type'] = array(
  751. '#type' => 'radios',
  752. '#title' => t('Logo Type'),
  753. '#default_value' => variable_get('powered_by_tripal_type', 'bw'),
  754. '#options' => array(
  755. 'bw' => t('Gray scale'),
  756. 'col' => t('Colored')
  757. ),
  758. '#description' => t('Select if you would like a black and white or colored "Powered by Tripal" logo.'),
  759. );
  760. }
  761. return $form;
  762. }
  763. /**
  764. * Implements hook_cron().
  765. */
  766. function tripal_cron() {
  767. if (variable_get('tripal_admin_notification_creation_during_cron', TRUE)) {
  768. $modules = module_implements('tripal_cron_notification');
  769. foreach ($modules as $module) {
  770. $function = $module . '_tripal_cron_notification';
  771. $function();
  772. }
  773. watchdog('tripal_cron', 'tripal_cron ran');
  774. }
  775. }
  776. /**
  777. * Implements hook_element_info().
  778. *
  779. * Used for creating new form API elements.
  780. */
  781. function tripal_element_info() {
  782. // Element for uploading large files. This form element
  783. // accepts the following keys when using in a form:
  784. // - #title: The title that will appear above the element.
  785. // - #description: The description that will appear below the element.
  786. // - #usage_type: Required. The type of file. This will be stored in
  787. // the 'type' column of the file_usage table.
  788. // - #usage_id: Required. A unique numeric ID representing an entity, node
  789. // or some other record identifier. This can be any identifier that
  790. // makes sense to the module that implements a form that uses this
  791. // element.
  792. $elements['html5_file'] = array(
  793. '#input' => 'TRUE',
  794. '#process' => array('tripal_html5_file_process'),
  795. '#element_validate' => array('tripal_html5_file_validate'),
  796. '#value_callback' => 'tripal_html5_file_value',
  797. );
  798. return $elements;
  799. }
  800. /**
  801. * The process function for the html5_file form element.
  802. */
  803. function tripal_html5_file_process($element, $form_state, $complete_form) {
  804. $type = $element['#usage_id'] . '-' . $element['#usage_type'];
  805. $name = $element['#name'];
  806. $name = preg_replace('/[^\w]/', '_', $name);
  807. $headers = array(
  808. array('data' => 'File'),
  809. array('data' => 'Size', 'width' => '10%'),
  810. array('data' => 'Upload Progress', 'width' => '20%'),
  811. array('data' => 'Action', 'width' => '10%')
  812. );
  813. $rows = array();
  814. $table_vars = array(
  815. 'header' => $headers,
  816. 'rows' => $rows,
  817. 'attributes' => array(
  818. 'class' => array('tripal-html5-file-upload-table'),
  819. 'id' => 'tripal-html5-file-upload-table-' . $type
  820. ),
  821. 'sticky' => TRUE,
  822. 'colgroups' => array(),
  823. 'empty' => t('There are currently no files.'),
  824. );
  825. $element['html5_file_table_key'] = array(
  826. '#type' => 'hidden',
  827. '#value' => $type,
  828. '#attributes' => array(
  829. 'class' => array('tripal-html5-file-upload-table-key')
  830. )
  831. );
  832. $element['html5_file_table'] = array(
  833. '#type' => 'item',
  834. '#title' => $element['#title'],
  835. '#description' => $element['#description'],
  836. '#markup' => theme('table', $table_vars)
  837. );
  838. $element[$name] = array(
  839. '#type' => 'hidden',
  840. '#attributes' => array('id' => 'tripal-html5-upload-fid-' . $type),
  841. '#default_value' => $element['#value'],
  842. );
  843. $element['html5_file_submit'] = array(
  844. '#type' => 'submit',
  845. '#value' => 'Upload File',
  846. '#name' => 'tripal_html5_file_upload_submit-' . $type,
  847. // We don't want this button to submit as the file upload
  848. // is handled by the JavaScript code.
  849. '#attributes' => array(
  850. 'id' => 'tripal-html5-file-upload-submit-' . $type,
  851. 'onclick' => 'return (false);'
  852. )
  853. );
  854. drupal_add_js(drupal_get_path ('module', 'tripal') . '/theme/js/TripalUploader.js');
  855. drupal_add_js(drupal_get_path ('module', 'tripal') . '/theme/js/TripalUploadFile.js');
  856. drupal_add_js(drupal_get_path ('module', 'tripal') . '/theme/js/tripal.file.js');
  857. return $element;
  858. }
  859. /**
  860. *
  861. */
  862. function tripal_html5_file_validate($element, &$form_state) {
  863. $is_required = $element['#required'];
  864. $fid = $element['#value'];
  865. if ($is_required and !$fid) {
  866. form_error($element, t('A file must be uploaded.'));
  867. }
  868. }
  869. /**
  870. * Implements hook_handle_uplaoded_file().
  871. */
  872. function tripal_handle_uploaded_file($filename, $filepath, $type) {
  873. global $user;
  874. // Split the type into a node ID and form_key
  875. list($nid, $form_key) = explode('-', $type);
  876. // See if this file is already managed then add another entry fin the
  877. // usage table.
  878. $fid = db_select('file_managed', 'fm')
  879. ->fields('fm', array('fid'))
  880. ->condition('uri', $filepath)
  881. ->execute()
  882. ->fetchField();
  883. if ($fid) {
  884. $file = file_load($fid);
  885. file_usage_add($file, 'tripal', $form_key, $nid);
  886. return $fid;
  887. }
  888. // Create a file object.
  889. $file = new stdClass();
  890. $file->uri = $filepath;
  891. $file->filename = $filename;
  892. $file->filemime = file_get_mimetype($filepath);
  893. $file->uid = $user->uid;
  894. $file->status = FILE_STATUS_PERMANENT;
  895. $file = file_save($file);
  896. return $file->fid;
  897. }
  898. /**
  899. * Implements hook_value() for the html5_file form element.
  900. */
  901. function tripal_html5_file_value($element, $input = FALSE, &$form_state) {
  902. if ($input) {
  903. if (is_array($input)) {
  904. $name = $element['#name'];
  905. $name = preg_replace('/[^\w]/', '_', $name);
  906. return $input[$name];
  907. }
  908. else {
  909. return $input;
  910. }
  911. }
  912. }
  913. /**
  914. * Implements hook_field_display_alter().
  915. *
  916. * @param $display
  917. * @param $context
  918. */
  919. function tripal_field_display_TripalEntity_alter(&$display, $context){
  920. $field_name = $context['field']['field_name'];
  921. $bundle = $context['entity']->bundle;
  922. $bundle_info = tripal_load_bundle_entity(array('name' => $bundle));
  923. // Hide fields that are empty, but only if the hide_empty_field variable
  924. // is set to 'hide' for this bundel.
  925. $hide_variable = tripal_get_bundle_variable('hide_empty_field', $bundle_info->id, 'hide');
  926. if($hide_variable == 'hide'){
  927. $item = field_get_items('TripalEntity', $context['entity'], $field_name);
  928. if($item) {
  929. $field = field_info_field($field_name);
  930. if(tripal_field_is_empty($item[0], $field)) {
  931. // Stop the right rail element from rendering.
  932. drupal_add_css('.' . $field_name.' {display: none;}', 'inline');
  933. }
  934. }
  935. }
  936. }
  937. /**
  938. * Implements hook_field_group_table_rows_alter().
  939. *
  940. * This hook is used for hiding empty rows in a Field Group Table field group.
  941. *
  942. * @param $element
  943. * The field group object.
  944. * @param $children
  945. * An array of field names that are cpntained in the field group
  946. */
  947. function tripal_field_group_table_rows_alter(&$element, &$children) {
  948. // Iterate through the children of this table field group.
  949. foreach ($children as $index => $child) {
  950. if (is_array($element[$child])) {
  951. $bundle = $element[$child]['#bundle'];
  952. $bundle_info = tripal_load_bundle_entity(array('name' => $bundle));
  953. // If the hide empty variable is turned on then remove fields from
  954. // the field group.
  955. $hide_variable = tripal_get_bundle_variable('hide_empty_field', $bundle_info->id, 'hide');
  956. if($hide_variable == 'hide'){
  957. $items = $element[$child]['#items'];
  958. // Case #1: there are no items.
  959. if (count($items) == 0) {
  960. unset($children[$index]);
  961. unset($element[$child]);
  962. }
  963. // Case #2: there is one item but the value is empty.
  964. if (count($items) == 1 and array_key_exists('value', $items[0]) and empty($items[0]['value'])) {
  965. unset($children[$index]);
  966. unset($element[$child]);
  967. }
  968. }
  969. }
  970. }
  971. }