2.0, ); } /** * * @ingroup tripal_contact */ function tripal_contact_init() { drupal_add_css(drupal_get_path('theme', 'tripal') . '/css/tripal_contact.css'); } /** * 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/configuration'] = array( 'title' => 'Configuration', 'description' => 'Integration of Chado contacts.', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_contact_admin'), 'access arguments' => array('administer tripal contact'), '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, ); // AJAX calls for adding/removing properties to a contact $items['tripal_contact/properties/add'] = array( 'page callback' => 'tripal_contact_property_add', 'access arguments' => array('edit chado_contact content'), 'type ' => MENU_CALLBACK, ); $items['tripal_contact/properties/description'] = array( 'page callback' => 'tripal_contact_property_get_description', 'access arguments' => array('edit chado_contact content'), 'type ' => MENU_CALLBACK, ); $items['tripal_contact/properties/minus/%/%'] = array( 'page callback' => 'tripal_contact_property_delete', 'page arguments' => array(3, 4), 'access arguments' => array('edit chado_contact content'), 'type ' => MENU_CALLBACK, ); 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_publications' => array( 'arguments' => array('node' => NULL) ), 'tripal_contact_admin' => array( 'template' => 'tripal_contact_admin', 'arguments' => array(NULL), 'path' => drupal_get_path('module', 'tripal_contact') . '/theme' ), // Themed Forms 'chado_contact_node_form' => array( 'arguments' => array('form'), ), ); } /** * 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 * 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. * */ function chado_contact_access($op, $node, $account ) { if ($op == 'create') { if (!user_access('create chado_contact content', $account)) { return FALSE; } return TRUE; } 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_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 { // we don't want to store the description in the description field as it may be longer than // 255 characters, so we'll use a property to store this value. $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; } // now add the properties $properties = array(); // stores all of the properties we need to add // get the list of properties for easy lookup (without doing lots of database queries $properties_list = array(); $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 NOT CVTO.name = 'Contact Type' ORDER BY CVTS.name ASC "; $prop_types = chado_query($sql); while ($prop = db_fetch_object($prop_types)) { $properties_list[$prop->cvterm_id] = $prop->name; } // get the properties that should be added. Properties are in one of two forms: // 1) prop_value-[type id]-[index] // 2) new_value-[type id]-[index] // 3) new_id, new_value foreach ($node as $name => $value) { if (preg_match('/^new_value-(\d+)-(\d+)/', $name, $matches)) { $type_id = $matches[1]; $index = $matches[2]; $name = $properties_list[$type_id]; $properties[$name][$index] = trim($value); } } if ($node->new_id and $node->new_value) { $type_id = $node->new_id; $index = count($properties[$name]); $name = $properties_list[$type_id]; $properties[$name][$index] = trim($node->new_value); } // now add in the properties foreach ($properties as $property => $elements) { foreach ($elements as $rank => $value) { $status = tripal_contact_insert_property($contact['contact_id'], $property, $value, FALSE); if (!$status) { drupal_set_message("Error cannot add property: $property", "error"); watchdog('t_contact', "Error cannot add property: %prop", array('%property' => $property), WATCHDOG_ERROR); } } } } // add the record to the chado_contact table in Drupal if ($contact) { // add the description property tripal_contact_insert_property($contact['contact_id'], 'contact_description', $node->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); if (!$status) { drupal_set_message("Error updating contact", "error"); watchdog('t_contact', "Error updating contact", array(), WATCHDOG_ERROR); return; } // now update the properties $properties = array(); // stores all of the properties we need to add // get the list of properties for easy lookup (without doing lots of database queries $properties_list = array(); $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 NOT CVTO.name = 'Contact Type' ORDER BY CVTS.name ASC "; $prop_types = chado_query($sql); while ($prop = db_fetch_object($prop_types)) { $properties_list[$prop->cvterm_id] = $prop->name; } // get the properties that should be added. Properties are in one of three forms: // 1) prop_value-[type id]-[index] // 2) new_value-[type id]-[index] // 3) new_id, new_value // dpm($node); foreach ($node as $key => $value) { if (preg_match('/^prop_value-(\d+)-(\d+)/', $key, $matches)) { $type_id = $matches[1]; $index = $matches[2]; $name = $properties_list[$type_id]; $properties[$name][$index] = trim($value); } if (preg_match('/^new_value-(\d+)-(\d+)/', $key, $matches)) { $type_id = $matches[1]; $index = $matches[2]; $name = $properties_list[$type_id]; $properties[$name][$index] = trim($value); } } if ($node->new_id and $node->new_value) { $type_id = $node->new_id; $name = $properties_list[$type_id]; $index = count($properties[$name]); $properties[$name][$index] = trim($node->new_value); } // now add in the properties by first removing any the contact // already has and adding the ones we have tripal_core_chado_delete('contactprop', array('contact_id' => $contact_id)); foreach ($properties as $property => $elements) { foreach ($elements as $rank => $value) { $status = tripal_contact_insert_property($contact_id, $property, $value, FALSE); if (!$status) { drupal_set_message("Error cannot add property: '$property'", "error"); watchdog('t_contact', "Error cannot add property: '%prop'", array('%prop' => $property), WATCHDOG_ERROR); } } } tripal_contact_update_property($contact_id, 'contact_description', $node->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); // get the contact description and replace the contact.description field with this one $values = array( 'contact_id' => $contact->contact_id, 'type_id' => array( 'name' => 'contact_description', ), ); $options = array( 'return_array' => 1, 'include_fk' => array('type_id' => 1), ); $description = tripal_core_generate_chado_var('contactprop', $values, $options); if (count($description) == 1) { $description = tripal_core_expand_chado_vars($description, 'field', 'contactprop.value'); $contact->description = $description[0]->value; } $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 // contact 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; } /* * */ function tripal_contact_form_alter(&$form, &$form_state, $form_id) { if ($form_id == "chado_contact_node_form") { } }