| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284 | <?php/** * @file * Implements Drupal Node hooks to create the chado_analysis node content type. * * @ingroup tripal_legacy_pub *//** * Implements hook_node_info(). * * Provide information to drupal about the node types that we're creating * in this module * * @ingroup tripal_legacy_pub */function tripal_pub_node_info() {  $nodes = array();  $nodes['chado_pub'] = array(    'name'        => t('Publication (Tripal v2 legacy)'),    'base'        => 'chado_pub',    'description' => t('A publication from the Chado database'),    'has_title'   => TRUE,    'locked'      => TRUE,    'chado_node_api' => array(      'base_table' => 'pub',      'hook_prefix' => 'chado_pub',      'record_type_title' => array(        'singular' => t('Publication'),        'plural' => t('Publications')      ),      'sync_filters' => array(        'type_id' => FALSE,        'organism_id' => FALSE,      ),    ),  );  return $nodes;}/** * Implements hook_form(). * * @ingroup tripal_legacy_pub */function chado_pub_form($node, $form_state) {  $form = array();  // Check to make sure that the tripal_pub vocabulary is loaded. If not, then  // warn the user that they should load it before continuing.  $pub_cv = chado_select_record('cv', array('cv_id'), array('name' => 'tripal_pub'));  if (count($pub_cv) == 0) {    drupal_set_message(t('The Tripal Pub vocabulary is currently not loaded. ' .        'This vocabulary is required to be loaded before adding ' .        'publications.  <br>Please !import',        array('!import' => l('load the Tripal Publication vocabulary', 'admin/tripal/loaders/chado_vocabs/obo_loader'))), 'warning');  }  // Default values can come in the following ways:  //  // 1) as elements of the $node object.  This occurs when editing an existing pub  // 2) in the $form_state['values'] array which occurs on a failed validation or  //    ajax callbacks from non submit form elements  // 3) in the $form_state['input'] array which occurs on ajax callbacks from submit  //    form elements and the form is being rebuilt  //  // set form field defaults  $pub_id      = null;  $title       = '';  $pyear       = '';  $uniquename  = '';  $type_id     = '';  $is_obsolete = '';  // some of the fields in the pub table should show up in the properties  // form elements to make the form more seemless.  We will add them  // to this array.  $more_props = array();  // if we are editing an existing node then the pub is already part of the node  if (property_exists($node, 'pub')) {    $pub = $node->pub;    $pub = chado_expand_var($pub, 'field', 'pub.title');    $pub = chado_expand_var($pub, 'field', 'pub.volumetitle');    $pub = chado_expand_var($pub, 'field', 'pub.uniquename');    $pub_id = $pub->pub_id;    $title       = $pub->title;    $pyear       = $pub->pyear;    $uniquename  = $pub->uniquename;    $type_id     = $pub->type_id->cvterm_id;    $is_obsolete = $pub->is_obsolete;    // if the obsolete value is set by the database then it is in the form of    // 't' or 'f', we need to convert to 1 or 0    $is_obsolete = $is_obsolete == 't' ? 1 : $is_obsolete;    $is_obsolete = $is_obsolete == 'f' ? 0 : $is_obsolete;    // set the organism_id in the form    $form['pub_id'] = array(      '#type' => 'value',      '#value' => $pub->pub_id,    );    // get fields from the pub table and convert them to properties. We will add these to the $more_props    // array which gets passed in to the tripal_core_properties_form() API call further down    if ($pub->volumetitle) {      $cvterm = tripal_get_cvterm(array(        'name' => 'Volume Title',        'cv_id' => array('name' => 'tripal_pub')      ));      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->volumetitle);    }    if ($pub->volume) {      $cvterm = tripal_get_cvterm(array(        'name' => 'Volume',        'cv_id' => array('name' => 'tripal_pub')      ));      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->volume);    }    if ($pub->series_name) {      switch ($pub->type_id->name) {        case 'Journal Article':          $cvterm = tripal_get_cvterm(array(            'name' => 'Journal Name',            'cv_id' => array('name' => 'tripal_pub')          ));          $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->series_name);          break;        case 'Conference Proceedings':          $cvterm = tripal_get_cvterm(array(            'name' => 'Conference Name',            'cv_id' => array('name' => 'tripal_pub')          ));          $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->series_name);          break;        default:          $cvterm = tripal_get_cvterm(array(            'name' => 'Series Name',            'cv_id' => array('tripal_pub')          ));          $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->series_name);      }    }    if ($pub->issue) {      $cvterm = tripal_get_cvterm(array(        'name' => 'Issue',        'cv_id' => array('name' => 'tripal_pub')      ));      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->issue);    }    if ($pub->pages) {      $cvterm = tripal_get_cvterm(array(        'name' => 'Pages',        'cv_id' => array('name' => 'tripal_pub')      ));      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->pages);    }    if ($pub->miniref) {      // not sure what to do with this one    }    if ($pub->publisher) {      $cvterm = tripal_get_cvterm(array(        'name' => 'Publisher',        'cv_id' => array('name' => 'tripal_pub')      ));      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->publisher);    }    if ($pub->pubplace) {      $cvterm = tripal_get_cvterm(array(        'name' => 'Published Location',        'cv_id' => array('name' => 'tripal_pub')      ));      $more_props[] = array('cvterm' => $cvterm, 'value' => $pub->pages);    }  }  // if we are re constructing the form from a failed validation or ajax callback  // then use the $form_state['values'] values  if (array_key_exists('values', $form_state) and isset($form_state['values']['pubtitle'])) {    $title        = $form_state['values']['pubtitle'];    $pyear        = $form_state['values']['pyear'];    $uniquename   = $form_state['values']['uniquename'];    $type_id      = $form_state['values']['type_id'];    $is_obsolete  = $form_state['values']['is_obsolete'];  }  // if we are re building the form from after submission (from ajax call) then  // the values are in the $form_state['input'] array  if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {    $title        = $form_state['input']['pubtitle'];    $uniquename   = $form_state['input']['uniquename'];    $type_id      = $form_state['input']['type_id'];    $is_obsolete  = array_key_exists('is_obsolete', $form_state['input']) ? $form_state['input']['is_obsolete'] : '';  }  $form['pubtitle'] = array(    '#type' => 'textarea',    '#title' => t('Publication Title'),    '#default_value' => $title,    '#required' => TRUE,  );  $type_cv = tripal_get_default_cv('pub', 'type_id');  if ($type_cv and $type_cv->name == 'tripal_pub') {    // get the list of publication types.  In the Tripal publication    // ontologies these are all grouped under the term 'Publication Type'    // we want the default to be 'Journal Article'    $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}          ON CVTO.cv_id      = CV.cv_id      WHERE        CV.name = 'tripal_pub' AND CVTO.name = 'Publication Type' AND        NOT CVTS.is_obsolete = 1      ORDER BY CVTS.name ASC    ";    $results = chado_query($sql);    $pub_types = array();    while ($pub_type = $results->fetchObject()) {      $pub_types[$pub_type->cvterm_id] = $pub_type->name;      // if we don't have a default type then set the default to be 'Journal Article'      if (strcmp($pub_type->name,"Journal Article") == 0 and !$type_id) {        $type_id = $pub_type->cvterm_id;      }    }  }  else {    $pub_types = tripal_get_cvterm_default_select_options('pub', 'type_id', 'publication types');    $pub_types[0] = 'Select a Type';  }  $form['type_id'] = array(    '#type' => 'select',    '#title' => t('Publication Type'),    '#options' => $pub_types,    '#required' => TRUE,    '#default_value' => $type_id,  );  $form['pyear'] = array(    '#type' => 'textfield',    '#title' => t('Publication Year'),    '#default_value' => $pyear,    '#required' => TRUE,    '#size' => 5,    '#description' => t('Enter the year of publication. Also, if available, please add a <b>Publication Date</b> property to specify the full date of publication.'),  );  $form['uniquename'] = array(    '#type' => 'textarea',    '#title' => t('Citation'),    '#default_value' => $uniquename,    '#description' => t('All publications must have a unique citation.      <b>Please enter the full citation for this publication or leave blank and one will be generated      automatically if possible</b>.  For PubMed style citations list      the last name of the author followed by initials. Each author should be separated by a comma. Next comes      the title, followed by the series title (e.g. journal name), publication date (4 digit year, 3 character Month, day), volume, issue and page numbers. You may also use HTML to provide a link in the citation.      Below is an example: <pre>Medeiros PM, Ladio AH, Santos AM, Albuquerque UP. <a href="http://www.ncbi.nlm.nih.gov/pubmed/23462414" target="_blank">Does the selection of medicinal plants by Brazilian local populations        suffer taxonomic influence?</a> J Ethnopharmacol. 2013 Apr 19; 146(3):842-52.</pre>'),  );  $form['is_obsolete'] = array(    '#type' => 'checkbox',    '#title' => t('Is Obsolete? (Check for Yes)'),    '#default_value' => $is_obsolete,  );  // Properties Form  // ----------------------------------  $select_options = array();  $prop_cv = tripal_get_default_cv('pubprop', 'type_id');  $cv_id = $prop_cv ? $prop_cv->cv_id : NULL;  // if the poperty cv is 'tripal_pub' then we need to pass in our own select_options  // for only a subset of the vocabulary  if ($prop_cv and $prop_cv->name == 'tripal_pub') {    $select_options[] = 'Select a Property';    $sql = "      SELECT        DISTINCT CVTS.cvterm_id, CVTS.name, CVTS.definition      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}          ON CVTO.cv_id      = CV.cv_id      WHERE CV.name = 'tripal_pub' and        (CVTO.name = 'Publication Details' OR CVTS.name = 'Publication Type') AND        NOT CVTS.is_obsolete = 1      ORDER BY CVTS.name ASC    ";    $prop_types = chado_query($sql);    while ($prop = $prop_types->fetchObject()) {      // add all properties except the Citation. That property is set via the uniquename field      if ($prop->name == 'Citation') {        continue;      }      // Publication Dbxref's are handled by the dbxref form addition below      if ($prop->name == 'Publication Dbxref') {        continue;      }      $select_options[$prop->cvterm_id] = $prop->name;    }  }  $details = array(    'property_table' => 'pubprop',    'chado_id' => $pub_id,    'cv_id' => $cv_id,    'select_options' => $select_options,    'default_properties' => $more_props,  );  chado_add_node_form_properties($form, $form_state, $details);  // RELATIONSHIPS FORM  //---------------------------------------------  $relationship_cv = tripal_get_default_cv('pub_relationship', 'type_id');  $cv_id = $relationship_cv ? $relationship_cv->cv_id : NULL;  $details = array(    'relationship_table' => 'pub_relationship', // the name of the _relationship table    'base_table' => 'pub',                      // the name of your chado base table    'base_foreign_key' => 'pub_id',             // the name of the key in your base chado table    'base_key_value' => $pub_id,                // the value of pub_id for this record    'nodetype' => 'pub',                        // the human-readable name of your node type    'cv_id' => $cv_id,                          // the cv.cv_id of the cv containing the relationships    'base_name_field' => 'uniquename',          // the base table field you want to be used as the name  );  // Adds the form elements to your current form  chado_add_node_form_relationships($form, $form_state, $details);  // ADDITIONAL DBXREFS FORM  //---------------------------------------------  $details = array(    'linking_table' => 'pub_dbxref',  // the name of the _dbxref table    'base_foreign_key' => 'pub_id',   // the name of the key in your base chado table    'base_key_value' => $pub_id       // the value of pub_id for this record  );  // Adds the form elements to your current form  chado_add_node_form_dbxrefs($form, $form_state, $details);  return $form;}/** * Implements hook_validate(). * * @ingroup tripal_legacy_pub */function chado_pub_validate($node, $form, &$form_state) {  // We only want to validate when the node is saved.  // Since this validate can be called on AJAX and Deletion of the node  // we need to make this check to ensure queries are not executed  // without the proper values.  if(property_exists($node, "op") and $node->op != 'Save') {    return;  }  // we are syncing if we do not have a node ID but we do have a pub_id. We don't  // need to validate during syncing so just skip it.  if (!property_exists($node, 'nid') and property_exists($node, 'pub_id') and $node->pub_id != 0) {    return;  }  // get the submitted values  $title        = property_exists($node, 'pubtitle') ? trim($node->pubtitle) : '';  $pyear        = property_exists($node, 'pyear') ? trim($node->pyear) : '';  $uniquename   = property_exists($node, 'uniquename') ? trim($node->uniquename) : '';  $is_obsolete  = property_exists($node, 'is_obsolete') ? trim($node->is_obsolete) : 0;  $type_id      = property_exists($node, 'type_id') ? trim($node->type_id) : '';  $pub = array();  // make sure the year is four digits  if(!preg_match('/^\d{4}$/', $pyear)){    form_set_error('pyear', t('The publication year should be a 4 digit year.'));    return;  }  // get the type of publication  $values = array('cvterm_id' => $type_id);  $cvterm = chado_select_record('cvterm', array('name'), $values);  if (count($cvterm) == 0) {    $message = t('Invalid publication type.');    form_set_error('type_id', $message);    return;  }  // Get the media name looking at the properties  $series_name = '';  $properties = chado_retrieve_node_form_properties($node);  foreach ($properties as $key => $prop_values) {    $values = array('cvterm_id' => $key);    $prop_type = chado_select_record('cvterm', array('name'), $values);    if ($prop_type[0]->name == 'Conference Name' or        $prop_type[0]->name == 'Journal Name' or        $prop_type[0]->name == 'Series Name') {      $v = array_values($prop_values);      $series_name = $v[0];    }    if ($prop_type[0]->name == 'Citation') {      $v = array_values($prop_values);      $uniquename = $v[0];    }    if (count($prop_values) == 1) {      $v = array_values($prop_values);      $pub[$prop_type[0]->name] = $v[0];    }    else {      $pub[$prop_type[0]->name] = $prop_values;    }  }  // if the citation is missing then try to generate one  if (!$uniquename) {    $pub['Title'] = $title;    $pub['Publication Type'][0] = $cvterm[0]->name;    $pub['Year'] = $pyear;    $uniquename = tripal_pub_create_citation($pub);    if (!$uniquename) {      form_set_error('uniquename', "Cannot automatically generate a citation for this publication type. Please add one manually.");    }  }  $skip_duplicate_check = 0;  // if this publication is a Patent then skip the validation below.  Patents can have the title  // name and year but be different  if (strcmp($cvterm[0]->name,'Patent') == 0) {    $skip_duplicate_check = 1;  }  // Validating for an update  if (!is_null($node->nid)) {    $pub_id = $node->pub_id;    // check to see if a duplicate publication already exists    if (!$skip_duplicate_check) {      chado_pub_validate_check_duplicate($title, $pyear, $series_name, $cvterm[0], $pub_id);    }    chado_pub_validate_check_uniquename($uniquename, $pub_id);  }  // Validating for an insert  else {    chado_pub_validate_check_duplicate($title, $pyear, $series_name, $cvterm[0]);    chado_pub_validate_check_uniquename($uniquename);  }}/** * Validate the publication uniquename. To be called from hook_validate(). * * @param $uniquename *  The uniquename of the publication * @param $pub_id *  If an update, provide the pub_id so we don't check for a matching *  uniquename of the pub we are editing * * @ingroup tripal_legacy_pub */function chado_pub_validate_check_uniquename($uniquename, $pub_id = NULL) {  // check to see if a pub exists with this uniquename  $pub = tripal_get_publication(array('uniquename' => $uniquename));  if ($pub) {    // if a $pub_id is provided to the function then this is an update    // if the pub_id's don't match then a different pub with the same    // uniquename already exists.    if ($pub->pub_id != $pub_id) {      $message = t('A publication with this unique citation already exists.');      form_set_error('uniquename', $message);    }  }}/** * Check for duplicate publications. To be called from hook_validate().  Sets * the form error if a duplicate * * @param $title *   The title of the publication * @param $pyear *   The year the publication was published * @param $series_name *   The series name of the publication * @param $cvterm *   The type of publication * @param $pub_id *   the unique id of the publication * * * @ingroup tripal_legacy_pub */function chado_pub_validate_check_duplicate($title, $pyear, $series_name, $cvterm, $pub_id = NULL) {  $pub_details = array(    'Title' => $title,    'Year' => $pyear,    'Series Name' => $series_name,    'Publication Type' => $cvterm->name,  );  // TODO: need to include the Publication Dbxref in the $pub_details as well  $pub_ids = tripal_publication_exists($pub_details);  // if we found only one publication and it is our publication then return, we're good.  if (count($pub_ids) == 1 and in_array($pub_id, $pub_ids)) {    return;  }  if (count($pub_ids) == 0) {    // there is no match so return    return;  }  // return an appropriate message based on the unique constraint settings  $import_dups_check = variable_get('tripal_pub_import_duplicate_check', 'title_year_media');  switch ($import_dups_check) {    case 'title_year':      $message = t('A publication with this title and publication year already exists.');      form_set_error('pubtitle', $message);      break;    case 'title_year_type':      $message = t('A publication with this title, type and publication year already exists.');      form_set_error('pubtitle', $message);      break;    case 'title_year_media':      $message = t('A publication with this title, media name (e.g. Journal Name) and publication year already exists.');      form_set_error('pubtitle', $message);      break;  }}/** * Implement hook_node_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_legacy_pub */function tripal_pub_node_access($node, $op, $account) {  $node_type = $node;  if (is_object($node)) {    $node_type = $node->type;  }  if($node_type == 'chado_pub') {    if ($op == 'create') {      if (!user_access('create chado_pub content', $account)) {        return NODE_ACCESS_DENY;      }      return NODE_ACCESS_ALLOW;    }    if ($op == 'update') {      if (!user_access('edit chado_pub content', $account)) {        return NODE_ACCESS_DENY;      }    }    if ($op == 'delete') {      if (!user_access('delete chado_pub content', $account)) {        return NODE_ACCESS_DENY;      }    }    if ($op == 'view') {      if (!user_access('access chado_pub content', $account)) {        return NODE_ACCESS_DENY;      }    }    return NODE_ACCESS_IGNORE;  }}/** * Implements hook_insert(). * * @ingroup tripal_legacy_pub */function chado_pub_insert($node) {  $pub_id = '';  // if there is an pub_id in the $node object then this must be a sync so  // we can skip adding the pub as it is already there, although  // we do need to proceed with insertion into the chado/drupal linking table.  if (!property_exists($node, 'pub_id')) {    $node->pubtitle     = trim($node->pubtitle);    $node->pyear        = trim($node->pyear);    $node->uniquename   = trim($node->uniquename);    $is_obsolete  = $node->is_obsolete;    $type_id      = $node->type_id;    // we need an array suitable for the tripal_pub_create_citation() function    // to automatically generate a citation if a uniquename doesn't already exist    $pub_arr = array();    // Stores all of the properties we need to add.    $properties = array();    // Stores any cross references for this publication.    $cross_refs = array();    // get the properties from the form    $properties = chado_retrieve_node_form_properties($node);    // get the list of properties for easy lookup (without doing lots of database queries    $properties_list = array();    $sql = "      SELECT CVTS.cvterm_id, CVTS.name, CVTS.definition      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} ON CVTO.cv_id = CV.cv_id      WHERE CV.name = 'tripal_pub' and CVTO.name = 'Publication Details' and        NOT CVTS.is_obsolete = 1      ORDER BY CVTS.name ASC    ";    $prop_types = chado_query($sql);    while ($prop = $prop_types->fetchObject()) {      $properties_list[$prop->cvterm_id] = $prop->name;      // The 'Citation' term is special because it serves      // both as a property and as the uniquename for the      // pub and we want it stored in both the pub table and the pubprop table      if ($prop->name == 'Citation') {        $citation_id = $prop->cvterm_id;        if (!empty($node->uniquename)) {          $properties[$citation_id][0] = $node->uniquename;        }      }    }    // iterate through all of the properties and remove those that really are    // part of the pub table fields    $volume = '';    $volumetitle = '';    $issue = '';    $pages = '';    $publisher = '';    $series_name = '';    $pubplace = '';    $miniref = '';    $cross_refs = array();    foreach ($properties as $type_id => $element) {      foreach ($element as $index => $value) {        $name = $properties_list[$type_id];        // populate our $pub_array for building a citation        $pub_arr[$name] = $value;        // remove properties that are stored in the pub table        if ($name == "Volume") {          $volume = $value;          unset($properties[$type_id]);        }        elseif ($name == "Volume Title") {          $volumetitle = $value;          unset($properties[$type_id]);        }        elseif ($name == "Issue") {          $issue = $value;          unset($properties[$type_id]);        }        elseif ($name == "Pages") {          $pages = $value;          unset($properties[$type_id]);        }        elseif ($name == "Publisher") {          $publisher = $value;          unset($properties[$type_id]);        }        elseif ($name == "Series Name" or $name == "Journal Name" or $name == "Conference Name") {          $series_name = $value;          unset($properties[$type_id]);        }        elseif ($name == "Journal Country" or $name == "Published Location") {          $pubplace = $value;          // allow this property to go into the pubprop table so we don't loose info          // so don't unset it. But it will also go into the pub.pubplace field        }        elseif ($name == "Publication Dbxref") {          // we will add the cross-references to the pub_dbxref table          // but we also want to keep the property in the pubprop table so don't unset it          $cross_refs[] = $value;        }      }    }    // generate a citation for this pub if one doesn't already exist    if (!$node->uniquename and !array_key_exists($citation_id, $properties)) {      $pub_type = tripal_get_cvterm(array('cvterm_id' => $node->type_id));      $pub_arr['Title'] = $node->pubtitle;      $pub_arr['Publication Type'][0] = $pub_type->name;      $pub_arr['Year'] = $node->pyear;      $node->uniquename = tripal_pub_create_citation($pub_arr);      $properties[$citation_id][0] = $node->uniquename;    }    // insert the pub record    $values = array(      'title'       => $node->pubtitle,      'series_name' => substr($series_name, 0, 255),      'type_id'     => $node->type_id,      'pyear'       => $node->pyear,      'is_obsolete' => $node->is_obsolete ? 'true' : 'false',      'uniquename'  => $node->uniquename,      'volumetitle' => $volumetitle,      'volume'      => $volume,      'issue'       => $issue,      'pages'       => $pages,      'miniref'     => substr($miniref, 0, 255),      'publisher'   => substr($publisher, 0, 255),      'pubplace'    => substr($pubplace, 0, 255),    );    $pub = chado_insert_record('pub', $values);    if (!$pub) {      drupal_set_message("Error inserting publication", "error");      watchdog('tripal_pub', "Error inserting publication", array(), WATCHDOG_ERROR);      return;    }    $pub_id = $pub['pub_id'];    // now add in the properties    // Only adds in those not used in the pub record    $details = array(      'property_table' => 'pubprop',      'base_table' => 'pub',      'foreignkey_name' => 'pub_id',      'foreignkey_value' => $pub_id    );    chado_update_node_form_properties($node, $details, $properties);    // * Relationships Form *    $details = array(      'relationship_table' => 'pub_relationship',  // name of the _relationship table      'foreignkey_value' => $pub_id                // value of the pub_id key    );    chado_update_node_form_relationships($node, $details);    // add in any database cross-references    foreach ($cross_refs as $index => $ref) {      $dbxref = array();      if(preg_match('/^(.*?):(.*?)$/', trim($ref), $matches)) {        $dbxref['db_name']   = $matches[1];        $dbxref['accession'] = $matches[2];      }      $success = chado_associate_dbxref('pub', $pub['pub_id'], $dbxref);      if (!$success) {        drupal_set_message("Error cannot add publication cross reference: $ref", "error");        watchdog('tripal_pub', "Error cannot add publication cross reference: %ref",        array('%ref' => $ref), WATCHDOG_ERROR);      }    }    // * Additional DBxrefs Form *    $details = array(      'linking_table' => 'pub_dbxref',   // the name of your _dbxref table      'foreignkey_name' => 'pub_id',     // the name of the key in your base table      'foreignkey_value' => $pub_id      // the value of the pub_id key    );    chado_update_node_form_dbxrefs($node, $details);  }  else {    $pub_id = $node->pub_id;  }  // Make sure the entry for this pub doesn't already exist in the  // chado_pub table if it doesn't exist then we want to add it.  $check_org_id = chado_get_id_from_nid('pub', $node->nid);  if (!$check_org_id) {    $record = new stdClass();    $record->nid = $node->nid;    $record->vid = $node->vid;    $record->pub_id = $pub_id;    drupal_write_record('chado_pub', $record);  }}/** * 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 Publication. * 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_legacy_pub */function chado_pub_update($node) {  $node->pubtitle   = trim($node->pubtitle);  $node->pyear      = trim($node->pyear);  $node->uniquename = trim($node->uniquename);  $is_obsolete      = $node->is_obsolete;  $type_id          = $node->type_id;  // we need an array suitable for the tripal_pub_create_citation() function  // to automatically generate a citation if a uniquename doesn't already exist  $pub_arr = array();  // get the publication ID for this publication  $pub_id = chado_get_id_from_nid('pub', $node->nid) ;  $properties = array(); // stores all of the properties we need to add  $cross_refs = array(); // stores any cross references for this publication  // get the properties from the form  $properties = chado_retrieve_node_form_properties($node);  // get the list of properties for easy lookup (without doing lots of database queries  $properties_list = array();  $sql = "    SELECT DISTINCT CVTS.cvterm_id, CVTS.name, CVTS.definition    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} ON CVTO.cv_id = CV.cv_id    WHERE CV.name = 'tripal_pub' and      (CVTO.name = 'Publication Details' or CVTS.name = 'Publication Type') and      NOT CVTS.is_obsolete = 1    ORDER BY CVTS.name ASC  ";  $prop_types = chado_query($sql);  while ($prop = $prop_types->fetchObject()) {    $properties_list[$prop->cvterm_id] = $prop->name;    // The 'Citation' term is special because it serves    // both as a property and as the uniquename for the    // pub and we want it stored in both the pub table and the pubprop table    if ($prop->name == 'Citation') {      $citation_id = $prop->cvterm_id;      if (!empty($node->uniquename)) {        $properties[$citation_id][0] = $node->uniquename;      }    }  }  // iterate through all of the properties and remove those that really are  // part of the pub table fields  $volume = '';  $volumetitle = '';  $issue = '';  $pages = '';  $publisher = '';  $series_name = '';  $pubplace = '';  $miniref = '';  $cross_refs = array();  foreach ($properties as $type_id => $element) {    foreach ($element as $index => $value) {      $name = $properties_list[$type_id];      // populate our $pub_array for building a citation      $pub_arr[$name] = $value;      // remove properties that are stored in the pub table      if ($name == "Volume") {        $volume = $value;        unset($properties[$type_id]);      }      elseif ($name == "Volume Title") {        $volumetitle = $value;        unset($properties[$type_id]);      }      elseif ($name == "Issue") {        $issue = $value;        unset($properties[$type_id]);      }      elseif ($name == "Pages") {        $pages = $value;        unset($properties[$type_id]);      }      elseif ($name == "Publisher") {        $publisher = $value;        unset($properties[$type_id]);      }      elseif ($name == "Journal Name" or $name == "Conference Name") {        $series_name = $value;        unset($properties[$type_id]);      }      elseif ($name == "Journal Country" or $name == "Published Location") {        $pubplace = $value;        // allow this property to go into the pubprop table so we don't loose info        // so don't unset it. But it will also go into the pub.pubplace field      }      elseif ($name == "Publication Dbxref") {        // we will add the cross-references to the pub_dbxref table        // but we also want to keep the property in the pubprop table so don't unset it        $cross_refs[] = $value;      }    }  }  // generate a citation for this pub if one doesn't already exist  if (!$node->uniquename) {    $pub_type = tripal_get_cvterm(array('cvterm_id' => $node->type_id));    $pub_arr['Title'] = $node->pubtitle;    $pub_arr['Publication Type'][0] = $pub_type->name;    $pub_arr['Year'] = $node->pyear;    $node->uniquename = tripal_pub_create_citation($pub_arr);    $properties[$citation_id][0] = $node->uniquename;  }  // update the pub record  $match = array(    'pub_id' => $pub_id,  );  $values = array(    'title'       => $node->pubtitle,    'type_id'     => $node->type_id,    'pyear'       => $node->pyear,    'is_obsolete' => $node->is_obsolete ? 'true' : 'false',    'uniquename'  => $node->uniquename,    'series_name' => substr($series_name, 0, 255),    'volumetitle' => $volumetitle,    'volume'      => $volume,    'issue'       => $issue,    'pages'       => $pages,    'miniref'     => substr($miniref, 0, 255),    'publisher'   => substr($publisher, 0, 255),    'pubplace'    => substr($pubplace, 0, 255),  );  $status = chado_update_record('pub', $match, $values);  if (!$status) {    drupal_set_message("Error updating publication", "error");    watchdog('tripal_pub', "Error updating publication", array(), WATCHDOG_ERROR);    return;  }  // now add in the properties by first removing any the publication  // already has and adding the ones we have  $details = array(    'property_table'  => 'pubprop',    'base_table'      => 'pub',    'foreignkey_name' => 'pub_id',    'foreignkey_value'=> $pub_id  );  chado_update_node_form_properties($node, $details, $properties);  // * Relationships Form *  $details = array(    'relationship_table' => 'pub_relationship',  // name of the _relationship table    'foreignkey_value'   => $pub_id                // value of the pub_id key  );  chado_update_node_form_relationships($node, $details);  // add in any database cross-references after first removing  chado_delete_record('pub_dbxref', array('pub_id' => $pub_id));  foreach ($cross_refs as $index => $ref) {    $dbxref = array();    if(preg_match('/^(.*?):(.*?)$/', trim($ref), $matches)) {      $dbxref['db_name']   = $matches[1];      $dbxref['accession'] = $matches[2];    }    $success = chado_associate_dbxref('pub', $pub_id, $dbxref);    if (!$success) {      drupal_set_message("Error cannot add publication cross reference: $ref", "error");      watchdog('tripal_pub', "Error cannot add publication cross reference: %ref",      array('%ref' => $ref), WATCHDOG_ERROR);    }  }  // * Additional DBxrefs Form *  $details = array(    'linking_table' => 'pub_dbxref',   // the name of your _dbxref table    'foreignkey_name' => 'pub_id',     // the name of the key in your base table    'foreignkey_value' => $pub_id      // the value of the pub_id key  );  chado_update_node_form_dbxrefs($node, $details);}/** * Implements hook_load(). * * @param $node *   The node that is to be loaded * * @return $node *   The node with the information to be loaded into the database * * @ingroup tripal_legacy_pub */function chado_pub_load($nodes) {  foreach ($nodes as $nid => $node) {    // find the pub and add in the details    $pub_id = chado_get_id_from_nid('pub', $nid);    // if the nid does not have a matching record then skip this node.    // this can happen with orphaned nodes.    if (!$pub_id) {      continue;    }    // get the pub    $values = array('pub_id' => $pub_id);    $pub = chado_generate_var('pub', $values);    // expand the 'text' fields as those aren't included by default    // and they really shouldn't be so large to cause problems    $pub = chado_expand_var($pub, 'field', 'pub.title');    $pub = chado_expand_var($pub, 'field', 'pub.volumetitle');    $pub = chado_expand_var($pub, 'field', 'pub.uniquename');    // set the URL path    $nodes[$nid]->path = "pub/$pub_id";    $nodes[$nid]->pub = $pub;    // Now get the title    $node->title = chado_get_node_title($node);  }}/** * Implements hook_delete(). * * This function takes a node and if the delete button has been chosen by the user, the publication * and it's details will be removed.Following,given the node-ID, the instance will be deleted from * the 'chado_pub' table. * * @parm $node *    Then node to be deleted * * @ingroup tripal_legacy_pub */function chado_pub_delete(&$node) {  $pub_id = chado_get_id_from_nid('pub', $node->nid);  // if we don't have a pub id for this node then this isn't a node of  // type chado_pub or the entry in the chado_pub table was lost.  if (!$pub_id) {    return;  }  // Remove data from {chado_pub}, {node} and {node_revision} tables of  // drupal database  $sql_del = "DELETE FROM {chado_pub} 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 pub and pubprop tables of chado database as well  chado_query("DELETE FROM {pubprop} WHERE pub_id = :pub_id", array(':pub_id' => $pub_id));  chado_query("DELETE FROM {pub} WHERE pub_id = :pub_id", array(':pub_id' => $pub_id));}/** * Implements hook_node_view(). Acts on all content types. * * @ingroup tripal_legacy_pub */function tripal_pub_node_view($node, $view_mode, $langcode) {  switch ($node->type) {    case 'chado_pub':      // Show feature browser and counts      if ($view_mode == 'full') {        $node->content['tripal_pub_authors'] = array(          '#theme' => 'tripal_pub_authors',          '#node' => $node,          '#tripal_toc_id'    => 'authors',          '#tripal_toc_title' => 'Author Details',        );        $node->content['tripal_pub_base'] = array(          '#theme' => 'tripal_pub_base',          '#node' => $node,          '#tripal_toc_id'    => 'base',          '#tripal_toc_title' => 'Overview',          '#weight' => -100,        );        $node->content['tripal_pub_featuremaps'] = array(          '#theme' => 'tripal_pub_featuremaps',          '#node' => $node,          '#tripal_toc_id'    => 'featuremaps',          '#tripal_toc_title' => 'Maps',        );        $node->content['tripal_pub_features'] = array(          '#theme' => 'tripal_pub_features',          '#node' => $node,          '#tripal_toc_id'    => 'features',          '#tripal_toc_title' => 'Features',        );        $node->content['tripal_pub_libraries'] = array(          '#theme' => 'tripal_pub_libraries',          '#node' => $node,          '#tripal_toc_id'    => 'libraries',          '#tripal_toc_title' => 'Libraries',        );        $node->content['tripal_pub_projects'] = array(          '#theme' => 'tripal_pub_projects',          '#node' => $node,          '#tripal_toc_id'    => 'projects',          '#tripal_toc_title' => 'Projects',        );        $node->content['tripal_pub_properties'] = array(          '#theme' => 'tripal_pub_properties',          '#node' => $node,          '#tripal_toc_id'    => 'properties',          '#tripal_toc_title' => 'Properties',        );        $node->content['tripal_pub_references'] = array(          '#theme' => 'tripal_pub_references',          '#node' => $node,          '#tripal_toc_id'    => 'references',          '#tripal_toc_title' => 'Cross References',        );        $node->content['tripal_pub_relationships'] = array(          '#theme' => 'tripal_pub_relationships',          '#node' => $node,          '#tripal_toc_id'    => 'relationships',          '#tripal_toc_title' => 'Relationships',        );        $node->content['tripal_pub_stocks'] = array(          '#theme' => 'tripal_pub_stocks',          '#node' => $node,          '#tripal_toc_id'    => 'stocks',          '#tripal_toc_title' => 'Stocks',        );      }      if ($view_mode == 'teaser') {        $node->content['tripal_pub_teaser'] = array(          '#theme' => 'tripal_pub_teaser',          '#node' => $node,        );      }      break;  }}/** * Implements hook_node_insert(). Acts on all content types. * * We want the publications to always have a URL of http://[base url]/pub/[pub id] * where [pub id] is the Chado publication ID.  This will allow for easy linking * into the publication without needing to know the node.  Of course if you know the * node that will still work too (e.g. http://[base url]/node/[node id] * so the nodeapi function ensures that the URL path is set after insert or update * of the node and when the node is loaded if it hasn't yet been set. * * @ingroup tripal_legacy_pub */function tripal_pub_node_insert($node) {  if ($node->type == 'chado_pub') {    // get the pub    $pub_id = chado_get_id_from_nid('pub', $node->nid);    $values = array('pub_id' => $pub_id);    $pub = chado_generate_var('pub', $values);    // expand the 'text' fields as those aren't included by default    // and they really shouldn't be so large to cause problems    $pub = chado_expand_var($pub, 'field', 'pub.title');    $pub = chado_expand_var($pub, 'field', 'pub.volumetitle');    $pub = chado_expand_var($pub, 'field', 'pub.uniquename');    $node->pub = $pub;    // Now get the title    $node->title = chado_get_node_title($node);    tripal_pub_set_pub_url($node, $pub_id);  }}/** * Implements hook_node_load(). Acts on all content types. * * We want the publications to always have a URL of http://[base url]/pub/[pub id] * where [pub id] is the Chado publication ID.  This will allow for easy linking * into the publication without needing to know the node.  Of course if you know the * node that will still work too (e.g. http://[base url]/node/[node id] * so the nodeapi function ensures that the URL path is set after insert or update * of the node and when the node is loaded if it hasn't yet been set. * * @ingroup tripal_legacy_pub */function tripal_pub_node_load($nodes, $types) {  if (count(array_intersect(array('chado_pub'), $types))) {    foreach ($nodes as $nid => $node) {      if ($node->type == 'chado_pub' and !drupal_lookup_path('alias', 'node/' . $nid)) {        $pub_id = chado_get_id_from_nid('pub', $node->nid);        $path = tripal_pub_set_pub_url($node, $pub_id);      }    }  }}/** * Implements hook_node_update(). Acts on all content types. * * We want the publications to always have a URL of http://[base url]/pub/[pub id] * where [pub id] is the Chado publication ID.  This will allow for easy linking * into the publication without needing to know the node.  Of course if you know the * node that will still work too (e.g. http://[base url]/node/[node id] * so the nodeapi function ensures that the URL path is set after insert or update * of the node and when the node is loaded if it hasn't yet been set. * * @ingroup tripal_legacy_pub */function tripal_pub_node_update($node) {  if ($node->type == 'chado_pub') {    // get the pub    $pub_id = chado_get_id_from_nid('pub', $node->nid);    $values = array('pub_id' => $pub_id);    $pub = chado_generate_var('pub', $values);    // expand the 'text' fields as those aren't included by default    // and they really shouldn't be so large to cause problems    $pub = chado_expand_var($pub, 'field', 'pub.title');    $pub = chado_expand_var($pub, 'field', 'pub.volumetitle');    $pub = chado_expand_var($pub, 'field', 'pub.uniquename');    $node->pub = $pub;    // Now get the title    $node->title = chado_get_node_title($node);    tripal_pub_set_pub_url($node, $pub_id);  }}/** * Implements hook_node_presave(). Acts on all content types. * * @ingroup tripal_legacy_pub */function tripal_pub_node_presave($node) {  switch ($node->type) {    // This step is for setting the title for the Drupal node.  This title    // is permanent and thus is created to be unique.  Title changes provided    // by tokens are generated on the fly dynamically, but the node title    // seen in the content listing needs to be set here. Do not call    // the chado_get_node_title() function here to set the title as the node    // object isn't properly filled out and the function will fail.    case 'chado_pub':      // when syncing the details are not present in the $node object      // as they are when submitted via the form.  Therefore, if we do      // not see any field values from the form, we assume this fucntion      // is being called for syncing, so we must set the title accordingly      if (property_exists($node, 'title')) {        // do nothing, the title is set      }      else if (property_exists($node, 'pub')) {        // in Drupal a node title can only be 255 characters so we truncate        // it just in case        $node->title = substr($node->pub->title, 0, 255);      }      break;  }}/** * Implements [content_type]_chado_node_default_title_format(). * * Defines a default title format for the Chado Node API to set the titles on * Chado pub nodes based on chado fields. */function chado_pub_chado_node_default_title_format() {  return '[pub.title]';}/** * Implements [content_type]_chado_node_sync_select_query(). * * Adds a where clause to the query to exclude the NULL pub. */function chado_pub_chado_node_sync_select_query($query) {  $query['where_clauses']['title'][] = 'pub.title <> :pub_title_null';  $query['where_args']['title'][':pub_title_null'] = 'NULL';  return $query;}
 |