'Stocks', 'description' => 'Basic Description of Tripal Stock Module Functionality', 'page callback' => 'theme', 'page arguments' => array('tripal_stock_help'), 'access arguments' => array('administer tripal stocks'), 'type' => MENU_NORMAL_ITEM ); $items['admin/tripal/tripal_stock/configuration'] = array( 'title' => 'Configuration', 'description' => 'Settings for Chado Stocks', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_stock_help'), 'access arguments' => array('administer tripal stocks'), 'type' => MENU_NORMAL_ITEM ); $items['admin/tripal/tripal_stock/sync'] = array( 'title' => ' Sync Stocks', 'description' => 'Sync stocks from Chado with Drupal', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_stock_sync_form'), 'access arguments' => array('administer tripal stocks'), 'type' => MENU_NORMAL_ITEM, ); // Adding Secondary Properties----------------- $items['node/%cs_node/properties'] = array( 'title' => 'Add Properties & Synonyms', 'description' => 'Settings for Chado Stocks', 'page callback' => 'tripal_stock_add_ALL_property_page', 'page arguments' => array(1), 'access arguments' => array('create chado_stock content'), 'type' => MENU_CALLBACK ); $items['node/%cs_node/db_references'] = array( 'title' => 'Add Database References', 'description' => 'Settings for Chado Stocks', 'page callback' => 'tripal_stock_add_ALL_dbreferences_page', 'page arguments' => array(1), 'access arguments' => array('create chado_stock content'), 'type' => MENU_CALLBACK ); $items['node/%cs_node/relationships'] = array( 'title' => 'Add Relationships', 'description' => 'Settings for Chado Stocks', 'page callback' => 'tripal_stock_add_ALL_relationships_page', 'page arguments' => array(1), 'access arguments' => array('create chado_stock content'), 'type' => MENU_CALLBACK ); //Edit/Deleting Secondary Properties------------- $items['node/%cs_node/edit_properties'] = array( 'title' => 'Edit Properties', 'description' => 'Settings for Chado Stocks', 'page callback' => 'tripal_stock_edit_ALL_properties_page', 'page arguments' => array(1), 'access arguments' => array('edit chado_stock content'), 'type' => MENU_LOCAL_TASK, 'weight' => 8, ); $items['node/%cs_node/edit_relationships'] = array( 'title' => 'Edit Relationships', 'description' => 'Settings for Chado Stocks', 'page callback' => 'tripal_stock_edit_ALL_relationships_page', 'page arguments' => array(1), 'access arguments' => array('edit chado_stock content'), 'type' => MENU_LOCAL_TASK, 'weight' => 9, ); $items['node/%cs_node/edit_db_references'] = array( 'title' => 'Edit DB References', 'description' => 'Settings for Chado Stocks', 'page callback' => 'tripal_stock_edit_ALL_dbreferences_page', 'page arguments' => array(1), 'access arguments' => array('edit chado_stock content'), 'type' => MENU_LOCAL_TASK, 'weight' => 10, ); // the menu link for addressing any stock (by name, uniquename, synonym) $items['stock/%'] = array( 'page callback' => 'tripal_stock_match_stocks_page', 'page arguments' => array(1), 'access arguments' => array('access chado_stock content'), 'type' => MENU_LOCAL_TASK, ); return $items; } /** * Implements Menu wildcard_load hook * * Purpose: Allows the node ID of a chado stock to be dynamically * pulled from the path. The node is loaded from this node ID * and supplied to the page as an arguement. This is an example * of dynamic argument replacement using wildcards in the path. * * @param $nid * The node ID passed in from the path * * @return * The node object with the passed in nid * * @ingroup tripal_stock */ function cs_node_load($nid) { if (is_numeric($nid)) { $node = node_load($nid); if ($node->type == 'chado_stock') { return $node; } } return FALSE; } /** * Implementation of hook_perm(). * * Purpose: Set the permission types that the chado stock module uses * * @return * Listing of the possible permission catagories * * @ingroup tripal_stock */ function tripal_stock_permissions() { return array( 'access chado_stock content' => array( 'title' => t('View Stocks'), 'description' => t('Allow users to view stock pages.'), ), 'create chado_stock content' => array( 'title' => t('Create Stocks'), 'description' => t('Allow users to create new stock pages.'), ), 'delete chado_stock content' => array( 'title' => t('Delete Stocks'), 'description' => t('Allow users to delete stock pages.'), ), 'edit chado_stock content' => array( 'title' => t('Edit Stocks'), 'description' => t('Allow users to edit stock pages.'), ), 'adminster tripal stock' => array( 'title' => t('Administer Stocks'), 'description' => t('Allow users to administer all stocks.'), ), ); } /** * Implement hook_access(). * * This hook allows node modules to limit access to the node types they define. * * @param $node * The node on which the operation is to be performed, or, if it does not yet exist, the * type of node to be created * * @param $op * The operation to be performed * * @param $account * A user object representing the user for whom the operation is to be performed * * @return * If the permission for the specified operation is not set then return FALSE. If the * permission is set then return NULL as this allows other modules to disable * access. The only exception is when the $op == 'create'. We will always * return TRUE if the permission is set. * * @ingroup tripal_stock */ function chado_stock_node_access($node, $op, $account) { if ($op == 'create') { if (!user_access('create chado_stock content', $account)) { return FALSE; } return TRUE; } if ($op == 'update') { if (!user_access('edit chado_stock content', $account)) { return FALSE; } } if ($op == 'delete') { if (!user_access('delete chado_stock content', $account)) { return FALSE; } } if ($op == 'view') { if (!user_access('access chado_stock content', $account)) { return FALSE; } } return NULL; } /** * Implements hook_views_api() * * Purpose: Essentially this hook tells drupal that there is views support for * for this module which then includes tripal_stock.views.inc where all the * views integration code is * * @return * An array with fields important for views integration * * @ingroup tripal_stock */ function tripal_stock_views_api() { return array( 'api' => 2.0, ); } /** * Implements hook_theme(): Register themeing functions for this module * * @return * An array of themeing functions to register * * @ingroup tripal_stock */ function tripal_stock_theme() { $theme_path = drupal_get_path('module', 'tripal_stock') . '/theme'; $items = array( // property edit forms function templates 'tripal_stock_edit_ALL_properties_form' => array( 'arguments' => array('form'), 'function' => 'theme_tripal_stock_edit_ALL_properties_form', ), 'tripal_stock_edit_ALL_db_references_form' => array( 'arguments' => array('form'), 'function' => 'theme_tripal_stock_edit_ALL_db_references_form', ), 'tripal_stock_edit_ALL_relationships_form' => array( 'arguments' => array('form'), 'function' => 'theme_tripal_stock_edit_ALL_relationships_form', ), // tripal_stock templates 'tripal_stock_base' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_base', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_properties' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_properties', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_references' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_references', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_relationships' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_relationships', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_synonyms' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_synonyms', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_collections' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_collections', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_collections' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_collections', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_phenotypes' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_phenotypes', 'path' => "$theme_path/tripal_stock", ), 'tripal_stock_locations' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_stock_locations', 'path' => "$theme_path/tripal_stock", ), // tripal_organism templates 'tripal_organism_stocks' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_organism_stocks', 'path' => "$theme_path/tripal_organism", ), // help template 'tripal_stock_help' => array( 'template' => 'tripal_stock_help', 'arguments' => array(NULL), 'path' => $theme_path, ), ); return $items; } /** * Implements hook_help() * Purpose: Adds a help page to the module list */ function tripal_stock_help ($path, $arg) { if ($path == 'admin/help#tripal_stock') { return theme('tripal_stock_help', array()); } } /** * Implements hook_node_info(): registers a stock node type * * @return * An array describing various details of the node * * @ingroup tripal_stock */ function tripal_stock_node_info() { return array( 'chado_stock' => array( 'name' => t('Stock'), 'base' => 'chado_stock', 'description' => t('A Chado Stock is a collection of material that can be sampled and have experiments performed on it.'), 'has_title' => TRUE, 'has_body' => FALSE, ), ); } /** * Implements hook_load(): Prepares the chado_stock node * * @param $node * The basic node containing all variables common to all nodes * * @return * A stock node containing all the variables from the basic node and all stock specific variables * * @ingroup tripal_stock */ function chado_stock_load($node) { // get the stock details from chado $stock_id = chado_get_id_for_node('stock', $node->nid); // build the variable with all the stock details $values = array('stock_id' => $stock_id); $stock = tripal_core_generate_chado_var('stock', $values); // by default, the titles are saved using the unique constraint. We will // keep it the same, but remove the duplicate name if the unique name and name // are identical $title_type = variable_get('chado_stock_title', 'unique_constraint'); if($title_type == 'unique_constraint') { if (strcmp($stock->name, $stock->uniquename)==0) { $node->title = $stock->name . " (" . $stock->type_id->name . ") " . $stock->organism_id->genus . " " . $stock->organism_id->species ; } // in previous version of Tripal, the stock title was simply the unique name. // so, we recreate the title just to be sure all of our stock pages are consistent else { $node->title = $stock->name . ", " . $stock->uniquename . " (" . $stock->type_id->name . ") " . $stock->organism_id->genus . " " . $stock->organism_id->species ; } } // set the title to be the stock name or uniquename as configured if($title_type == 'stock_name') { $node->title = $stock->name; } if($title_type == 'stock_unique_name') { $node->title = $stock->uniquename; } // add this to the node $additions = new stdClass(); $additions->stock = $stock; return $additions; } /** * Implements hook_form(): Creates the main Add/Edit/Delete Form for chado stocks * * Parts to be added by this form * name, * uniquename, * description, * type => select from cvterm with key cvterm_id, * organism => select from available with key organism_id * main_db_reference => accession, version, description, db_name(select from dropdown) * * @param $node * An empty node object on insert OR the current stock node object on update * @param $form_state * The current state of the form * * @return * A description of the form to be rendered by drupal_get_form() * * @ingroup tripal_stock */ function chado_stock_form($node, $form_state) { // Expand all fields needed $fields_needed = array('stock.uniquename', 'stock.name', 'stock.stock_id', 'stock.type_id', 'stock.organism_id', 'stock.description', 'stock.dbxref_id', 'dbxref.accession', 'dbxref.description', 'dbxref.db_id', 'db.db_id'); foreach ($fields_needed as $field_name) { // Check to see if it's excluded and expand it if so if ($node->expandable_fields) { if (in_array($field_name, $node->expandable_fields)) { $node = tripal_core_expand_chado_vars($node, 'field', $field_name); } } } // This defines the path for the next step in a simulated multipart form // NOTE: The %node gets replaced with the nid in insert $form['next_step_path'] = array( '#type' => 'hidden', '#value' => 'node/%node/properties' ); // If you don't want a multipart form set this to false // Will then do default redirect (to new node) on submit $form['simulate_multipart'] = array( '#type' => 'textfield', '#attributes' => array('style' => "display:none"), '#default_value' => TRUE ); if (!isset($node->stock->uniquename)) { $form['progress'] = array( '#type' => 'item', '#value' => tripal_stock_add_chado_properties_progress('main') ); } $form['names'] = array( '#type' => 'fieldset', '#title' => t('Stock Name') ); $form['names']['sname'] = array( '#type' => 'textfield', '#title' => t('Name'), '#default_value' => $node->stock->name, '#required' => TRUE ); $form['names']['uniquename'] = array( '#type' => 'textfield', '#title' => t('Unique Name'), '#default_value' => $node->stock->uniquename, '#required' => TRUE ); $form['names']['stock_id'] = array( '#type' => 'hidden', '#value' => $node->stock->stock_id ); $form['details'] = array( '#type' => 'fieldset', '#title' => t('Stock Details') ); $type_options = tripal_cv_get_cvterm_options( variable_get('chado_stock_types_cv', 'NULL') ); $type_options[0] = 'Select a Type'; if ($node->nid == '') { $type_default = 0; } else { $type_default = $node->stock->type_id->cvterm_id; } $form['details']['type_id'] = array( '#type' => 'select', '#title' => t('Type of Stock'), '#options' => $type_options, '#default_value' => $type_default, '#required' => TRUE, ); // get the list of organisms $sql = "SELECT * FROM {Organism} ORDER BY genus, species"; $org_rset = chado_query($sql); $organisms = array(); $organisms[''] = ''; while ($organism = $org_rset->fetchObject()) { $organisms[$organism->organism_id] = "$organism->genus $organism->species ($organism->common_name)"; } $form['details']['organism_id'] = array( '#type' => 'select', '#title' => t('Source Organism for stock'), '#default_value' => $node->stock->organism_id->organism_id, '#options' => $organisms, '#required' => TRUE ); $form['details']['stock_description'] = array( '#type' => 'textarea', '#title' => t('Notes'), '#default_value' => $node->stock->description, '#description' => t('Briefly enter any notes on the above stock. This should not include phenotypes or genotypes.'), ); $form['database_reference'] = array( '#type' => 'fieldset', '#title' => t('Stock Database Reference') ); $form['database_reference']['accession'] = array( '#type' => 'textfield', '#title' => t('Accession'), '#default_value' => $node->stock->dbxref_id->accession ); $form['database_reference']['db_description'] = array( '#type' => 'textarea', '#title' => t('Description of Database Reference'), '#default_value' => $node->stock->dbxref_id->description, '#description' => t('Optionally enter a description about the database accession.') ); $db_options = tripal_db_get_db_options(); $db_options[0] = 'Select a Database'; if ($node->nid == '') { $db_default = 0; } else { $db_default = $node->stock->dbxref_id->db_id->db_id; } $form['database_reference']['database'] = array( '#type' => 'select', '#title' => t('Database'), '#options' => $db_options, '#default_value' => $db_default ); return $form; } /** * Implements hook_validate(): Validate the input from the chado_stock node form * * @param $node * The current node including fields with the form element names and submitted values * @param $form * A description of the form to be rendered by drupal_get_form() * * @ingroup tripal_stock */ function chado_stock_validate($node, &$form) { $int_in_chado_sql = "SELECT count(*) as count FROM {:table} WHERE :column = :value"; $string_in_chado_sql = "SELECT count(*) as count FROM {:table} WHERE :column = :value"; // if this is an update, we want to make sure that a different stock for // the organism doesn't already have this uniquename. We don't want to give // two sequences the same uniquename if ($node->stock_id) { $sql = " SELECT * FROM {stock} S INNER JOIN {cvterm} CVT ON S.type_id = CVT.cvterm_id WHERE uniquename = :uname AND organism_id = :organism_id AND CVT.name = :cvtname AND NOT stock_id = :stock_id "; $result = chado_query($sql, array(':uname' => $node->uniquename, ':organism_id' => $node->organism_id, ':cvtname' => $node->stock_type, ':stock_id' => $node->stock_id))->fetchObject(); if ($result) { form_set_error('uniquename', t("Stock update cannot proceed. The stock name '$node->uniquename' is not unique for this organism. Please provide a unique name for this stock.")); } } // if this is an insert then we just need to make sure this name doesn't // already exist for this organism if it does then we need to throw an error else { $sql = " SELECT * FROM {Stock} S INNER JOIN {cvterm} CVT ON S.type_id = CVT.cvterm_id WHERE uniquename = :uname'AND organism_id = :organism_id AND CVT.name = :cvtname"; $result = chado_query($sql, array(':uname' => $node->uniquename, ':organism_id' => $node->organism_id, ':cvtname' => $node->stock_type))->fetchObject(); if ($result) { form_set_error('uniquename', t("Stock insert cannot proceed. The stock name '$node->uniquename' already exists for this organism. Please provide a unique name for this stock.")); } } // Check Type of Stock is valid cvterm_id in chado ( $form['values']['details']['type_id'] ) if ( $node->type_id == 0) { form_set_error('type_id', 'Please select a type of stock.'); } else { $num_rows = chado_query($int_in_chado_sql, array(':table' => 'cvterm', ':column' => 'cvterm_id', ':value' => $node->type_id))->fetchObject(); if ( $num_rows->count != 1) { form_set_error('type_id', "The type you selected is not valid. Please choose another one. (CODE:$num_rows)"); } } // Check Source Organism is valid organism_id in chado ( $form['values']['details']['organism_id'] ) if ( $node->organism_id == 0) { form_set_error('organism_id', 'Please select a source organism for this stock'); } else { $num_rows = chado_query($int_in_chado_sql, array(':table' => 'organism', ':column' => 'organism_id', ':value' => $node->organism_id))->fetchObject(); if ( $num_rows->count != 1 ) { form_set_error('organism_id', "The organism you selected is not valid. Please choose another one. (CODE:$num_rows)"); } } // Check if Accession also database if ($node->accession != '') { if ($node->database == 0) { // there is an accession but no database selected form_set_error('database', 'You need to enter both a database and an accession for that database in order to add a database reference.'); } } else { if ($node->database > 0) { // there is a database selected but no accession form_set_error('accession', 'You need to enter both a database and an accession for that database in order to add a database reference.'); } } // Check database is valid db_id in chado ( $form['values']['database_reference']['database'] ) if ( $node->database > 0) { $num_rows = chado_query($int_in_chado_sql, array(':table' => 'db', ':column' => 'db_id', ':value' => $node->database))->fetchObject(); if ($num_rows->count != 1) { form_set_error('database', 'The database you selected is not valid. Please choose another one.'); } } } /** * Implements hook_insert(): Inserts data from chado_stock_form() into drupal and chado * * @param $node * The current node including fields with the form element names and submitted values * * @return * TRUE if the node was successfully inserted into drupal/chado; FALSE otherwise * * @ingroup tripal_stock */ function chado_stock_insert($node) { // If the chado stock exists (e.g. this is only a syncing operation) // then don't create but simply link to node if ($node->chado_stock_exists) { if (!empty($node->stock_id)) { $sql = "INSERT INTO {chado_stock} (nid, vid, stock_id) VALUES (:nid, :vid, :stock_id)"; db_query($sql, array(':nid' => $node->nid, ':vid' => $node->vid, ':stock_id' => $node->stock_id)); } return $node; } // before we can add the stock, we must add the dbxref if one has been // provided by the user. $dbxref_status = 0; if (!empty($node->accession) ) { if (!empty($node->database) ) { $values = array( 'db_id' => $node->database, 'accession' => $node->accession, ); if (!tripal_core_chado_select('dbxref', array(dbxref_id), $values)) { $values['description'] = $node->db_description; $values['version'] = '1'; $dbxref_status = tripal_core_chado_insert('dbxref', $values); if (!$dbxref_status) { drupal_set_message(t('Unable to add database reference to this stock.'), 'warning'); watchdog('tripal_stock', 'Insert Stock: Unable to create dbxref where values:%values', array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING ); } } else { $dbxref_status = 1; } } } // create stock including the dbxref $stock = ''; if ($dbxref_status) { $values = array( 'dbxref_id' => array( 'db_id' => $node->database, 'accession' => $node->accession ), 'organism_id' => $node->organism_id, 'name' => $node->sname, 'uniquename' => $node->uniquename, 'description' => $node->stock_description, 'type_id' => $node->type_id ); $stock = tripal_core_chado_insert('stock', $values); } // create a stock without a dbxref else { $values = array( 'organism_id' => $node->organism_id, 'name' => $node->sname, 'uniquename' => $node->uniquename, 'description' => $node->stock_description, 'type_id' => $node->type_id ); $stock = tripal_core_chado_insert('stock', $values); } // if the stock creation was succesful then add the URL and the entry in the // chado_stock table if (is_array($stock)) { // convert the stock into an object $stock = (object) $stock; // add the entry to the chado_stock table $sql = "INSERT INTO {chado_stock} (nid, vid, stock_id) VALUES :nid, :vid, :stock_id)"; db_query($sql, array(':nid' => $node->nid, ':vid' => $node->vid, ':stock_id' => $stock->stock_id)); // Move on to next stage of Stock Creation based on next_stage_path field if ($node->simulate_multipart) { $next_stage_path = preg_replace('/%node/', $node->nid, $node->next_step_path); $_REQUEST['destination'] = $next_stage_path; } } else { drupal_set_message(t('Error during stock creation.'), 'error'); watchdog('tripal_stock', 'Insert Stock: Unable to create stock where values:%values', array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING ); return FALSE; } } /** * Implements hook_update(): Handles Editing/Updating of main stock info * * NOTE: Currently just writes over all old data * * @param $node * The current node including fields with the form element names and submitted values * * @return * TRUE if the node was successfully updated in drupal/chado; FALSE otherwise * * @ingroup tripal_stock */ function chado_stock_update($node) { if ($node->revision) { // there is no way to handle revisions in Chado but leave // this here just to make not we've addressed it. } //update dbxref if ($node->database) { if ($node->accession) { $dbxref_mode = ''; $stock = tripal_core_chado_select( 'stock', array('dbxref_id', 'type_id'), array('stock_id' => $node->stock_id) ); if ($stock[0]->dbxref_id) { $values = array( 'db_id' => $node->database, 'accession' => $node->accession, 'description' => $node->db_description ); $dbxref_status = tripal_core_chado_update( 'dbxref', array('dbxref_id' => $stock[0]->dbxref_id), $values ); $dbxref_mode = 'Update'; } else { if ($stock[0]->type_id) { //create the dbxref //used the type_id as a control to check we have a stock but not a dbxref $values = array( 'db_id' => $node->database, 'accession' => $node->accession, 'description' => $node->db_description, 'version' => '1', ); $dbxref_status = tripal_core_chado_insert( 'dbxref', $values ); $dbxref_mode = 'Create'; } else { drupal_set_message(t('Unable to find stock to Update'), 'error'); watchdog( 'tripal_stock', 'Stock Update: Unable to find stock to update using values: %values', array('%values', print_r($values, TRUE)), WATCHDOG_ERROR ); return FALSE; } } } } if (!$dbxref_status) { watchdog( 'tripal_stock', 'Stock Update: Unable to %mode main stock dbxref with values: %values', array('%values' => print_r($values, TRUE), '%mode' => $dbxref_mode), WATCHDOG_WARNING ); } //can't change stock id which is all thats stored in drupal thus only update chado $update_values = array( 'organism_id' => $node->organism_id, 'name' => $node->sname, 'uniquename' => $node->uniquename, 'description' => $node->stock_description, 'type_id' => $node->type_id, ); if ($dbxref_status) { $update_values['dbxref_id'] = array( 'db_id' => $node->database, 'accession' => $node->accession ); } $status = tripal_core_chado_update('stock', array('stock_id' => $node->stock_id), $update_values); if (!$status) { drupal_set_message(t('Unable to update stock'), 'error'); watchdog( 'tripal_stock', 'Stock Update: Unable to update stock using match values: %mvalues and update values: %uvalues', array('%mvalues' => print_r(array('stock_id' => $node->stock_id), TRUE), '%uvalues' => print_r($update_values, TRUE)), WATCHDOG_ERROR ); } else { // set the URL for this stock page $values = array('stock_id' => $node->stock_id); $stock = tripal_core_chado_select('stock', array('*'), $values); } } /** * Implements hook_delete(): Handles deleting of chado_stocks * * NOTE: Currently deletes data -no undo or record-keeping functionality * * @param $node * The current node including fields with the form element names and submitted values * * @return * TRUE if the node was successfully deleted from drupal/chado; FALSE otherwise * * @ingroup tripal_stock */ function chado_stock_delete($node) { // Set stock in chado: is_obsolete = TRUE chado_query("DELETE FROM {stock} WHERE stock_id = :stock_id", array(':stock_id' => $node->stock->stock_id)); //remove drupal node and all revisions db_query("DELETE FROM {chado_stock} WHERE nid = :nid", array(':nid' => $node->nid)); } /** * @ingroup tripal_stock */ function tripal_stock_block_info() { $blocks['base']['info'] = t('Tripal Stock Details'); $blocks['base']['cache'] = BLOCK_NO_CACHE; $blocks['properties']['info'] = t('Tripal Stock Properties'); $blocks['properties']['cache'] = BLOCK_NO_CACHE; $blocks['references']['info'] = t('Tripal Stock References'); $blocks['references']['cache'] = BLOCK_NO_CACHE; $blocks['relationships_as_object']['info'] = t('Tripal Stock Relationships'); $blocks['relationships_as_object']['cache'] = BLOCK_NO_CACHE; $blocks['synonyms']['info'] = t('Tripal Stock Synonyms'); $blocks['synonyms']['cache'] = BLOCK_NO_CACHE; $blocks['collections']['info'] = t('Tripal Stock Collections'); $blocks['collections']['cache'] = BLOCK_NO_CACHE; $blocks['phenotypes']['info'] = t('Tripal Stock Phenotypes'); $blocks['phenotypes']['cache'] = BLOCK_NO_CACHE; $blocks['genotypes']['info'] = t('Tripal Stock Genotypes'); $blocks['genotypes']['cache'] = BLOCK_NO_CACHE; $blocks['locations']['info'] = t('Tripal Stock Locations'); $blocks['locations']['cache'] = BLOCK_NO_CACHE; $blocks['orgstocks']['info'] = t('Tripal Organism Stocks'); $blocks['orgstocks']['cache'] = BLOCK_NO_CACHE; return $blocks; } /** * * @ingroup tripal_stock */ function tripal_stock_block_view($delta = '') { if (user_access('access chado_stock content') and arg(0) == 'node' and is_numeric(arg(1))) { $nid = arg(1); $node = node_load($nid); $block = array(); switch ($delta) { case 'base': $block['subject'] = t('Stock Details'); $block['content'] = theme('tripal_stock_base', $node); break; case 'properties': $block['subject'] = t('Properties'); $block['content'] = theme('tripal_stock_properties', $node); break; case 'references': $block['subject'] = t('References'); $block['content'] = theme('tripal_stock_references', $node); break; case 'relationships': $block['subject'] = t('Relationships'); $block['content'] = theme('tripal_stock_relationships', $node); break; case 'synonyms': $block['subject'] = t('Synonyms'); $block['content'] = theme('tripal_stock_synonyms', $node); break; case 'collections': $block['subject'] = t('Stock Collections'); $block['content'] = theme('tripal_stock_collections', $node); break; case 'phenotypes': $block['subject'] = t('Stock Phenotypes'); $block['content'] = theme('tripal_stock_phenotypes', $node); break; case 'genotypes': $block['subject'] = t('Stock Genotypes'); $block['content'] = theme('tripal_stock_genotypes', $node); break; case 'locations': $block['subject'] = t('Stock Locations'); $block['content'] = theme('tripal_stock_locations', $node); break; case 'orgstocks': $block['subject'] = t('Organism Stocks'); $block['content'] = theme('tripal_organism_stocks', $node); break; } return $block; } } /** * * * @ingroup tripal_stock */ function tripal_stock_preprocess_tripal_stock_relationships(&$variables) { // we want to provide a new variable that contains the matched stocks. $stock = $variables['node']->stock; // normally we would use tripal_core_expand_chado_vars to expand our // organism object and add in the relationships, however whan a large // number of relationships are present this significantly slows the // query, therefore we will manually perform the query $sql = " SELECT S.name, S.uniquename, S.stock_id, CS.nid, CVT.name as rel_type, CVTs.name as obj_type, SR.value FROM {stock_relationship} SR INNER JOIN {stock} S on SR.object_id = S.stock_id INNER JOIN {cvterm} CVT on SR.type_id = CVT.cvterm_id INNER JOIN {cvterm} CVTs on S.type_id = CVTs.cvterm_id LEFT JOIN public.chado_stock CS on S.stock_id = CS.stock_id WHERE SR.subject_id = :stock_id "; $as_subject = chado_query($sql, array(':stock_id' => $stock->stock_id)); $sql = " SELECT S.name, S.uniquename, S.stock_id, CS.nid, CVT.name as rel_type, CVTs.name as sub_type, SR.value FROM {stock_relationship} SR INNER JOIN {stock} S on SR.subject_id = S.stock_id INNER JOIN {cvterm} CVT on SR.type_id = CVT.cvterm_id INNER JOIN {cvterm} CVTs on S.type_id = CVTs.cvterm_id LEFT JOIN public.chado_stock CS on S.stock_id = CS.stock_id WHERE SR.object_id = :stock_id "; $as_object = chado_query($sql, array(':stock_id' => $stock->stock_id)); // combine both object and subject relationshisp into a single array $relationships = array(); $relationships['object'] = array(); $relationships['subject'] = array(); // iterate through the object relationships while ($relationship = $as_object->fetchObject()) { // get the relationship and child types $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type)); $sub_type = t(preg_replace('/_/', " ", $relationship->sub_type)); if (!array_key_exists($rel_type, $relationships['object'])) { $relationships['object'][$rel_type] = array(); } if (!array_key_exists($sub_type, $relationships['object'][$rel_type])) { $relationships['object'][$rel_type][$sub_type] = array(); } $relationships['object'][$rel_type][$sub_type][] = $relationship; } // now add in the subject relationships while ($relationship = $as_subject->fetchObject()) { // get the relationship and child types $rel_type = t(preg_replace('/_/', " ", $relationship->rel_type)); $obj_type = t(preg_replace('/_/', " ", $relationship->obj_type)); if (!array_key_exists($rel_type, $relationships['subject'])) { $relationships['subject'][$rel_type] = array(); } if (!array_key_exists($obj_type, $relationships['subject'][$rel_type])) { $relationships['subject'][$rel_type][$obj_type] = array(); } $relationships['subject'][$rel_type][$obj_type][] = $relationship; } $stock->all_relationships = $relationships; } /** * @ingroup tripal_stock */ function tripal_stock_node_presave($node) { switch ($node->type) { case 'chado_stock': $values = array('organism_id' => $node->organism_id); $organism = tripal_core_chado_select('organism', array('genus','species'), $values); $values = array('cvterm_id' => $node->type_id); $cvterm = tripal_core_chado_select('cvterm', array('name'), $values); $node->title = $node->sname . ', ' . $node->uniquename . ' (' . $cvterm[0]->name . ') ' . $organism[0]->genus . ' ' . $organism[0]->species; break; } } /** * @ingroup tripal_stock */ function tripal_stock_node_insert($node) { switch ($node->type) { case 'chado_stock': if (!$node->stock_id) { $sql = "SELECT * FROM {chado_stock} WHERE nid = :nid"; $chado_stock = db_query($sql, array(':nid' => $node->nid))->fetchObject(); $node->stock_id = $chado_stock->stock_id; } // remove any previous alias db_query("DELETE FROM {url_alias} WHERE src = :src", array(':src' => "node/$node->nid")); // set the URL for this stock page $url_alias = tripal_stock_get_stock_url($node); $path_alias = array("source" => "node/$node->nid", "alias" => $url_alias); path_save($path_alias); break; } } /** * @ingroup tripal_stock */ function tripal_stock_node_update($node) { switch ($node->type) { case 'chado_stock': // remove any previous alias db_query("DELETE FROM {url_alias} WHERE src = :src", array(':src' => "node/$node->nid")); // set the URL for this stock page $url_alias = tripal_stock_get_stock_url($node); $path_alias = array("source" => "node/$node->nid", "alias" => $url_alias); path_save($path_alias); break; } } /** * @ingroup tripal_stock */ function tripal_stock_node_view($node, $view_mode, $langcode) { switch ($node->type) { case 'chado_organism': if ($view_mode == 'full') { // Show stock if the organism/feature is not at teaser view $node->content['tripal_organism_stocks'] = array( '#value' => theme('tripal_organism_stocks', $node), ); } break; } } /* * Uses the value provided in the $id argument to find all stocks that match * that ID by name, stockname or synonym. If it matches uniquenly to a single * stock it will redirect to that stock page, otherwise, a list of matching * stocks is shown. */ function tripal_stock_match_stocks_page($id) { // if the URL alias configuration is set such that the URL // always begins with 'stock' then we want to use the ID as it is and // forward it on. Otherwise, try to find the matching stock. $url_alias = variable_get('chado_stock_url_string', '/stock/[genus]/[species]/[type]/[uniquename]'); if (!$url_alias) { $url_alias = '/stock/[genus]/[species]/[type]/[uniquename]'; } $url_alias = preg_replace('/^\//', '', $url_alias); // remove any preceeding forward slash if (preg_match('/^stock\//', $url_alias)) { drupal_goto($id); } $sql = " SELECT S.name, S.uniquename, S.stock_id, O.genus, O.species, O.organism_id, CVT.cvterm_id, CVT.name as type_name, CS.nid FROM {stock} S INNER JOIN {organism} O on S.organism_id = O.organism_id INNER JOIN {cvterm} CVT on CVT.cvterm_id = S.type_id INNER JOIN public.chado_stock CS on CS.stock_id = S.stock_id WHERE S.uniquename = :uname or S.name = :name "; $results = chado_query($sql, array(':uname' => $id, ':name' => $id)); $num_matches = 0; // iterate through the matches and build the table for showing matches $header = array('Uniquename', 'Name', 'Type', 'Species'); $rows = array(); $curr_match; while ($match = $results->fetchObject()) { $curr_match = $match; $rows[] = array( $match->uniquename, "nid) ."\">" . $match->name . "", $match->type_name, '' . $match->genus . ' ' . $match->species . '', ); $num_matches++; } // if we have more than one match then generate the table, otherwise, redirect // to the matched stock if ($num_matches == 1) { drupal_goto("node/" . $curr_match->nid); } if ($num_matches == 0) { return "
No stocks matched the given name '$id'
"; } $table_attrs = array( 'class' => 'tripal-table tripal-table-horz' ); $output = "The following stocks match the name '$id'.
"; $output .= theme_table($header, $rows, $table_attrs, $caption); return $output; }