tripal_core.module 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. <?php
  2. /**
  3. * @file
  4. * The Tripal Core module
  5. */
  6. /**
  7. * @defgroup tripal_core Tripal Core Module
  8. * @ingroup tripal_modules
  9. * @{
  10. * Functionality useful for all other Tripal modules including the Tripal jobs, files,
  11. * materialized views and custom table functions.
  12. * @}
  13. */
  14. // APPLICATION PROGRAMMER INTERFACE -------------
  15. // Chado API
  16. require_once 'api/tripal_core.chado_general.api.inc';
  17. require_once 'api/tripal_core.chado_query.api.inc';
  18. require_once 'api/tripal_core.chado_variables.api.inc';
  19. require_once 'api/tripal_core.chado_schema.api.inc';
  20. require_once 'api/tripal_core.chado_nodes.api.inc';
  21. require_once 'api/tripal_core.chado_nodes.title_and_path.inc';
  22. require_once 'api/tripal_core.chado_nodes.properties.api.inc';
  23. require_once 'api/tripal_core.chado_nodes.dbxrefs.api.inc';
  24. require_once 'api/tripal_core.chado_nodes.relationships.api.inc';
  25. // Table API
  26. require_once 'api/tripal_core.custom_tables.api.inc';
  27. require_once 'api/tripal_core.mviews.api.inc';
  28. // Miscellaneous API
  29. require_once 'api/tripal_core.files.api.inc';
  30. require_once 'api/tripal_core.jobs.api.inc';
  31. require_once 'api/tripal_core.tripal.api.inc';
  32. require_once 'api/tripal_core.DEPRECATED.inc';
  33. // INCLUDES
  34. require_once 'includes/tripal_core.jobs.inc';
  35. require_once 'includes/tripal_core.mviews.inc';
  36. require_once 'includes/tripal_core.custom_tables.inc';
  37. require_once 'includes/tripal_core.chado_install.inc';
  38. require_once 'includes/tripal_core.form_elements.inc';
  39. tripal_core_set_globals();
  40. /**
  41. * This function is used to set the global Chado variables
  42. *
  43. * @ingroup tripal_core
  44. */
  45. function tripal_core_set_globals() {
  46. // these global variables are meant to be accessed by all Tripal
  47. // modules to find the chado version installed and if Chado is local.
  48. // these variables are stored as globals rather than using the drupal_set_variable
  49. // functions because the Drupal functions make databaes queries and for long
  50. // running loaders we don't want those queries repeatedly.
  51. $GLOBALS["chado_is_installed"] = chado_is_installed();
  52. if ($GLOBALS["chado_is_installed"]) {
  53. $GLOBALS["chado_is_local"] = chado_is_local();
  54. $GLOBALS["chado_version"] = chado_get_version();
  55. $GLOBALS["exact_chado_version"] = chado_get_version(TRUE);
  56. }
  57. }
  58. /**
  59. * Implements hook_init().
  60. * Used to set the search_path, create default content and set default variables.
  61. *
  62. * @ingroup tripal_core
  63. */
  64. function tripal_core_init() {
  65. global $base_url;
  66. // create the 'tripal' controlled volcabulary in chado but only if it doesn't already exist, and
  67. // only if the chado database is present.
  68. if ($GLOBALS["chado_is_installed"]) {
  69. // if the Tripal cv is missing then add
  70. $results = chado_query("SELECT * FROM {cv} WHERE name = 'tripal'");
  71. $tripal_cv = $results->fetchObject();
  72. if (!$tripal_cv) {
  73. $results = chado_query(
  74. "INSERT INTO {cv} (name,definition) " .
  75. "VALUES ('tripal', 'Terms used by Tripal for modules to manage data such as that stored in property tables like featureprop, analysisprop, etc')"
  76. );
  77. }
  78. // if the Tripal db is missing then add it
  79. $results = chado_query("SELECT * FROM {db} WHERE name = 'tripal'");
  80. $tripal_db = $results->fetchObject();
  81. if (!$tripal_db) {
  82. $results = chado_query(
  83. "INSERT INTO {db} (name,description) " .
  84. "VALUES ('tripal', 'Used as a database placeholder for tripal defined objects such as tripal cvterms')"
  85. );
  86. }
  87. }
  88. // add some variables for all javasript to use for building URLs
  89. $theme_dir = drupal_get_path('theme', 'tripal');
  90. $clean_urls = variable_get('clean_url', 0);
  91. drupal_add_js(
  92. " var baseurl = '$base_url';
  93. var themedir = '$theme_dir';
  94. var isClean = $clean_urls;",
  95. 'inline', 'header');
  96. // make sure the date time settings are the way Tripal will insert them
  97. // otherwise PostgreSQL version that may have a different datestyle setting
  98. // will fail when inserting or updating a date column in a table.
  99. db_query("SET DATESTYLE TO :style", array(':style' => 'MDY'));
  100. // If we want AHAH elements on the node forms (e.g. chado_pub form) then we need to include
  101. // the node.pages file. Otherwise this error message is given:
  102. //
  103. // warning: call_user_func_array() expects parameter 1 to be a valid callback,
  104. // function 'node_form' not found or invalid function name
  105. // in /var/www/includes/form.inc on line 382.
  106. module_load_include('inc', 'node', 'node.pages');
  107. }
  108. /**
  109. * Implements hook_menu().
  110. * Defines all menu items needed by Tripal Core
  111. *
  112. * @ingroup tripal_core
  113. */
  114. function tripal_core_menu() {
  115. $items = array();
  116. // Triapl setting groups
  117. $items['admin/tripal'] = array(
  118. 'title' => 'Tripal',
  119. 'description' => t("Manage the behavior or Tripal and its various modules."),
  120. 'weight' => -8,
  121. 'page callback' => 'system_admin_menu_block_page',
  122. 'access arguments' => array('administer tripal'),
  123. 'file' => 'system.admin.inc',
  124. 'file path' => drupal_get_path('module', 'system'),
  125. );
  126. $items['admin/tripal/schema'] = array(
  127. 'title' => 'Chado Schema',
  128. 'description' => t("Tools to extend the chado schema through custom tables & materialized views."),
  129. 'weight' => -2,
  130. 'access arguments' => array('administer tripal'),
  131. );
  132. $items['admin/tripal/chado'] = array(
  133. 'title' => 'Chado Modules',
  134. 'description' => t('Configuration for specific chado data types such as Vocabularies, Features, etc.'),
  135. 'access arguments' => array('administer tripal'),
  136. 'type' => MENU_NORMAL_ITEM,
  137. 'weight' => -6
  138. );
  139. $items['admin/tripal/loaders'] = array(
  140. 'title' => 'Chado Data Loaders',
  141. 'description' => t('Tools facilitating loading data into the chado database. Includes a generic tab-delimited loader (Bulk Loader).'),
  142. 'access arguments' => array('administer tripal'),
  143. 'type' => MENU_NORMAL_ITEM,
  144. 'weight' => -4
  145. );
  146. $items['admin/tripal/extension'] = array(
  147. 'title' => 'Extension Modules',
  148. 'description' => t('Configuration for Tripal extension modules.'),
  149. 'access arguments' => array('administer tripal'),
  150. 'type' => MENU_NORMAL_ITEM,
  151. 'weight' => 0
  152. );
  153. // Tripal Setup
  154. $items['admin/tripal/setup'] = array(
  155. 'title' => 'Setup Tripal',
  156. 'description' => t('Tools for setup of Tripal'),
  157. 'access arguments' => array('administer tripal'),
  158. 'weight' => -8
  159. );
  160. $items['admin/tripal/setup/chado_install'] = array(
  161. 'title' => 'Install Chado Schema',
  162. 'description' => t('Installs the Chado database tables, views, etc., inside the current Drupal database'),
  163. 'page callback' => 'drupal_get_form',
  164. 'page arguments' => array('tripal_core_chado_load_form'),
  165. 'access arguments' => array('install chado'),
  166. 'type' => MENU_NORMAL_ITEM,
  167. 'weight' => -10
  168. );
  169. $items['admin/tripal/setup/customize'] = array(
  170. 'title' => 'Customize Tripal',
  171. 'description' => t('Information on how to customize tripal'),
  172. 'page callback' => 'theme',
  173. 'page arguments' => array('tripal_core_customize'),
  174. 'access arguments' => array('administer tripal'),
  175. 'weight' => 10
  176. );
  177. // Jobs Management
  178. $items['admin/tripal/tripal_jobs'] = array(
  179. 'title' => 'Jobs',
  180. 'description' => t('Jobs managed by Tripal'),
  181. 'page callback' => 'tripal_jobs_admin_view',
  182. 'access arguments' => array('administer tripal'),
  183. 'type' => MENU_NORMAL_ITEM,
  184. 'weight' => -10
  185. );
  186. $items['admin/tripal/tripal_jobs/help'] = array(
  187. 'title' => 'Help',
  188. 'description' => t('Help for the tripal job management system'),
  189. 'page callback' => 'theme',
  190. 'page arguments' => array('tripal_core_job_help'),
  191. 'access arguments' => array('administer tripal'),
  192. 'type' => MENU_LOCAL_TASK,
  193. 'weight' => 10
  194. );
  195. $items['admin/tripal/tripal_jobs/cancel/%'] = array(
  196. 'title' => 'Jobs',
  197. 'description' => t('Cancel a pending job'),
  198. 'page callback' => 'tripal_cancel_job',
  199. 'page arguments' => array(4),
  200. 'access arguments' => array('administer tripal'),
  201. 'type' => MENU_CALLBACK,
  202. );
  203. $items['admin/tripal/tripal_jobs/rerun/%'] = array(
  204. 'title' => 'Jobs',
  205. 'description' => t('Re-run an existing job.'),
  206. 'page callback' => 'tripal_rerun_job',
  207. 'page arguments' => array(4),
  208. 'access arguments' => array('administer tripal'),
  209. 'type' => MENU_CALLBACK,
  210. );
  211. $items['admin/tripal/tripal_jobs/view/%'] = array(
  212. 'title' => 'Jobs Details',
  213. 'description' => t('View job details.'),
  214. 'page callback' => 'tripal_jobs_view',
  215. 'page arguments' => array(4),
  216. 'access arguments' => array('administer tripal'),
  217. 'type' => MENU_CALLBACK,
  218. );
  219. $items['admin/tripal/tripal_jobs/views/jobs/enable'] = array(
  220. 'title' => 'Enable Jobs Administrative View',
  221. 'page callback' => 'tripal_enable_view',
  222. 'page arguments' => array('tripal_core_admin_jobs', 'admin/tripal/tripal_jobs'),
  223. 'access arguments' => array('administer tripal'),
  224. 'type' => MENU_CALLBACK,
  225. );
  226. // Materialized Views
  227. $items['admin/tripal/schema/mviews'] = array(
  228. 'title' => 'Materialized Views',
  229. 'description' => t('Materialized views are used to improve speed of large or complex queries.'),
  230. 'page callback' => 'tripal_mview_admin_view',
  231. 'access arguments' => array('administer tripal'),
  232. 'type' => MENU_NORMAL_ITEM,
  233. 'weight' => -10
  234. );
  235. $items['admin/tripal/schema/mviews/help'] = array(
  236. 'title' => 'Help',
  237. 'description' => t('Help for the materialized views management system'),
  238. 'page callback' => 'theme',
  239. 'page arguments' => array('tripal_core_mviews_help'),
  240. 'access arguments' => array('administer tripal'),
  241. 'type' => MENU_LOCAL_TASK,
  242. 'weight' => 10
  243. );
  244. $items['admin/tripal/schema/mviews/report/%'] = array(
  245. 'title' => 'Materialized View',
  246. 'description' => t('Materialized views are used to improve speed of large or complex queries. These are database views as compared to Drupal views.'),
  247. 'page callback' => 'tripal_mview_report',
  248. 'page arguments' => array(5),
  249. 'access arguments' => array('administer tripal'),
  250. 'type' => MENU_CALLBACK,
  251. );
  252. $items['admin/tripal/schema/mviews/new'] = array(
  253. 'title' => 'Create Materialized View',
  254. 'description' => t('Create a new materialized view.'),
  255. 'page callback' => 'drupal_get_form',
  256. 'page arguments' => array('tripal_mviews_form'),
  257. 'access arguments' => array('administer tripal'),
  258. 'type' => MENU_CALLBACK,
  259. );
  260. $items['admin/tripal/schema/mviews/edit/%'] = array(
  261. 'title' => 'Edit Materialized View',
  262. 'page callback' => 'drupal_get_form',
  263. 'page arguments' => array('tripal_mviews_form', 5),
  264. 'access arguments' => array('administer tripal'),
  265. 'type' => MENU_CALLBACK,
  266. );
  267. $items['admin/tripal/schema/mviews/update/%'] = array(
  268. 'title' => 'Create Materialized View',
  269. 'description' => t('Materialized views are used to improve speed of large or complex queries.'),
  270. 'page callback' => 'tripal_mviews_add_populate_job',
  271. 'page arguments' => array(5),
  272. 'access arguments' => array('administer tripal'),
  273. 'type' => MENU_CALLBACK,
  274. );
  275. $items['admin/tripal/schema/mviews/delete/%'] = array(
  276. 'title' => 'Create Materialized View',
  277. 'description' => t('Materialized views are used to improve speed of large or complex queries.'),
  278. 'page callback' => 'drupal_get_form',
  279. 'page arguments' => array('tripal_mviews_delete_form', 5),
  280. 'access arguments' => array('administer tripal'),
  281. 'type' => MENU_CALLBACK,
  282. );
  283. // Custom Tables
  284. $items['admin/tripal/schema/custom_tables'] = array(
  285. 'title' => 'Custom Tables',
  286. 'description' => t('Creation of custom tables that are added to Chado database.'),
  287. 'page callback' => 'tripal_custom_table_admin_view',
  288. 'access arguments' => array('administer tripal'),
  289. 'type' => MENU_NORMAL_ITEM,
  290. 'weight' => -10
  291. );
  292. $items['admin/tripal/schema/custom_tables/help'] = array(
  293. 'title' => 'Help',
  294. 'description' => t('Help for the tripal job management system'),
  295. 'page callback' => 'theme',
  296. 'page arguments' => array('tripal_core_job_help'),
  297. 'access arguments' => array('administer tripal'),
  298. 'type' => MENU_LOCAL_TASK,
  299. 'weight' => 10
  300. );
  301. $items['admin/tripal/schema/custom_tables/view/%'] = array(
  302. 'title' => 'Custom Tables',
  303. 'description' => t('Custom tables are added to Chado.'),
  304. 'page callback' => 'tripal_custom_table_view',
  305. 'page arguments' => array(5),
  306. 'access arguments' => array('administer tripal'),
  307. 'type' => MENU_CALLBACK,
  308. );
  309. $items['admin/tripal/schema/custom_tables/new'] = array(
  310. 'title' => 'Create Custom Table',
  311. 'description' => t('An interface for creating your own custom tables.'),
  312. 'page callback' => 'tripal_custom_table_new_page',
  313. 'access arguments' => array('administer tripal'),
  314. 'type' => MENU_CALLBACK,
  315. );
  316. $items['admin/tripal/schema/custom_tables/edit/%'] = array(
  317. 'title' => 'Edit Custom Table',
  318. 'page callback' => 'drupal_get_form',
  319. 'page arguments' => array('tripal_custom_tables_form', 5),
  320. 'access arguments' => array('administer tripal'),
  321. 'type' => MENU_CALLBACK,
  322. );
  323. $items['admin/tripal/schema/custom_tables/delete/%'] = array(
  324. 'title' => 'Create Custom Table',
  325. 'description' => t('Custom tables are added to Chado.'),
  326. 'page callback' => 'drupal_get_form',
  327. 'page arguments' => array('tripal_custom_tables_delete_form', 5),
  328. 'access arguments' => array('administer tripal'),
  329. 'type' => MENU_CALLBACK,
  330. );
  331. $items['admin/tripal/schema/custom_tables/views/tables/enable'] = array(
  332. 'title' => 'Enable Custom Tables Administrative View',
  333. 'page callback' => 'tripal_enable_view',
  334. 'page arguments' => array('tripal_core_admin_custom_table', 'admin/tripal/schema/custom_tables'),
  335. 'access arguments' => array('administer tripal'),
  336. 'type' => MENU_CALLBACK,
  337. );
  338. // Relationshi API autocomplete callback
  339. $items['tripal_ajax/relationship_nodeform/%/%/name_to_id'] = array(
  340. 'page callback' => 'chado_add_node_form_relationships_name_to_id_callback',
  341. 'page arguments' => array(2,3),
  342. 'access arguments' => array('access content'),
  343. 'type' => MENU_CALLBACK
  344. );
  345. return $items;
  346. }
  347. /**
  348. * Implements hook_permission().
  349. *
  350. * Set the permission types that the chado module uses. Essentially we
  351. * want permissionis that protect creation, editing and deleting of chado
  352. * data objects
  353. *
  354. * @ingroup tripal_core
  355. */
  356. function tripal_core_permission() {
  357. return array(
  358. 'install chado' => array(
  359. 'title' => t('Install Chado'),
  360. 'description' => t('Allow the user to install or upgrade a Chado database in the existing Drupal database.')
  361. ),
  362. 'administer tripal' => array(
  363. 'title' => t('Administer Tripal'),
  364. 'description' => t('Allow the user to access administrative pages of Tripal.')
  365. ),
  366. 'view dev helps' => array(
  367. 'title' => t('View Developer Hints'),
  368. 'description' => t('Tripal will provide blue shaded boxes that provide
  369. instructions for how to customize or setup specific pages on a
  370. site. This permission should be enabled for developers. But can
  371. be disabled once developers are accustomed to these hints.'),
  372. 'restrict access' => TRUE,
  373. ),
  374. 'view ids' => array(
  375. 'title' => t('View Internal IDs'),
  376. 'description' => t('On content pages Tripal will typically provide
  377. a table of information pulled from the Chado database but the
  378. primary key IDs for that data is typically not shown. The
  379. default Tripal templates can show the primary key ID inside of a
  380. blue shaded table row if this permission is enabled. This can
  381. be useful for site developers who might want these IDs when working
  382. with the underlying database.'),
  383. 'restrict access' => TRUE,
  384. )
  385. );
  386. }
  387. /**
  388. * Implements hook_theme().
  389. * Registers template files/functions used by this module.
  390. *
  391. * @ingroup tripal_core
  392. */
  393. function tripal_core_theme($existing, $type, $theme, $path) {
  394. return array(
  395. 'tripal_core_customize' => array(
  396. 'arguments' => array('job_id' => NULL),
  397. 'template' => 'tripal_core_customize',
  398. 'path' => "$path/theme/templates"
  399. ),
  400. 'theme_file_upload_combo' => array(
  401. 'render element' => 'element',
  402. ),
  403. 'theme_sequence_combo' => array(
  404. 'render element' => 'element',
  405. ),
  406. 'tripal_core_jobs_help' => array(
  407. 'template' => 'tripal_core_jobs_help',
  408. 'variables' => array(NULL),
  409. 'path' => "$path/theme/templates"
  410. ),
  411. 'tripal_core_customtables_help' => array(
  412. 'template' => 'tripal_core_customtables_help',
  413. 'variables' => array(NULL),
  414. 'path' => "$path/theme/templates"
  415. ),
  416. // Chado Node API Themes
  417. // --------------------------------
  418. // Properties Node Form
  419. 'chado_node_properties_form_table' => array(
  420. 'function' => 'theme_chado_add_node_form_properties',
  421. 'render element' => 'element',
  422. ),
  423. // Additional Dbxrefs Nore Form
  424. 'chado_node_additional_dbxrefs_form_table' => array(
  425. 'function' => 'theme_chado_add_node_form_dbxrefs_table',
  426. 'render element' => 'element',
  427. ),
  428. // Relationships Nore Form
  429. 'chado_node_relationships_form_table' => array(
  430. 'function' => 'theme_chado_add_node_form_relationships_table',
  431. 'render element' => 'element',
  432. ),
  433. // Admin messages theme
  434. // --------------------------------
  435. 'tripal_admin_message' => array(
  436. 'function' => 'theme_tripal_admin_message',
  437. 'variables' => array('message' => NULL),
  438. )
  439. );
  440. }
  441. /**
  442. * Implements hook_job_describe_args().
  443. * Describes the arguements for the tripal_populate_mview job to allow for greater
  444. * readability in the jobs details pages.
  445. *
  446. * @param $callback
  447. * The callback of the current tripal job (this is the function that will be executed
  448. * when tripal_launch_jobs.php is run.
  449. * @param $args
  450. * An array of arguments passed in when the job was registered.
  451. *
  452. * @return
  453. * A more readable $args array
  454. *
  455. * @ingroup tripal_core
  456. */
  457. function tripal_core_job_describe_args($callback, $args) {
  458. $new_args = array();
  459. if ($callback == 'tripal_populate_mview') {
  460. // get this mview details
  461. $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = :mview_id ";
  462. $results = db_query($sql, array(':mview_id' => $args[0]));
  463. $mview = $results->fetchObject();
  464. $new_args['View Name'] = $mview->name;
  465. }
  466. elseif ($callback == 'tripal_core_install_chado') {
  467. $new_args['Action'] = $args[0];
  468. }
  469. return $new_args;
  470. }
  471. /**
  472. * this is just a wrapper for backwards compatibility with a naming mistake.
  473. * it can go away in the future as it only is useful for jobs created by v0.3b
  474. *
  475. * @todo remove this function
  476. */
  477. function tripal_core_load_gff3($gff_file, $organism_id, $analysis_id, $add_only = 0,
  478. $update = 0, $refresh = 0, $remove = 0, $job = NULL) {
  479. tripal_feature_load_gff3($gff_file, $organism_id, $analysis_id, $add_only,
  480. $update, $refresh, $remove, $job);
  481. }
  482. /**
  483. * Implements hook_coder_ignore().
  484. * Defines the path to the file (tripal_core.coder_ignores.txt) where ignore rules for coder are stored
  485. */
  486. function tripal_core_coder_ignore() {
  487. return array(
  488. 'path' => drupal_get_path('module', 'tripal_core'),
  489. 'line prefix' => drupal_get_path('module', 'tripal_core'),
  490. );
  491. }
  492. /**
  493. * Implements hook_views_api()
  494. * Purpose: Essentially this hook tells drupal that there is views support for
  495. * for this module which then includes tripal_db.views.inc where all the
  496. * views integration code is
  497. *
  498. * @ingroup tripal_organism
  499. */
  500. function tripal_core_views_api() {
  501. return array(
  502. 'api' => 3.0,
  503. );
  504. }
  505. /**
  506. * After the node is built, we want to add instructions to each
  507. * content section letting the administrator know which template
  508. * they can customize
  509. *
  510. * @param unknown $build
  511. */
  512. function tripal_core_node_view_alter(&$build) {
  513. global $theme;
  514. // if this is not a full node view, we do not want to alter
  515. if ($build['#view_mode'] != 'full' OR !array_key_exists('#tripal_generic_node_template', $build)) {
  516. return;
  517. }
  518. $node_type = $build["#node"]->type;
  519. $nid = $build["#node"]->nid;
  520. $cache = cache_get("theme_registry:$theme", 'cache');
  521. $node = $build['#node'];
  522. $toc = array();
  523. $toc_html = '';
  524. // if we are looking at a Tripal node template then we want to
  525. // make some changes to each block of content so that we can associate
  526. // a table of contents and add administrator and curator messages
  527. if ($build['#tripal_generic_node_template'] == TRUE) {
  528. // iterate through all the elements of the $build array and for those
  529. // that are wanting to provide content for this node
  530. $markup = array();
  531. foreach ($build as $key => $value) {
  532. // skip the body element as the Tripal node types do not use it
  533. if ($key == 'body') {
  534. continue;
  535. }
  536. // examine elements without a '#' prefix as these should be adding
  537. // contents to the page. Skip the table of contents and links as those
  538. // will be placed elsewhere
  539. if (preg_match('/^#/', $key) or $key == 'tripal_toc' or $key == 'links') {
  540. continue;
  541. }
  542. //kook to see if the title, position and visibilty of this element has
  543. // custom settings. First check if the node is customized then check
  544. // if the node type.
  545. $override_title = '';
  546. $override_weight = '';
  547. $override_hide = 0;
  548. $toc_item_overrides = db_select('tripal_toc', 'tc')
  549. ->fields('tc', array('toc_item_id', 'title', 'weight', 'hide'))
  550. ->condition('node_type', $node_type)
  551. ->condition('key', $key)
  552. ->condition('nid', $nid)
  553. ->execute()
  554. ->fetchObject();
  555. if ($toc_item_overrides) {
  556. $override_title = $toc_item_overrides->title;
  557. $override_weight = $toc_item_overrides->weight;
  558. $override_hide = $toc_item_overrides->hide;
  559. }
  560. else {
  561. // get the override title, weight for the general case
  562. $toc_item_overrides = db_select('tripal_toc', 'tc')
  563. ->fields('tc', array('toc_item_id', 'title', 'weight', 'hide'))
  564. ->condition('node_type', $node_type)
  565. ->condition('key', $key)
  566. ->isNull('nid')
  567. ->execute()
  568. ->fetchObject();
  569. if ($toc_item_overrides) {
  570. $override_title = $toc_item_overrides->title;
  571. $override_weight = $toc_item_overrides->weight;
  572. $override_hide = $toc_item_overrides->hide;
  573. }
  574. }
  575. // if the element should be hiddent then unset this key the build
  576. // array continue to the next one
  577. if ($override_hide == 1) {
  578. unset($build[$key]);
  579. continue;
  580. }
  581. // for backwards compatibility we will handle the content type fields
  582. // named 'field_resource_blocks', 'field_resource_titles', and 'field_resource_links'
  583. // these fields can be added on the Drupal content types page and were
  584. // specifically recoginzed by Tripal v1.1.
  585. if ($key == "field_resource_links") {
  586. // links should just appear on the sidebar as is and not open up a panel
  587. foreach (element_children($build[$key]) as $index) {
  588. $element = $build[$key][$index];
  589. $weight = 0;
  590. $parts = explode("|", $element['#markup']);
  591. if (count($parts) == 2) {
  592. $toc[$weight][$parts[0]] = "<div class=\"tripal_toc_list_item\">" . l($parts[0], $parts[1], array('attributes' => array('target' => '_blank'))) . "</div>";
  593. }
  594. else {
  595. $toc[$weight][$parts[0]] = "<div class=\"tripal_toc_list_item\">" . $element['#markup'] . "</div>";
  596. }
  597. // remove this link from the build array as we've moved it to appear in the TOC
  598. unset($build[$key]);
  599. }
  600. continue;
  601. }
  602. if ($key == "field_resource_titles") {
  603. // ignore these, we will use them in the field_resource_blocks if
  604. // statement below
  605. continue;
  606. }
  607. if ($key == "field_resource_blocks") {
  608. foreach (element_children($build[$key]) as $index) {
  609. // get the block details and the title
  610. $weight = 0;
  611. $markup = $build[$key][$index]["#markup"];
  612. $toc_item_id = "resource-$index";
  613. $toc_item_title = $build["field_resource_titles"][$index]["#markup"];
  614. $updated_markup = "
  615. <div id=\"$toc_item_id-tripal-data-block\" class=\"tripal-data-block\">
  616. <div class=\"$toc_item_id-tripal-data-block-title tripal-data-block-title\">$toc_item_title</div>
  617. $markup
  618. </div>
  619. </div>
  620. ";
  621. $build[$toc_item_id]['#markup'] = $updated_markup;
  622. $build[$toc_item_id]['#weight'] = $weight;
  623. $build[$toc_item_id]['#toc_handled'] = TRUE;
  624. // add the entry to the TOC
  625. $toc_item_link = "<div class=\"tripal_toc_list_item\"><a id=\"$toc_item_id\" class=\"tripal_toc_list_item_link\" href=\"?block=$toc_item_id\">$toc_item_title</a></div>";
  626. $toc[$weight][$toc_item_title] = $toc_item_link;
  627. }
  628. // remove the key from the build array. We have have replaced it
  629. unset($build[$key]);
  630. unset($build["field_resource_titles"]);
  631. continue;
  632. }
  633. // skip any keys we may have already handled. This is the case for
  634. // the field_resource_blocks where we removed the old CCK fields
  635. // and added new ones. We don't want these new ones to be processed
  636. // again by the code below.
  637. if (array_key_exists('#toc_handled', $build[$key]) and $build[$key]['#toc_handled'] == TRUE) {
  638. continue;
  639. }
  640. // for all other fields we will handle in the following way
  641. //-----------------------
  642. // INITIALIZE THE CONTENT VARIABLES
  643. //-----------------------
  644. $toc_item_title = $key;
  645. $toc_item_id = $key;
  646. $toc_item_link = '';
  647. // get the title for the table of contents. Tripal templates should
  648. // have a '#tripal_toc_title' element in the build array
  649. if (array_key_exists('#tripal_toc_title', $build[$key])) {
  650. $toc_item_title = $build[$key]['#tripal_toc_title'];
  651. }
  652. // other elements in the $build array may just have a '#title' element,
  653. if (array_key_exists('#title', $build[$key])) {
  654. $toc_item_title = $build[$key]['#title'];
  655. }
  656. $toc_item_title = ucwords($toc_item_title);
  657. // now override the title if a value is set in the tripal_toc table
  658. $toc_item_title = $override_title ? $override_title : $toc_item_title;
  659. if (array_key_exists('#tripal_toc_id', $build[$key])) {
  660. $toc_item_id = $build[$key]['#tripal_toc_id'];
  661. }
  662. $toc_item_link = "<div class=\"tripal_toc_list_item\"><a id=\"$toc_item_id\" class=\"tripal_toc_list_item_link\" href=\"?block=$toc_item_id\">$toc_item_title</a></div>";
  663. //-----------------------
  664. // GET THE MARKUP FOR EACH ELEMENT
  665. //-----------------------
  666. $markup = '';
  667. // find the markup. Some fields will have a '#markup' and others, such
  668. // as CCK elements may have a set of '#markup' elements organized by
  669. // numerical keys.
  670. if (array_key_exists('#markup', $build[$key]) and trim($build[$key]['#markup'])) {
  671. $markup = $build[$key]['#markup'];
  672. }
  673. // For backwards copmatibility we should support the '#value' element as well.
  674. elseif (array_key_exists('#value', $build[$key]) and trim($build[$key]['#value'])) {
  675. $markup = $build[$key]['#markup'];
  676. }
  677. // if we have no '#markup' field then this element has not yet
  678. // been rendered. Let's render it and substitute that for markup
  679. if (!$markup) {
  680. $markup = trim(render($build[$key]));
  681. $build[$key] = array(
  682. '#markup' => $markup,
  683. );
  684. }
  685. // if we still don't have markup then skip this one
  686. if (!$markup) {
  687. continue;
  688. }
  689. //-----------------------
  690. // FIND THE TEMPLATE PATH
  691. //-----------------------
  692. // get the template path so we can put it in an admin message box
  693. $path = '';
  694. if (!array_key_exists('#tripal_template_show', $build[$key]) or
  695. $build[$key]['#tripal_template_show'] == TRUE) {
  696. if ($cache and array_key_exists($key, $cache->data) and array_key_exists('path', $cache->data[$key])) {
  697. $path = $cache->data[$key]['path'] . '/' . $key . '.tpl.php';
  698. $path = tripal_set_message("Administrators, you can
  699. customize the way the content above is presented. Tripal provides a template
  700. file for each block of content. To customize, copy the template file to your
  701. site's default theme, edit then " .
  702. l('clear the Drupal cache', 'admin/config/development/performance', array('attributes' => array('target' => '_blank'))) . ".
  703. Currently, the content above is provided by this template: <br><br>$path",
  704. TRIPAL_INFO,
  705. array('return_html' => 1)
  706. );
  707. }
  708. }
  709. //-----------------------
  710. // SET THE WEIGHTS FOR THE TOC ELEMENTS
  711. //-----------------------
  712. // set the weight of the TOC item and add it to our $toc array
  713. // for building of the TOC below
  714. $weight = 0;
  715. if (array_key_exists('#weight', $build[$key])) {
  716. $weight = $build[$key]['#weight'];
  717. }
  718. // override the weight if it's set in the tripal_toc table
  719. $weight = $override_weight ? $override_weight : $weight;
  720. $toc[$weight][$toc_item_title] = $toc_item_link;
  721. //-----------------------
  722. // CREATE THE DATA BLOCK
  723. //-----------------------
  724. // add a surrounding <div> box around the content
  725. $updated_markup = "
  726. <div id=\"$toc_item_id-tripal-data-block\" class=\"tripal-data-block\">
  727. <div class=\"$toc_item_id-tripal-data-block-title tripal-data-block-title\">$toc_item_title</div>
  728. $markup
  729. $path
  730. </div>
  731. </div>
  732. ";
  733. $build[$key]['#markup'] = $updated_markup;
  734. $build[$key]['#weight'] = $weight;
  735. } // end foreach ($build as $key => $value) {
  736. } // end if ($build['#tripal_generic_node_template'] == TRUE) {
  737. //-----------------------
  738. // BUILD THE TABLE OF CONTENTS LINKS
  739. //-----------------------
  740. // first sort the links numerically by their weight
  741. ksort($toc, SORT_NUMERIC);
  742. $toc_html = '';
  743. foreach ($toc as $weight => $links) {
  744. // for links in the same weight, sort them alphabetically
  745. ksort($links);
  746. foreach ($links as $toc_item_title => $toc_item_link) {
  747. $toc_html .= $toc_item_link;
  748. }
  749. }
  750. $build['tripal_toc']['#markup'] = "<div id=\"$node->type-tripal-toc-block\" class=\"tripal-toc-block\">$toc_html</div>";
  751. }
  752. /**
  753. *
  754. * @ingroup tripal_core
  755. */
  756. function tripal_core_node_view($node, $view_mode, $langcode) {
  757. // if this node type is a chado-based node (i.e. Tripal node)
  758. // the we want to add a table of contents to it's content list
  759. // this table of contents will be an empty
  760. if (preg_match('/^chado_/', $node->type)) {
  761. // Show feature browser and counts
  762. if ($view_mode == 'full') {
  763. if (!isset($node->content['#tripal_generic_node_template'])) {
  764. $node->content['#tripal_generic_node_template'] = TRUE;
  765. }
  766. }
  767. }
  768. }