2.0, ); } /** * Implements hook_menu * * @ingroup tripal_project */ function tripal_project_menu() { $items[ 'admin/tripal/tripal_project' ]= array( 'title' => 'Projects', 'description' => ('A module for interfacing the GMOD chado database with Drupal, providing viewing of projects'), 'page callback' => 'theme', 'page arguments' => array('tripal_project_admin'), 'access arguments' => array('adminster tripal projects'), 'type' => MENU_NORMAL_ITEM ); $items[ 'admin/tripal/tripal_project/configuration' ]= array( 'title' => 'Configuration', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_project_admin'), 'access arguments' => array('adminster tripal projects'), 'type' => MENU_NORMAL_ITEM ); return $items; } /** * Implements hook_perm() * * This function sets the permission for the user to access the information in the database. * This includes creating, inserting, deleting and updating of information in the database * * * @ingroup tripal_project */ function tripal_project_perm() { return array( 'access chado_projects content', 'create chado_projects content', 'delete chado_projects content', 'edit chado_projects content', 'adminster tripal projects', ); } /** * Implement hook_access(). * * This hook allows node modules to limit access to the node types they define. * * @param $op * The operation to be performed * * @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 $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_project */ function chado_project_access($op, $node, $account) { if ($op == 'create') { if (!user_access('create chado_projects content', $account)) { return FALSE; } return TRUE; } if ($op == 'update') { if (!user_access('edit chado_projects content', $account)) { return FALSE; } } if ($op == 'delete') { if (!user_access('delete chado_projects content', $account)) { return FALSE; } } if ($op == 'view') { if (!user_access('access chado_projects content', $account)) { return FALSE; } } return NULL; } /** * Implementation of hook_node_info(). * * This node_info, is a simple node that describes the functionallity of the module. It specifies * that the title(Project Name) and body(Description) set to true so that they information can be * entered * * * @ingroup tripal_project */ function tripal_project_node_info() { return array( 'chado_project' => array( 'name' => t('Project'), 'module' => 'chado_project', 'description' => t('A module for interfacing the GMOD chado database with Drupal, providing viewing of projects'), 'has_title' => TRUE, 'title_label' => t('Project Name'), 'had_body' => TRUE, 'body_label' => t('Full Description'), ) ); } /** * 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_project */ function tripal_project_theme() { return array( 'tripal_project_base' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_project_base', ), 'tripal_project_contact' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_project_contact', ), 'tripal_project_publications' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_project_publications', ), 'tripal_project_relationships' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_project_relationships', ), 'tripal_project_properties' => array( 'arguments' => array('node' => NULL), 'template' => 'tripal_project_properties', ), 'tripal_project_admin' => array( 'template' => 'tripal_project_admin', 'arguments' => array(NULL), 'path' => drupal_get_path('module', 'tripal_project') . '/theme' ), ); } /** * Implementation of hook_form(). * * This form takes the Project Title information and description from the user. * * @parm $node * The initialized node * * @parm $form_state * The state of the form, that has the user entered information that is neccessary for adding * information to the project * * @return $form * An array as described by the Drupal Form API * * * @ingroup tripal_project */ function chado_project_form(&$node, $form_state) { $form = array(); $project = $node->project; // get the project default values. When this module was first created // the project description was incorrectly stored in the $node->body field. // It is better to store it in the Chado tables. However, the 'description' // field of the project table is only 255 characters. So, we are going // to follow the same as the project module and store the description in // the projectprop table and leave the project.description field blank. // however, for backwards compatibitily, we check to see if the description // is in the $node->body field. If it is we'll use that. When the node is // edited the text will be moved out of the body and into the projectprop // table where it should belong. if ($node->body) { $project_description = $node->body; } else { $project_description = $node->project_description; } if (!$project_description) { $projectprop = tripal_project_get_property($project->project_id, 'project_description'); $project_description = $projectprop->value; } // keep track of the project id if we have. If we do have one then // this is an update as opposed to an insert. $form['project_id'] = array( '#type' => 'value', '#value' => $project->project_id, ); $form['title']= array( '#type' => 'textfield', '#title' => t('Project Title'), '#description' => t('Please enter the title for this project. This appears at the top of the project page.'), '#required' => TRUE, '#default_value' => $node->title, '#weight' => 1 ); $form['project_description']= array( '#type' => 'textarea', '#title' => t('Project Description'), '#description' => t('A brief description of the project'), '#required' => TRUE, '#default_value' => $project_description, '#weight' => 5 ); return $form; } /** * validates submission of form when adding or updating a project node * * @ingroup tripal_project */ function chado_project_validate($node) { $project = 0; // check to make sure the name on the project is unique // before we try to insert into chado. if ($node->project_id) { $sql = "SELECT * FROM {project} WHERE name = '%s' AND NOT project_id = %d"; $project = db_fetch_object(chado_query($sql, $node->title, $node->project_id)); } else { $sql = "SELECT * FROM {project} WHERE name = '%s'"; $project = db_fetch_object(chado_query($sql, $node->title)); } if ($project) { form_set_error('title', t('The unique project name already exists. Please choose another')); } } /** * Implementation of hook_insert(). * * @parm $node * Then node that has the information stored within, accessed given the nid * * * @ingroup tripal_project */ function chado_project_insert($node) { if ($node->project_id) { $project['project_id'] = $node->project_id; } else { $values = array( 'name' => $node->title, 'description' => '', ); $project = tripal_core_chado_insert('project', $values); } if ($project) { // add the description property tripal_project_insert_property($project['project_id'], 'project_description', $node->project_description); // make sure the entry for this feature doesn't already exist in the chado_project table // if it doesn't exist then we want to add it. $project_id = chado_get_id_for_node('project', $node) ; if (!$project_id) { // next add the item to the drupal table $sql = "INSERT INTO {chado_project} (nid, vid, project_id) ". "VALUES (%d, %d, %d)"; db_query($sql, $node->nid, $node->vid, $project['project_id']); } } else { drupal_set_message(t('Unable to add project.', 'warning')); watchdog('tripal_project', 'Insert feature: Unable to create project where values: %values', array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING); } } /** * * Implementation of hook_delete(). * * @param $node * The node which is to be deleted, only chado project and chado_project need to be dealt with * since the drupal node is deleted automagically * * * @ingroup tripal_project */ function chado_project_delete($node) { $project_id = chado_get_id_for_node('project', $node); // if we don't have a project id for this node then this isn't a node of // type chado_project or the entry in the chado_project table was lost. if (!$project_id) { return; } // Remove data from {chado_project}, {node} and {node_revisions} tables of // drupal database $sql_del = "DELETE FROM {chado_project} ". "WHERE nid = %d ". "AND vid = %d"; db_query($sql_del, $node->nid, $node->vid); $sql_del = "DELETE FROM {node_revisions} ". "WHERE nid = %d ". "AND vid = %d"; db_query($sql_del, $node->nid, $node->vid); $sql_del = "DELETE FROM {node} ". "WHERE nid = %d ". "AND vid = %d"; db_query($sql_del, $node->nid, $node->vid); // Remove data from project and projectprop tables of chado database as well chado_query("DELETE FROM {projectprop} WHERE project_id = %d", $project_id); chado_query("DELETE FROM {project} WHERE project_id = %d", $project_id); } /** * Implements hook_update(). * * @param $node * The node which is to have its containing information updated when the user modifies information * pertaining to the specific project * * * @ingroup tripal_project */ function chado_project_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 the project and the description $project_id = chado_get_id_for_node('project', $node) ; $match = array( 'project_id' => $project_id, ); $values = array( 'name' => $node->title, 'description' => '', ); $status = tripal_core_chado_update('project', $match, $values); tripal_project_update_property($project_id, 'project_description', $node->project_description, 1); } /** * Implementation of node_load(). * * @param $node * The node that is to have its containing information loaded * * @return $node * The node, containing the loaded project with the current nid * * * @ingroup tripal_project */ function chado_project_load($node) { // get the feature details from chado $project_id = chado_get_id_for_node('project', $node); $values = array('project_id' => $project_id); $project = tripal_core_generate_chado_var('project', $values); $additions = new stdClass(); $additions->project = $project; return $additions; } /** * Display block with projects * @param op - parameter to define the phase being called for the block * @param delta - id of the block to return (ignored when op is list) * @param edit - when op is save, contains the submitted form data * * @ingroup tripal_project */ function tripal_project_block($op = 'list', $delta = '0', $edit = array()) { switch ($op) { case 'list': $blocks['projectbase']['info'] = t('Tripal Project Details'); $blocks['projectbase']['cache'] = BLOCK_NO_CACHE; $blocks['projectprops']['info'] = t('Tripal Project Properties'); $blocks['projectprops']['cache'] = BLOCK_NO_CACHE; $blocks['projectpubs']['info'] = t('Tripal Project Publications'); $blocks['projectpubs']['cache'] = BLOCK_NO_CACHE; $blocks['projectcont']['info'] = t('Tripal Project Contact'); $blocks['projectcont']['cache'] = BLOCK_NO_CACHE; $blocks['projectrels']['info'] = t('Tripal Project Relationships'); $blocks['projectrels']['cache'] = BLOCK_NO_CACHE; return $blocks; case 'view': if (user_access('access chado_project content') and arg(0) == 'node' and is_numeric(arg(1))) { $nid = arg(1); $node = node_load($nid); $block = array(); switch ($delta) { case 'projectbase': $block['subject'] = t('Project Details'); $block['content'] = theme('tripal_project_base', $node); break; case 'projectprops': $block['subject'] = t('Properties'); $block['content'] = theme('tripal_project_properties', $node); break; case 'projectpubs': $block['subject'] = t('Publications'); $block['content'] = theme('tripal_project_publications', $node); break; case 'projectcont': $block['subject'] = t('Contact'); $block['content'] = theme('tripal_project_contact', $node); break; case 'projectrels': $block['subject'] = t('Relationships'); $block['content'] = theme('tripal_project_relationships', $node); break; default : } return $block; } } } /** * * * @ingroup tripal_project */ function tripal_project_preprocess_tripal_project_relationships(&$variables) { // we want to provide a new variable that contains the matched projects. $project = $variables['node']->project; // 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 P.name, P.project_id, CP.nid, CVT.name as rel_type FROM project_relationship PR INNER JOIN {project} P ON PR.object_project_id = P.project_id INNER JOIN {cvterm} CVT ON PR.type_id = CVT.cvterm_id LEFT JOIN public.chado_project CP ON P.project_id = CP.project_id WHERE PR.subject_project_id = %d "; $as_subject = chado_query($sql, $project->project_id); $sql = " SELECT P.name, P.project_id, CP.nid, CVT.name as rel_type FROM project_relationship PR INNER JOIN {project} P ON PR.subject_project_id = P.project_id INNER JOIN {cvterm} CVT ON PR.type_id = CVT.cvterm_id LEFT JOIN public.chado_project CP ON P.project_id = CP.project_id WHERE PR.object_project_id = %d "; $as_object = chado_query($sql, $project->project_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 = db_fetch_object($as_object)) { // 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 = db_fetch_object($as_subject)) { // 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; } $project->all_relationships = $relationships; }