array( 'title' => t('View Phylotrees'), 'description' => t('Allow users to view phylotree pages.'), ), 'administer tripal phylotree' => array( 'title' => t('Administer Phylotrees'), 'description' => t('Allow users to administer all phylotrees.'), ), ); } /** * Implements hook_menu(). * * Menu items are automatically added for the new node types created * by this module to the 'Create Content' Navigation menu item. This function * adds more menu items needed for this module. * * @ingroup tripal_phylogeny */ function tripal_phylogeny_menu() { $items = array(); // administration landing page. currently has no content but is // apparently required for the Sync and Help links to work. $items['admin/tripal/legacy/tripal_phylogeny'] = array( 'title' => 'Phylogeny and Taxonomy', 'description' => 'Phylogenetic and taxonomic trees.', 'page callback' => 'tripal_phylogeny_admin_phylotrees_listing', 'access arguments' => array('administer tripal phylotree'), 'type' => MENU_NORMAL_ITEM, ); // help menu $items['admin/tripal/legacy/tripal_phylogeny/help'] = array( 'title' => 'Help', 'description' => 'Basic Description of Tripal Phylotree Module Functionality', 'page callback' => 'theme', 'page arguments' => array('tripal_phylogeny_help'), 'access arguments' => array('administer tripal phylotree'), 'type' => MENU_LOCAL_TASK, 'weight' => 10 ); // configuration menu item $items['admin/tripal/legacy/tripal_phylogeny/configuration'] = array( 'title' => 'Settings', 'description' => 'Configure the Tripal Phylotree module', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_phylogeny_admin'), 'access arguments' => array('administer tripal phylotree'), 'type' => MENU_LOCAL_TASK, 'weight' => 1 ); $items['admin/tripal/legacy/tripal_phylogeny/plots'] = array( 'title' => 'Plot Defaults', 'description' => 'Set defaults for the trees', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_phylogeny_default_plots_form'), 'access arguments' => array('administer tripal phylotree'), 'type' => MENU_LOCAL_TASK, 'weight' => 2 ); // sync menu item (will be rendered as a tab by tripal) $items['admin/tripal/legacy/tripal_phylogeny/sync'] = array( 'title' => ' Sync', 'description' => 'Create pages on this site for phylotrees stored in Chado', 'page callback' => 'drupal_get_form', 'page arguments' => array('chado_node_sync_form', 'tripal_phylogeny', 'chado_phylotree'), 'access arguments' => array('administer tripal phylotree'), 'type' => MENU_LOCAL_TASK, 'weight' => 3 ); // Enable admin view $items['admin/tripal/legacy/tripal_phylogeny/views/phylotree/enable'] = array( 'title' => 'Enable Phylotree Administrative View', 'page callback' => 'tripal_enable_view', 'page arguments' => array('tripal_phylogeny_admin_phylotree', 'admin/tripal/legacy/tripal_phylogeny'), 'access arguments' => array('administer tripal phylotree'), 'type' => MENU_CALLBACK, ); $items['taxonomy_view'] = array( 'title' => 'Taxonomy', 'description' => 'Taxonomic view of the species available on this site.', 'page callback' => 'tripal_phylogeny_taxonomy_view', 'access arguments' => array('access taxonomy content'), 'file' => '/includes/tripal_phylogeny.taxonomy.inc', 'type' => MENU_NORMAL_ITEM, ); // create a route for viewing json of all phylonodes having this phylotree_id $items['ajax/chado_phylotree/%/json'] = array( 'page callback' => 'tripal_phylogeny_ajax_get_tree_json', 'page arguments' => array(2), // allow all anonymous http clients 'access callback' => TRUE ); return $items; } /** * Implements hook_search_biological_data_views(). * * Adds the described views to the "Search Data" Page created by Tripal Views */ function tripal_phylogeny_search_biological_data_views() { return array( 'tripal_phylogeny_user_phylotree' => array( 'machine_name' => 'tripal_phylogeny_user_phylotree', 'human_name' => 'Phylogenetic Trees', 'description' => 'Gene trees, species trees, etc.', 'link' => 'chado/phylotree' ), ); } /** * Implements hook_views_api(). * * Essentially this hook tells drupal that there is views support for * for this module which then includes tripal_db.views.inc where all the * views integration code is * * @ingroup tripal_phylogeny */ function tripal_phylogeny_views_api() { return array( 'api' => 3.0, ); } /** * Implements hook_theme(). * * We need to let drupal know about our theme functions and their arguments. * We create theme functions to allow users of the module to customize the * look and feel of the output generated in this module * * @ingroup tripal_phylogeny */ function tripal_phylogeny_theme($existing, $type, $theme, $path) { $core_path = drupal_get_path('module', 'tripal_core'); $items = array( // built-in theme 'node__chado_phylotree' => array( 'template' => 'node--chado-generic', 'render element' => 'node', 'base hook' => 'node', 'path' => "$core_path/theme/templates", ), // base template for this page (default tab) includes the phylogram 'tripal_phylogeny_base' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_phylogeny_base', 'path' => "$path/theme/templates", ), // Template for the phylogram. 'tripal_phylogeny_phylogram' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_phylogeny_phylogram', 'path' => "$path/theme/templates", ), // Template for the taxonomic tree. 'tripal_phylogeny_taxonomic_tree' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_phylogeny_taxonomic_tree', 'path' => "$path/theme/templates", ), // partial for organisms block 'tripal_phylogeny_organisms' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_phylogeny_organisms', 'path' => "$path/theme/templates", ), // partial for cross references block 'tripal_phylogeny_references' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_phylogeny_references', 'path' => "$path/theme/templates", ), // partial for cross references block 'tripal_phylogeny_analysis' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_phylogeny_analysis', 'path' => "$path/theme/templates", ), // partial for teaser view 'tripal_phylogeny_teaser' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_phylogeny_teaser', 'path' => "$path/theme/templates", ), // FORM THEMES // Theme function for the project table in admin projects form 'tripal_phylogeny_admin_org_color_tables' => array( 'render element' => 'element', ) ); return $items; } /** * Implements hook_help(). * Adds a help page to the module list * * @ingroup tripal_phylogeny */ function tripal_phylogeny_help ($path, $arg) { if ($path == 'admin/help#tripal_phylogeny') { return theme('tripal_phylogeny_help', array()); } } /** * Get json representation of a phylotree id. * * This function is meant to be called via AJAX. * * @param int $phylotree_id * the ID of the phylotree node. * * @return string json * * @ingroup tripal_phylogeny */ function tripal_phylogeny_ajax_get_tree_json($phylotree_id) { $phylotree = chado_generate_var('phylotree', array('phylotree_id' => $phylotree_id)); // This SQL gets all of the phylonodes for a given tree as well as the // features and organisms with which it is assocaited. Each phylonode // can be associated with an orgnaism in one of two ways: 1) via a // feature linked by the phylonode.feature_id field or 2) via a // a record in the phylonde_organsim table. Therefore both types of // organism records are returned in the query below, but those // retrieved via a FK link on features are prefixed with 'fo_'. $sql = " SELECT n.phylonode_id, n.parent_phylonode_id, n.label AS name, n.distance AS length, f.feature_id, f.name AS feature_name, cvt.name AS cvterm_name, o.organism_id, o.common_name, o.abbreviation, o.genus, o.species, fo.organism_id AS fo_organism_id, fo.common_name AS fo_common_name, fo.abbreviation AS fo_abbreviation, fo.genus as fo_genus, fo.species AS fo_species, cf.nid AS feature_node_id, fco.nid AS fo_organism_node_id, co.nid AS organism_node_id FROM {phylonode} n LEFT OUTER JOIN {cvterm} cvt ON n.type_id = cvt.cvterm_id LEFT OUTER JOIN {feature} f ON n.feature_id = f.feature_id LEFT OUTER JOIN [chado_feature] cf ON cf.feature_id = f.feature_id LEFT OUTER JOIN {organism} fo ON f.organism_id = fo.organism_id LEFT OUTER JOIN [chado_organism] fco ON fco.organism_id = fo.organism_id LEFT OUTER JOIN {phylonode_organism} po ON po.phylonode_id = n.phylonode_id LEFT OUTER JOIN {organism} o ON PO.organism_id = o.organism_id LEFT OUTER JOIN [chado_organism] co ON co.organism_id = o.organism_id WHERE n.phylotree_id = :phylotree_id "; $args = array(':phylotree_id' => $phylotree_id); $result = chado_query($sql, $args); // Fetch all the phylonodes into an assoc array indexed by phylonode_id. // Convert from resultset record to array, fixing datatypes. chado_query // returns numeric as string and fun stuff like that. $phylonodes = array(); $root_phylonode_ref = null; foreach ($result as $r) { $phylonode_id = (int) $r->phylonode_id; // expect all nodes to have these properties $node = array( 'phylonode_id' => $phylonode_id, 'parent_phylonode_id' => (int) $r->parent_phylonode_id, 'length' => (double) $r->length, 'cvterm_name' => $r->cvterm_name ); // If the nodes are taxonomic then set an equal distance if ($phylotree->type_id->name == 'taxonomy') { $node['length'] = 0.001; } // Other props may exist only for leaf nodes if ($r->name) { $node['name'] = $r->name; } // If this node is associated with a feature then add in the details if ($r->feature_id) { $node['feature_id'] = (int) $r->feature_id; $node['feature_name'] = $r->feature_name; $node['feature_node_id'] = (int) $r->feature_node_id; } // Add in the organism fields when they are available via the // phylonode_organism table. if ($r->organism_id) { $node['organism_id'] = (int) $r->organism_id; $node['common_name'] = $r->common_name; $node['abbreviation'] = $r->abbreviation; $node['genus'] = $r->genus; $node['species'] = $r->species; $node['organism_node_id'] = (int) $r->organism_node_id; // If the node does not have a name but is linked to an organism // then set the name to be that of the genus and species. if (!$r->name) { $node['name'] = $r->genus . ' ' . $r->species; } } // Add in the organism fields when they are available via the // the phylonode.feature_id FK relationship. if ($r->fo_organism_id) { $node['fo_organism_id'] = (int) $r->fo_organism_id; $node['fo_common_name'] = $r->fo_common_name; $node['fo_abbreviation'] = $r->fo_abbreviation; $node['fo_genus'] = $r->fo_genus; $node['fo_species'] = $r->fo_species; $node['fo_organism_node_id'] = (int) $r->fo_organism_node_id; } // Add this node to the list, organized by ID. $phylonodes[$phylonode_id] = $node; } // Populate the children[] arrays for each node. foreach ($phylonodes as $key => &$node) { if ($node['parent_phylonode_id'] !== 0) { $parent_ref = &$phylonodes[ $node['parent_phylonode_id']]; // Append node refernce to children. $parent_ref['children'][] = &$node; } else { $root_phylonode_ref = &$node; } } // dump datastructure as json to browser. drupal sets the mime-type correctly. drupal_json_output($root_phylonode_ref); }