2.0, ); } /** * * @ingroup tripal_contact */ function tripal_contact_init() { drupal_add_js(drupal_get_path('module', 'tripal_contact') . '/theme/js/tripal_contact.js'); drupal_add_css(drupal_get_path('module', 'tripal_contact') . '/theme/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'), 'base' => '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/chado/tripal_contact']= array( 'title' => 'Contacts', 'description' => ('Model persons, institutes, groups, organizations, etc.'), 'page callback' => 'tripal_contact_admin_contact_view', 'access arguments' => array('administer tripal contacts'), 'type' => MENU_NORMAL_ITEM ); $items['admin/tripal/chado/tripal_contact/configuration'] = array( 'title' => 'Settings', 'description' => 'Integration of Chado contacts.', 'page callback' => 'drupal_get_form', 'page arguments' => array('tripal_contact_admin'), 'access arguments' => array('administer tripal contact'), 'type' => MENU_LOCAL_TASK, 'weight' => 5 ); $items['admin/tripal/chado/tripal_contact/help']= array( 'title' => 'Help', 'description' => ('Help with the contact module.'), 'page callback' => 'theme', 'page arguments' => array('tripal_contact_help'), 'access arguments' => array('administer tripal contacts'), 'type' => MENU_LOCAL_TASK, 'weight' => 10 ); $items['admin/tripal/chado/tripal_contact/sync'] = array( 'title' => ' Sync', '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_LOCAL_TASK, 'weight' => 0 ); // 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($existing, $type, $theme, $path) { $core_path = drupal_get_path('module', 'tripal_core'); $items = array( 'node__chado_contact' => array( 'template' => 'node--chado-generic', 'render element' => 'node', 'base hook' => 'node', 'path' => "$core_path/theme", ), 'tripal_contact_base' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_contact_base', 'path' => "$path/theme/tripal_contact", ), 'tripal_contact_properties' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_contact_properties', 'path' => "$path/theme/tripal_contact", ), 'tripal_contact_relationships' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_contact_relationships', 'path' => "$path/theme/tripal_contact", ), 'tripal_contact_publications' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_contact_publications', 'path' => "$path/theme/tripal_contact", ), 'tripal_contact_help' => array( 'template' => 'tripal_contact_help', 'variables' => array(NULL), 'path' => "$path/theme", ), 'tripal_contact_teaser' => array( 'variables' => array('node' => NULL), 'template' => 'tripal_contact_teaser', 'path' => "$path/theme/tripal_contact", ), ); return $items; } /** * @ingroup tripal_contact */ function tripal_contact_block_info() { $blocks['contbase']['info'] = t('Tripal Contact Details'); $blocks['contbase']['cache'] = 'BLOCK_NO_CACHE'; $blocks['contprops']['info'] = t('Tripal Contact Properties'); $blocks['contprops']['cache'] = 'BLOCK_NO_CACHE'; $blocks['contrels']['info'] = t('Tripal Contact Relationships'); $blocks['contrels']['cache'] = 'BLOCK_NO_CACHE'; $blocks['contpubs']['info'] = t('Tripal Cotact Publications'); $blocks['contpubs']['cache'] = 'BLOCK_NO_CACHE'; return $blocks; } /** * @ingroup tripal_contact */ function tripal_contact_block_view($delta = '') { if (user_access('access chado_contact content') and arg(0) == 'node' and is_numeric(arg(1))) { $nid = arg(1); $node = node_load($nid); $block = array(); switch ($delta) { case 'contbase': $block['subject'] = t('Details'); $block['content'] = theme('tripal_contact_base', $node); break; case 'contprops': $block['subject'] = t('Properties'); $block['content'] = theme('tripal_contact_properties', $node); break; case 'contrels': $block['subject'] = t('Relationships'); $block['content'] = theme('tripal_contact_relationships', $node); break; case 'contpubs': $block['subject'] = t('Publications'); $block['content'] = theme('tripal_contact_publications', $node); break; default : } return $block; } } /** * Implement hook_perm(). */ function tripal_contact_permissions() { return array( 'access chado_contact content' => array( 'title' => t('View Contacts'), 'description' => t('Allow users to view contact pages.'), ), 'create chado_contact content' => array( 'title' => t('Create Contacts'), 'description' => t('Allow users to create new contact pages.'), ), 'delete chado_contact content' => array( 'title' => t('Delete Contacts'), 'description' => t('Allow users to delete contact pages.'), ), 'edit chado_contact content' => array( 'title' => t('Edit Contacts'), 'description' => t('Allow users to edit contact pages.'), ), 'adminster tripal contact' => array( 'title' => t('Administer Contacts'), 'description' => t('Allow users to administer all contacts.'), ), ); } /** * 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. * */ function chado_contact_node_access($node, $op, $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) { // remove surrounding white-space on submitted values $node->title = trim($node->title); $node->description = trim($node->description); // if there is a contact_id in the $node object then this must be a sync so // we can skip adding the contact as it is already there, although // we do need to proceed with the rest of the insert if (!property_exists($node, 'contact_id')) { // insert and then get the newly inserted contact record $values = array( 'name' => $node->title, 'description' => '', 'type_id' => $node->type_id, ); $contact = tripal_core_chado_insert('contact', $values); if (!$contact) { 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_ERROR); return; } $contact_id = $contact['contact_id']; // now add in the properties $properties = tripal_core_properties_form_retreive($node, 'tripal_contact'); 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('%property' => $property), WATCHDOG_ERROR); } } } // add in the description as a separate property tripal_contact_insert_property($contact_id, 'contact_description', $node->description, FALSE); } else { $contact_id = $node->contact_id; } // 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. $check_org_id = chado_get_id_for_node('contact', $node->nid); if (!$check_org_id) { $record = new stdClass(); $record->nid = $node->nid; $record->vid = $node->vid; $record->contact_id = $contact_id; drupal_write_record('chado_contact', $record); } 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) { // remove surrounding white-space on submitted values $node->title = trim($node->title); $node->description = trim($node->description); $contact_id = chado_get_id_for_node('contact', $node->nid) ; // 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 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)); $properties = tripal_core_properties_form_retreive($node, 'tripal_contact'); 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); } } } // add in the description as a separate property 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($nodes) { foreach ($nodes as $nid => $node) { // find the contact and add in the details $contact_id = chado_get_id_for_node('contact', $nid); // get the contact $values = array('contact_id' => $contact_id); $contact = tripal_core_generate_chado_var('contact', $values); // get the contact description from the contactprop table and replace // the contact.description field with this one (we don't use the contact.description // field because it is only 255 characters (too small)). $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; } $nodes[$nid]->contact = $contact; } } /** * 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->nid); // 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 = :nid AND vid = :vid"; db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid)); $sql_del = "DELETE FROM {node_revision} WHERE nid = :nid AND vid = :vid"; db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid)); $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid"; db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid)); // Remove data from contact and contactprop tables of chado database as well chado_query("DELETE FROM {contactprop} WHERE contact_id = :contact_id", array(':contact_id' => $contact_id)); chado_query("DELETE FROM {contact} WHERE contact_id = :contact_id", array(':contact_id' => $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 = :contact_id "; $as_subject = chado_query($sql, array(':contact_id' => $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 = :contact_id "; $as_object = chado_query($sql, array(':contact_id' => $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 = $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; } $contact->all_relationships = $relationships; } /** * Implementation of hook_form_alter() * * @param $form * @param $form_state * @param $form_id */ function tripal_contact_form_alter(&$form, &$form_state, $form_id) { // turn of preview button for insert/updates if ($form_id == "chado_contact_node_form") { $form['actions']['preview']['#access'] = FALSE; } } /** * * @ingroup tripal_feature */ function tripal_contact_node_view($node, $view_mode, $langcode) { switch ($node->type) { case 'chado_contact': // Show feature browser and counts if ($view_mode == 'full') { $node->content['tripal_contact_base'] = array( '#value' => theme('tripal_contact_base', array('node' => $node)), ); $node->content['tripal_contact_properties'] = array( '#value' => theme('tripal_contact_properties', array('node' => $node)), ); $node->content['tripal_contact_publications'] = array( '#value' => theme('tripal_contact_publications', array('node' => $node)), ); $node->content['tripal_contact_relationships'] = array( '#value' => theme('tripal_contact_relationships', array('node' => $node)), ); } if ($view_mode == 'teaser') { $node->content['tripal_contact_teaser'] = array( '#value' => theme('tripal_contact_teaser', array('node' => $node)), ); } break; } }