2.0, ); } /** * * @ingroup tripal_contact */ function tripal_contact_init() { } /** * Implementation of hook_tripal_contact_node_info(). * * This node_info, is a simple node that describes the functionallity of the module. * */ function tripal_contact_node_info() { return array( 'chado_contact' => array( 'name' => t('Contact'), 'module' => 'chado_contact', 'description' => t('A contact from the Chado database'), 'title_label' => t('Article Title'), 'body_label' => t('Abstract'), 'has_title' => TRUE, 'has_body' => FALSE, ), ); } /** * Tripal-contact-Menu * * Implemets hook_menu(): Adds menu items for the tripal_contact module menu. This section * gives the outline for the main menu of the Tripal-contact module * * @return * An array of menu items that is visible within the Drupal Menu, returned as soon * as the program is ran */ function tripal_contact_menu() { $items = array(); $items[ 'admin/tripal/tripal_contact' ]= array( 'title' => 'Contacts', 'description' => ('A module for interfacing the GMOD chado database with Drupal, providing viewing of contacts'), 'page callback' => 'theme', 'page arguments' => array('tripal_contact_admin'), 'access arguments' => array('administer tripal contacts'), 'type' => MENU_NORMAL_ITEM ); $items['admin/tripal/tripal_contact/sync'] = array( 'title' => ' Sync Contacts', 'description' => 'Sync contacts in Chado with Drupal', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_contact_sync_form'), 'access arguments' => array('administer tripal contacts'), 'type' => MENU_NORMAL_ITEM, ); return $items; } /** * Implements hook_theme(): Register themeing functions for this module * * * @return * An array of themeing functions to register * */ function tripal_contact_theme() { return array( 'tripal_contact_base' => array( 'arguments' => array('node' => NULL), ), 'tripal_contact_properties' => array( 'arguments' => array('node' => NULL) ), 'tripal_contact_relationships' => array( 'arguments' => array('node' => NULL) ), 'tripal_contact_admin' => array( 'template' => 'tripal_contact_admin', 'arguments' => array(NULL), 'path' => drupal_get_path('module', 'tripal_contact') . '/theme' ), ); } /** * Implement hook_perm(). */ function tripal_contact_perm() { return array( 'access chado_contact content', 'create chado_contact content', 'delete chado_contact content', 'edit chado_contact content', 'administer tripal contacts', ); } /** * 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 * TRUE * */ function chado_contact_access($op, $node, $account ) { if ($op == 'create') { if (!user_access('create chado_contact content', $account)) { return FALSE; } } if ($op == 'update') { if (!user_access('edit chado_contact content', $account)) { return FALSE; } } if ($op == 'delete') { if (!user_access('delete chado_contact content', $account)) { return FALSE; } } if ($op == 'view') { if (!user_access('access chado_contact content', $account)) { return FALSE; } } return NULL; } /** * Implementation of tripal_contact_form(). * * * * @parm &$node * The node that is created when the database is initialized * * @parm $form_state * The state of the form, that has the user entered information that is neccessary for, setting * up the database tables for the contact * * @return $form * The information that was enterd allong with * */ function chado_contact_form(&$node, $form_state) { $form = array(); $contact = $node->contact; // get the contact default values. When this module was first created // the contact 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 contact table is only 255 characters. So, we are going // to follow the same as the contact module and store the description in // the contactprop table and leave the contact.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 contactprop // table where it should belong. if ($node->body) { $contact_description = $node->body; } else { $contact_description = $node->contact_description; } if (!$contact_description) { $contactprop = tripal_contact_get_property($contact->contact_id, 'contact_description'); $contact_description = $contactprop->value; } $form['contact_id'] = array( '#type' => 'hidden', '#value' => (isset($node->contact_id)) ? $node->contact_id->contact_id : NULL , ); $sql = " SELECT CVTS.cvterm_id, CVTS.name FROM {cvtermpath} CVTP INNER JOIN {cvterm} CVTS ON CVTP.subject_id = CVTS.cvterm_id INNER JOIN {cvterm} CVTO ON CVTP.object_id = CVTO.cvterm_id INNER JOIN {cv} CV ON CVTO.cv_id = CV.cv_id WHERE CV.name = 'tripal_contact' AND CVTO.name = 'Contact Type' AND CVTP.pathdistance = 1 ORDER BY CVTS.name ASC "; $results = chado_query($sql); $contact_types = array(); $default_type = ''; while ($contact_type = db_fetch_object($results)) { $contact_types[$contact_type->cvterm_id] = $contact_type->name; if (strcmp($contact_type->name,"Person") == 0) { $default_type = $contact_type->cvterm_id; } } $form['type_id'] = array( '#type' => 'select', '#title' => t('Contact Type'), '#options' => $contact_types, '#required' => TRUE, '#default_value' => isset($contact->contact_id->type_id) ? $contact->contact_id->type_id : $default_type, ); $form['title']= array( '#type' => 'textfield', '#title' => t('Contact Name'), '#description' => t('Enter the name of this contact'), '#required' => TRUE, '#default_value' => $contact->name, '#weight' => 1 ); $form['contact_description']= array( '#type' => 'textarea', '#title' => t('Contact Description'), '#description' => t('A brief description of the contact'), '#required' => TRUE, '#default_value' => $contact_description, '#weight' => 5 ); return $form; } /** * Implementation of tripal_contact_insert(). * * This function inserts user entered information pertaining to the contact instance into the * 'contactauthor', 'contactprop', 'chado_contact', 'contact' talble of the database. * * @parm $node * Then node which contains the information stored within the node-ID * * */ function chado_contact_insert($node) { // if a contact_id already exists for this node then it already exists in Chado and // we get here because we are syncing the node. Therefore, we can skip the insert if ($node->contact_id) { $contact['contact_id'] = $node->contact_id; } else { // check to see if this contact name already exists. $values = array('name' => $node->contact_name); $options = array('statement_name' => 'sel_contact_na'); $contact = tripal_core_chado_select('contact', array('contact_id'), $values, $options); if (count($contact) > 0) { drupal_set_message(t('A contact with this name already exists.', 'error')); watchdog('tripal_contact','Insert Contact: A contact with this name already exists. %name', array('%name' => $node->contact_name), WATCHDOG_ERROR); return FALSE; } else { $values = array( 'name' => $node->title, 'description' => '', 'type_id' => $node->type_id ); $options = array('statement_name' => 'ins_contact_nadety'); $contact = tripal_core_chado_insert('contact', $values, $options); if (!$contact) { drupal_set_message(t('Could not add the contact'), 'error'); watchdog('tripal_contact','Could not add the contact', array(), WATCHDOG_ERROR); return FALSE; } } } if ($contact) { // add the description property tripal_contact_insert_property($contact['contact_id'], 'contact_description', $node->contact_description, TRUE); // make sure the entry for this contact doesn't already exist in the chado_contact table // if it doesn't exist then we want to add it. $contact_id = chado_get_id_for_node('contact', $node) ; if (!$contact_id) { // next add the item to the drupal table $sql = "INSERT INTO {chado_contact} (nid, vid, contact_id) ". "VALUES (%d, %d, %d)"; db_query($sql, $node->nid, $node->vid, $contact['contact_id']); } } else { drupal_set_message(t('Unable to add contact.', 'warning')); watchdog('tripal_contact', 'Insert contact: Unable to create contact where values: %values', array('%values' => print_r($values, TRUE)), WATCHDOG_WARNING); } return TRUE; } /* * * Implements hook_update * * The purpose of the function is to allow the module to take action when an edited node is being * updated. It updates any name changes to the database tables that werec reated upon registering a contact. * As well, the database will be changed, so the user changed information will be saved to the database. * * @param $node * The node being updated * * @ingroup tripal_contact */ function chado_contact_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. } $contact_id = chado_get_id_for_node('contact', $node) ; // check to see if this contact name doens't already exists. $sql = "SELECT contact_id FROM {contact} WHERE NOT contact_id = %d AND name = '%s'"; $contact = db_fetch_object(chado_query($sql, $contact_id, $node->contact_name)); if ($contact) { drupal_set_message(t('A contact with this name already exists. Cannot perform update.'), 'warning'); return; } // update the contact record $match = array( 'contact_id' => $contact_id, ); $values = array( 'name' => $node->title, 'description' => '', 'type_id' => $node->type_id ); $status = tripal_core_chado_update('contact', $match, $values); tripal_contact_update_property($contact_id, 'contact_description', $node->contact_description, 1); } /** * Implementation of tripal_contact_load(). * * * @param $node * The node that is to be accessed from the database * * @return $node * The node with the information to be loaded into the database * */ function chado_contact_load($node) { // get the feature details from chado $contact_id = chado_get_id_for_node('contact', $node); $values = array('contact_id' => $contact_id); $contact = tripal_core_generate_chado_var('contact', $values); $additions = new stdClass(); $additions->contact = $contact; return $additions; } /** * Implementation of tripal_contact_delete(). * * This function takes a node and if the delete button has been chosen by the user, the contact * and it's details will be removed.Following,given the node-ID, the instance will be deleted from * the 'chado_contact' table. * * @parm $node * Then node which contains the information stored within the node-ID * */ function chado_contact_delete(&$node) { $contact_id = chado_get_id_for_node('contact', $node); // if we don't have a contact id for this node then this isn't a node of // type chado_contact or the entry in the chado_contact table was lost. if (!$contact_id) { return; } // Remove data from {chado_contact}, {node} and {node_revisions} tables of // drupal database $sql_del = "DELETE FROM {chado_contact} ". "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 contact and contactprop tables of chado database as well chado_query("DELETE FROM {contactprop} WHERE contact_id = %d", $contact_id); chado_query("DELETE FROM {contact} WHERE contact_id = %d", $contact_id); } /** * * * @ingroup tripal_contact */ function tripal_contact_preprocess_tripal_contact_relationships(&$variables) { // we want to provide a new variable that contains the matched contacts. $contact = $variables['node']->contact; // 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 C.name, C.contact_id, CP.nid, CVT.name as rel_type FROM contact_relationship PR INNER JOIN {contact} C ON PR.object_id = C.contact_id INNER JOIN {cvterm} CVT ON PR.type_id = CVT.cvterm_id LEFT JOIN public.chado_contact CP ON C.contact_id = CP.contact_id WHERE PR.subject_id = %d "; $as_subject = chado_query($sql, $contact->contact_id); $sql = " SELECT C.name, C.contact_id, CP.nid, CVT.name as rel_type FROM contact_relationship PR INNER JOIN {contact} C ON PR.subject_id = C.contact_id INNER JOIN {cvterm} CVT ON PR.type_id = CVT.cvterm_id LEFT JOIN public.chado_contact CP ON C.contact_id = CP.contact_id WHERE PR.object_id = %d "; $as_object = chado_query($sql, $contact->contact_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; } $contact->all_relationships = $relationships; }