| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281 | <?php/** * @defgroup tripal_feature Feature * @{ * Provides functions for managing chado features including creating details pages for each feature * @} * @ingroup tripal_modules */ require_once "tripal_feature.admin.inc";require_once "syncFeatures.php";require_once "indexFeatures.php";require_once "fasta_loader.php";require_once "gff_loader.php";require_once "tripal_feature.api.inc";require_once "tripal_feature-delete.inc";require_once "tripal_feature-secondary_tables.inc";require_once "tripal_feature-properties.inc";require_once "tripal_feature-relationships.inc";require_once "tripal_feature-db_references.inc";/** * * @ingroup tripal_feature */function tripal_feature_init(){   // add the jGCharts JS and CSS   drupal_add_js (drupal_get_path('theme', 'tripal').'/js/tripal_feature.js');    drupal_add_js (drupal_get_path('theme', 'tripal').'/js/jgcharts/jgcharts.js');    drupal_add_css(drupal_get_path('theme', 'tripal').                                  '/css/tripal_feature.css');}/** * Implements hook_views_api() * * Purpose: Essentially this hook tells drupal that there is views support for *  for this module which then includes tripal_db.views.inc where all the *  views integration code is * * @ingroup tripal_feature */ function tripal_feature_views_api() {   return array(      'api' => 2.0,   );}/** * Display help and module information * * @param  *   path which path of the site we're displaying help * @param  *   arg array that holds the current path as would be returned from arg() function * * @return  *   help text for the path * * @ingroup tripal_feature */function tripal_feature_help($path, $arg) {   $output = '';   switch ($path) {      case "admin/help#tripal_feature":         $output='<p>'.t("Displays links to nodes created on this date").'</p>';         break;   }   return $output;}/** *  Provide information to drupal about the node types that we're creating *  in this module * * @ingroup tripal_feature */function tripal_feature_node_info() {   $nodes = array();   $nodes['chado_feature'] = array(      'name' => t('Feature'),      'module' => 'chado_feature',      'description' => t('A feature from the chado database'),      'has_title' => FALSE,      'title_label' => t('Feature'),      'has_body' => FALSE,      'body_label' => t('Feature Description'),      'locked' => TRUE   );   return $nodes;}/** *  Set the permission types that the chado module uses.  Essentially we *  want permissionis that protect creation, editing and deleting of chado *  data objects * * @ingroup tripal_feature */function tripal_feature_perm(){   return array(      'access chado_feature content',      'create chado_feature content',      'delete chado_feature content',      'edit chado_feature content',      'manage chado_feature aggregator',   );}/** *  Set the permission types that the module uses. * * @ingroup tripal_feature */function chado_feature_access($op, $node, $account) {	if ($op == 'create') {		if(!user_access('create chado_feature content', $account)){			return FALSE;      }	}	if ($op == 'update') {		if (!user_access('edit chado_feature content', $account)) {			return FALSE;		}	}	if ($op == 'delete') {		if (!user_access('delete chado_feature content', $account)) {			return FALSE;		}	}	if ($op == 'view') {		if(!user_access('access chado_feature content', $account)){         return FALSE;      }	}   return NULL;}/** *  Menu items are automatically added for the new node types created *  by this module to the 'Create Content' Navigation menu item.  This function *  adds more menu items needed for this module. * * @ingroup tripal_feature */function tripal_feature_menu() {   $items = array();   // the administative settings menu   $items['admin/tripal/tripal_feature'] = array(     'title' => 'Features',     'description' => 'Basic Description of Tripal Organism Module Functionality',     'page callback' => 'tripal_feature_module_description_page',     'access arguments' => array('administer site configuration'),     'type' => MENU_NORMAL_ITEM,   );   $items['admin/tripal/tripal_feature/configuration'] = array(     'title' => 'Feature Configuration',     'description' => 'Settings for Chado Features',     'page callback' => 'drupal_get_form',     'page arguments' => array('tripal_feature_admin'),     'access arguments' => array('administer site configuration'),     'type' => MENU_NORMAL_ITEM,   );   $items['admin/tripal/tripal_feature/fasta_loader'] = array(     'title' => 'Import a multi-FASTA file',     'description' => 'Load sequences from a multi-FASTA file into Chado',     'page callback' => 'drupal_get_form',     'page arguments' => array('tripal_feature_fasta_load_form'),     'access arguments' => array('administer site configuration'),     'type' => MENU_NORMAL_ITEM,   );   $items['admin/tripal/tripal_feature/gff3_load'] = array(     'title' => 'Import a GFF3 file',     'description' => 'Import a GFF3 file into Chado',     'page callback' => 'drupal_get_form',     'page arguments' => array('tripal_feature_gff3_load_form'),     'access arguments' => array('access administration pages'),     'type' => MENU_NORMAL_ITEM,   );     $items['admin/tripal/tripal_feature/delete'] = array(     'title' => ' Delete Features',     'description' => 'Delete multiple features from Chado',     'page callback' => 'drupal_get_form',     'page arguments' => array('tripal_feature_delete_form'),     'access arguments' => array('access administration pages'),     'type' => MENU_NORMAL_ITEM,   );    $items['admin/tripal/tripal_feature/sync'] = array(     'title' => ' Sync Features',     'description' => 'Sync features from Chado with Drupal',     'page callback' => 'drupal_get_form',     'page arguments' => array('tripal_feature_sync_form'),     'access arguments' => array('access administration pages'),     'type' => MENU_NORMAL_ITEM,   );   // Adding Secondary Properties  /**  $items['node/%tf_node/tf_properties'] = array(           'title' => t('Add Properties & Synonyms'),                             'description' => t('Settings for Features'),    'page callback' => 'tripal_feature_add_ALL_property_page',               'page arguments' => array(1),     'access arguments' => array('create chado_feature content'),    'type' => MENU_CALLBACK  );   $items['node/%tf_node/tf_db_references'] = array(                            'title' => t('Add Database References'),                       'description' => t('Settings for Features'),                  'page callback' => 'tripal_feature_add_ALL_dbreferences_page',                             'page arguments' => array(1),    'access arguments' => array('create chado_feature content'),    'type' => MENU_CALLBACK  );   $items['node/%tf_node/tf_relationships'] = array(                          'title' => t('Add Relationships'),                          'description' => t('Settings for Features'),                   'page callback' => 'tripal_feature_add_ALL_relationships_page',                              'page arguments' => array(1),    'access arguments' => array('create chado_feature content'),    'type' => MENU_CALLBACK  );  */    //Edit/Deleting Secondary Properties-------------  $items['node/%tf_node/edit_feature_properties'] = array(    'title' => t('Edit Properties'),    'description' => t('Settings for Features'),    'page callback' => 'tripal_feature_edit_ALL_properties_page',    'page arguments' => array(1),    'access arguments' => array('edit chado_feature content'),    'type' => MENU_LOCAL_TASK,    'weight' => 8,  );/**    $items['node/%tf_node/tf_edit_relationships'] = array(    'title' => t('Edit Relationships'),    'description' => t('Settings for Feature'),     'page callback' => 'tripal_feature_edit_ALL_relationships_page',    'page arguments' => array(1),    'access arguments' => array('edit chado_feature content'),    'type' => MENU_LOCAL_TASK,    'weight' => 9,  );*/  $items['node/%tf_node/tf_edit_db_references'] = array(    'title' => t('Edit References'),    'description' => t('Settings for Feature'),    'page callback' => 'tripal_feature_edit_ALL_dbreferences_page',    'page arguments' => array(1),    'access arguments' => array('edit chado_feature content'),    'type' => MENU_LOCAL_TASK,    'weight' => 10,  ); // managing relationship aggregates   $items['admin/tripal/tripal_feature/aggregate'] = array(     'title' => 'Feature Relationship Aggegators',     'description' => t('Features have relationships with other features and it may be desirable to aggregate the content from one ore more child or parent feature.'),     'page callback' => 'tripal_feature_aggregator_page',     'access arguments' => array('manage chado_feature aggregator'),     'type' => MENU_NORMAL_ITEM,   );   $items['admin/tripal/tripal_feature/aggregate/new'] = array(     'title' => 'Add an Aggregator',     'page callback' => 'drupal_get_form',     'page arguments' => array('tripal_feature_aggregator_form'),     'access arguments' => array('manage chado_feature aggregator'),     'type' => MENU_NORMAL_ITEM,   );   $items['admin/tripal/tripal_feature/aggregate/edit/js'] = array(     'title' => 'Edit an Aggegator',     'page callback' => 'tripal_feature_aggregator_ajax_edit',     'access arguments' => array('manage chado_feature aggregator'),     'type' => MENU_CALLBACK,   );   return $items;}/** * Implements Menu wildcard_load hook * Purpose: Allows the node ID of a chado feature to be dynamically  *   pulled from the path. The node is loaded from this node ID *   and supplied to the page as an arguement * * @ingroup tripal_feature */function tf_node_load($nid) {  if (is_numeric($nid)) {    $node = node_load($nid);    if ($node->type == 'chado_feature') {      return $node;    }  }  return FALSE;}/** * * * @ingroup tripal_feature */function tripal_feature_block($op = 'list', $delta = 0, $edit=array()){   switch($op) {      case 'list':         $blocks['references']['info'] = t('Tripal Feature References');         $blocks['references']['cache'] = BLOCK_NO_CACHE;         $blocks['base']['info'] = t('Tripal Feature Details');         $blocks['base']['cache'] = BLOCK_NO_CACHE;         $blocks['sequence']['info'] = t('Tripal Feature Sequence');         $blocks['sequence']['cache'] = BLOCK_NO_CACHE;         $blocks['synonyms']['info'] = t('Tripal Feature Synonyms');         $blocks['synonyms']['cache'] = BLOCK_NO_CACHE;         $blocks['properties']['info'] = t('Tripal Feature Properties');         $blocks['properties']['cache'] = BLOCK_NO_CACHE;;         $blocks['featureloc_sequences']['info'] = t('Tripal Formatted Sequence');         $blocks['featureloc_sequences']['cache'] = BLOCK_NO_CACHE;         $blocks['alignments']['info'] = t('Tripal Feature Alignments');         $blocks['alignments']['cache'] = BLOCK_NO_CACHE;         $blocks['relationships']['info'] = t('Tripal Feature Relationships');         $blocks['relationships']['cache'] = BLOCK_NO_CACHE;         $blocks['org_feature_counts']['info'] = t('Tripal Organism Feature Counts');         $blocks['org_feature_counts']['cache'] = BLOCK_NO_CACHE;         $blocks['org_feature_browser']['info'] = t('Tripal Organism Feature Browser');         $blocks['org_feature_browser']['cache'] = BLOCK_NO_CACHE;         $blocks['library_feature_browser']['info'] = t('Tripal Library Feature Browser');         $blocks['library_feature_browser']['cache'] = BLOCK_NO_CACHE;         return $blocks;      case 'view':         if(user_access('access chado_feature content') and arg(0) == 'node' and is_numeric(arg(1))) {            $nid = arg(1);            $node = node_load($nid);             $block = array();            switch($delta){               case 'references':                  $block['subject'] = t('References');                  $block['content'] = theme('tripal_feature_references',$node);                  break;               case 'base':                  $block['subject'] = t('Feature Details');                  $block['content'] = theme('tripal_feature_base',$node);                  break;               case 'synonyms':                  $block['subject'] = t('Synonyms');                  $block['content'] = theme('tripal_feature_synonyms',$node);                  break;               case 'properties':                  $block['subject'] = t('Properties');                  $block['content'] = theme('tripal_feature_properties',$node);                  break;;               case 'sequence':                  $block['subject'] = t('Sequence');                  $block['content'] = theme('tripal_feature_sequence',$node);                  break;               case 'featureloc_sequences':                  $block['subject'] = t('Formatted Sequences');                  $block['content'] = theme('tripal_feature_featureloc_sequences',$node);                  break;               case 'alignments':                  $block['subject'] = t('Alignments');                  $block['content'] = theme('tripal_feature_featurelocs',$node);                  break;               case 'relationships':                  $block['subject'] = t('Relationships');                  $block['content'] = theme('tripal_feature_relationships',$node);                  break;               case 'org_feature_counts':                  $block['subject'] = t('Feature Type Summary');                  $block['content'] = theme('tripal_organism_feature_counts', $node);                  break;               case 'org_feature_browser':                  $block['subject'] = t('Feature Browser');                  $block['content'] = theme('tripal_organism_feature_browser', $node);                  break;               case 'library_feature_browser':                  $block['subject'] = t('Library Feature Browser');                  $block['content'] = theme('tripal_library_feature_browser', $node);                  break;               default :            }            return $block;         }   }}/** *  When a new chado_feature node is created we also need to add information *  to our chado_feature table.  This function is called on insert of a new node *  of type 'chado_feature' and inserts the necessary information. * * @ingroup tripal_feature */function chado_feature_insert($node){   // remove spaces, newlines from residues   $residues = preg_replace("/[\n\r\s]/","",$node->residues);   $obsolete = 'FALSE';   if($node->is_obsolete){      $obsolete = 'TRUE';   }   $values = array(      'cv_id' => array(         'name' => 'sequence'      ),      'name' => $node->feature_type   );   $type = tripal_core_chado_select('cvterm',array('cvterm_id'),$values);   $values = array(      'organism_id' => $node->organism_id,      'name' => $node->fname,      'uniquename' => $node->uniquename,      'residues' => $residues,      'seqlen' => strlen($residues),      'is_obsolete' => $obsolete,      'type_id' => $type[0]->cvterm_id,      'md5checksum' => md5($residues)   );   $istatus = tripal_core_chado_insert('feature', $values);   if (!$istatus) {		drupal_set_message('Unable to add feature.', 'warning');		watchdog('tripal_organism', 			'Insert feature: Unable to create feature where values: %values', 			array('%values' => print_r($values, TRUE)),			WATCHDOG_WARNING		);	}     $values = array(      'organism_id' => $node->organism_id,      'uniquename' => $node->uniquename,      'type_id' => $type[0]->cvterm_id,   );   $feature = tripal_core_chado_select('feature',array('feature_id'),$values);      // add the genbank accession and synonyms   chado_feature_add_synonyms($node->synonyms,$feature[0]->feature_id);   // make sure the entry for this feature doesn't already exist in the chado_feature table   // if it doesn't exist then we want to add it.   $node_check_sql = "SELECT * FROM {chado_feature} ".                     "WHERE feature_id = '%s'";   $node_check = db_fetch_object(db_query($node_check_sql,$feature[0]->feature_id));   if(!$node_check){      // next add the item to the drupal table      $sql = "INSERT INTO {chado_feature} (nid, vid, feature_id, sync_date) ".             "VALUES (%d, %d, %d, " . time() . ")";      db_query($sql,$node->nid,$node->vid,$feature[0]->feature_id);   }}/** * * * @ingroup tripal_feature */function chado_feature_update($node){   if($node->revision){      // TODO -- decide what to do about revisions   } else {      $residues = preg_replace("/[\n\r\s]/","",$node->residues);      $obsolete = 'FALSE';      if($node->is_obsolete){         $obsolete = 'TRUE';      }      // get the feature type id      $values = array(         'cv_id' => array(            'name' => 'sequence'         ),         'name' => $node->feature_type      );      $type = tripal_core_chado_select('cvterm',array('cvterm_id'),$values);      $feature_id = chado_get_id_for_node('feature',$node) ;      if(sizeof($type) > 0){         $match = array(            'feature_id' => $feature_id,         );              $values = array(            'organism_id' => $node->organism_id,            'name' => $node->fname,            'uniquename' => $node->uniquename,            'residues' => $residues,            'seqlen' => strlen($residues),            'is_obsolete' => $obsolete,            'type_id' => $type[0]->cvterm_id,            'md5checksum' => md5($residues)         );         $status = tripal_core_chado_update('feature', $match,$values);          // add the genbank synonyms         chado_feature_add_synonyms($node->synonyms,$feature_id);      }          else {		   drupal_set_message('Unable to update feature.', 'warning');		   watchdog('tripal_organism', 			   'Update feature: Unable to update feature where values: %values', 			   array('%values' => print_r($values, TRUE)),			   WATCHDOG_WARNING		   );      }   }}/** * * * @ingroup tripal_feature */function chado_feature_delete($node){   $feature_id  = chado_get_id_for_node('feature',$node);   // remove the drupal content     $sql_del = "DELETE FROM {chado_feature} ".              "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);   $sql_del = "DELETE FROM {node_revisions} ".              "WHERE nid = %d ".              "AND vid = %d";   db_query($sql_del, $node->nid, $node->vid);   // Remove data from feature tables of chado database.  This will   // cause a cascade delete and remove all data in referencing tables   // for this feature   $previous_db = tripal_db_set_active('chado');   db_query("DELETE FROM {feature} WHERE feature_id = %d", $feature_id);   tripal_db_set_active($previous_db);      drupal_set_message("The feature and all associated data were removed from ".      "chado");}/** * * * @ingroup tripal_feature */function chado_feature_add_synonyms($synonyms,$feature_id){   // make sure we only have a single space between each synonym   $synonyms = preg_replace("/[\s\n\r]+/"," ",$synonyms);   // split the synonyms into an array based on a space as the delimieter   $syn_array = array();   $syn_array = explode(" ",$synonyms);   // use the chado database   $previous_db = tripal_db_set_active('chado');   // remove any old synonyms   $feature_syn_dsql = "DELETE FROM {feature_synonym} WHERE feature_id = %d";   if(!db_query($feature_syn_dsql,$feature_id)){      $error .= "Could not remove synonyms from feature. ";   }   // return if we don't have any synonmys to add   if(!$synonyms){      tripal_db_set_active($previous_db);      return;   }   // iterate through each synonym and add it to the database   foreach($syn_array as $syn){      // skip this item if it's empty      if(!$syn){ break; }      // check to see if we have this accession number already in the database      // if so then don't add it again. it messes up drupal if the insert fails.      // It is possible for the accession number to be present and not the feature      $synonym_sql = "SELECT synonym_id FROM {synonym} ".                     "WHERE name = '%s'";      $synonym = db_fetch_object(db_query($synonym_sql,$syn));      if(!$synonym){         $synonym_isql = "INSERT INTO {synonym} (name,synonym_sgml,type_id) ".                         "VALUES ('%s','%s', ".                         "   (SELECT cvterm_id ".                         "    FROM {CVTerm} CVT ".                         "    INNER JOIN CV ON CVT.cv_id = CV.cv_id ".                         "    WHERE CV.name = 'feature_property' and CVT.name = 'synonym'))";         if(!db_query($synonym_isql,$syn,$syn)){            $error .= "Could not add synonym. ";         }         // now get the synonym we just added         $synonym_sql = "SELECT synonym_id FROM {synonym} ".                        "WHERE name = '%s'";         $synonym = db_fetch_object(db_query($synonym_sql,$syn));      }      // now add in our new sysnonym      $feature_syn_isql = "INSERT INTO {feature_synonym} (synonym_id,feature_id,pub_id) ".                          "VALUES (%d,%d,1)";      if(!db_query($feature_syn_isql,$synonym->synonym_id,$feature_id)){         $error .= "Could not add synonyms to feature. ";      }   }   // return to the drupal database   tripal_db_set_active($previous_db);   return $error;}/** * * * @ingroup tripal_feature */function chado_feature_add_gbaccession($accession,$feature_id){   // use chado database   $previous_db = tripal_db_set_active('chado');   // remove any old accession from genbank dbEST   $fdbxref_dsql = "DELETE FROM {feature_dbxref} ".                   "WHERE feature_id = %d and dbxref_id IN ".                   "   (SELECT DBX.dbxref_id FROM {dbxref} DBX ".                   "    INNER JOIN DB  ON DB.db_id = DBX.db_id ".                   "    INNER JOIN feature_dbxref FDBX ON DBX.dbxref_id = FDBX.dbxref_id ".                   "    WHERE DB.name = 'DB:Genbank' and FDBX.feature_id = %d)";   if(!db_query($fdbxref_dsql,$feature_id,$feature_id)){      $error .= "Could not remove accession from feature. ";   }   // if we don't have an accession number to add then just return   if(!$accession){      tripal_db_set_active($previous_db);      return;   }   // get the db_id   $db_sql = "SELECT db_id FROM {DB} ".             "WHERE name = 'DB:Genbank_est'";   $db = db_fetch_object(db_query($db_sql));   // check to see if we have this accession number already in the database   // if so then don't add it again. it messes up drupal if the insert fails.   // It is possible for the accession number to be present and not the feature   $dbxref_sql = "SELECT dbxref_id FROM {dbxref} ".                 "WHERE db_id = %d and accession = '%s'";   $dbxref = db_fetch_object(db_query($dbxref_sql,$db->db_id,$accession));   if(!$dbxref){      // add the accession number      $dbxref_isql = "INSERT INTO {dbxref} (db_id,accession) ".                     "  VALUES (%d, '%s') ";      if(!db_query($dbxref_isql,$db->db_id,$accession)){         $error .= 'Could not add accession as a database reference ';      }      // get the dbxref_id for the just added accession number      $dbxref_sql = "SELECT dbxref_id FROM {dbxref} ".                    "WHERE db_id = %d and accession = '%s'";      $dbxref = db_fetch_object(db_query($dbxref_sql,$db->db_id,$accession));   }   // associate the accession number with the feature   $feature_dbxref_isql = "INSERT INTO {feature_dbxref} (feature_id,dbxref_id) ".                          "  VALUES (%d, %d) ";   if(!db_query($feature_dbxref_isql,$feature_id,$dbxref->dbxref_id)){      $error .= 'Could not add feature database reference. ';   }   tripal_db_set_active($previous_db);   return $error;}/** * * * @ingroup tripal_feature */function chado_feature_form ($node,$param){   $type = node_get_types('type', $node);   $form = array();   $feature = $node->feature;   // add the residues to the feature object   $feature = tripal_core_expand_chado_vars($feature,'field','feature.residues');   // if the node has synonyms then use that as the form may be returning   // from an error.  Otherwise try to find synonyms from the database   $synonyms = $node->synonyms;   $feature = tripal_core_expand_chado_vars($feature,'table','feature_synonym');   $feature_synonyms = $feature->feature_synonym;   if(!$synonyms){      if (!is_array($feature_synonyms)) {         $synonyms = $feature_synonyms->synonym_id->name;      }       elseif(is_array($feature_synonyms)) {          foreach($feature_synonyms as $index => $synonym){            $synonyms .= $synonym->synonym_id->name ."\n";         }      }   }   $analyses = $node->analyses;   $references = $node->references;   // We need to pass above variables for preview to show   $form['feature'] = array(      '#type' => 'value',      '#value' => $feature   );   // This field is read when previewing a node   $form['synonyms'] = array(      '#type' => 'value',      '#value' => $synonyms   );   // This field is read when previewing a node   $form['analyses'] = array(      '#type' => 'value',      '#value' => $analyses   );   // This field is read when previewing a node   $form['references'] = array(      '#type' => 'value',      '#value' => $references   );   // keep track of the feature id if we have one.  If we do have one then   // this would indicate an update as opposed to an insert.   $form['feature_id'] = array(      '#type' => 'value',      '#value' => $feature->feature_id,   );   $form['title']= array(      '#type' => 'textfield',      '#title' => t('Title'),      '#required' => TRUE,      '#default_value' => $node->title,      '#description' => t('The title must be a unique identifier for this feature.  It is recommended to use a combination of uniquename, organism and feature type in the title as this is guranteed to be unique.'),      '#weight' => 1,      '#maxlength' => 255   );   $form['uniquename']= array(      '#type' => 'textfield',      '#title' => t('Unique Feature Name'),      '#required' => TRUE,      '#default_value' => $feature->uniquename,      '#description' => t('Enter a unique name for this feature.  This name must be unique for the organism and feature type.'),      '#weight' => 1,      '#maxlength' => 255   );   $form['fname']= array(      '#type' => 'textfield',      '#title' => t('Feature Name'),      '#required' => TRUE,      '#default_value' => $feature->name,      '#description' => t('Enter the name used by humans to refer to this feature.'),      '#weight' => 1,      '#maxlength' => 255   );   // get the list of supported feature types   $ftypes = array();   $ftypes[''] = '';   $supported_ftypes = split("[ \n]",variable_get('tripal_feature_type_setting','gene mRNA EST contig'));   foreach($supported_ftypes as $ftype){      $ftypes["$ftype"] = $ftype;   }   $form['feature_type'] = array (     '#title'       => t('Feature Type'),     '#type'        => t('select'),     '#description' => t("Choose the feature type."),     '#required'    => TRUE,     '#default_value' => $feature->type_id->name,     '#options'     => $ftypes,     '#weight'      => 2   );   // get the list of organisms   $sql = "SELECT * FROM {Organism} ORDER BY genus, species";   $previous_db = tripal_db_set_active('chado');  // use chado database   $org_rset = db_query($sql);   tripal_db_set_active($previous_db);  // now use drupal database   //   $organisms = array();   $organisms[''] = '';   while($organism = db_fetch_object($org_rset)){      $organisms[$organism->organism_id] = "$organism->genus $organism->species ($organism->common_name)";   }   $form['organism_id'] = array (     '#title'       => t('Organism'),     '#type'        => t('select'),     '#description' => t("Choose the organism with which this feature is associated "),     '#required'    => TRUE,     '#default_value' => $feature->organism_id->organism_id,     '#options'     => $organisms,     '#weight'      => 3,   );   // Get synonyms   if ($synonyms) {      if (is_array($synonyms)) {         foreach ($synonyms as $synonym){            $syn_text .= "$synonym->name\n";         }      } else {         $syn_text = $synonyms;      }   }   $form['synonyms']= array(      '#type' => 'textarea',      '#title' => t('Synonyms'),      '#required' => FALSE,      '#default_value' => $syn_text,      '#description' => t('Enter alternate names (synonmys) for this feature to help in searching and identification. You may enter as many alternate names as needed separated by spaces or on different lines.'),      '#weight' => 5,   );   $form['residues']= array(      '#type' => 'textarea',      '#title' => t('Residues'),      '#required' => FALSE,      '#default_value' => $feature->residues,      '#description' => t('Enter the nucelotide sequences for this feature'),      '#weight' => 6   );   $checked = '';   if($feature->is_obsolete == 't'){      $checked = '1';   }   $form['is_obsolete']= array(      '#type' => 'checkbox',      '#title' => t('Is Obsolete'),      '#required' => FALSE,      '#default_value' => $checked,      '#description' => t('Check this box if this sequence should be retired and no longer included in further analysis.'),      '#weight' => 8   );   return $form;}/** * * * @ingroup tripal_feature */function chado_feature_validate($node){   $result = 0;   // if this is an update, we want to make sure that a different feature for   // the organism doesn't already have this uniquename. We don't want to give   // two sequences the same uniquename   if($node->feature_id){      $sql = "SELECT *               FROM {Feature} F                INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id              WHERE uniquename = '%s'                AND organism_id = %d AND CVT.name = '%s' AND NOT feature_id = %d";      $previous_db = tripal_db_set_active('chado');      $result = db_fetch_object(db_query($sql, $node->uniquename,$node->organism_id,$node->feature_type,$node->feature_id));      tripal_db_set_active($previous_db);      if($result){         form_set_error('uniquename',t("Feature update cannot proceed. The feature name '$node->uniquename' is not unique for this organism. Please provide a unique name for this feature. "));      }   }   // if this is an insert then we just need to make sure this name doesn't   // already exist for this organism if it does then we need to throw an error   else {      $sql = "SELECT *               FROM {Feature} F                INNER JOIN {cvterm} CVT ON F.type_id = CVT.cvterm_id              WHERE uniquename = '%s'                AND organism_id = %d AND CVT.name = '%s'";      $previous_db = tripal_db_set_active('chado');      $result = db_fetch_object(db_query($sql, $node->uniquename,$node->organism_id,$node->feature_type));      tripal_db_set_active($previous_db);      if($result){         form_set_error('uniquename',t("Feature insert cannot proceed. The feature name '$node->uniquename' already exists for this organism. Please provide a unique name for this feature. "));      }   }   // we want to remove all characters except IUPAC nucleotide characters from the   // the residues. however, residues are not required so if blank then we'll skip   // this step   if($node->residues){      $residues = preg_replace("/[^\w]/",'',$node->residues);      if(!preg_match("/^[ACTGURYMKSWBDHVN]+$/i",$residues)){         form_set_error('residues',t("The residues in feature $node->name contains more than the nucleotide IUPAC characters. Only the following characters are allowed: A,C,T,G,U,R,Y,M,K,S,W,B,D,H,V,N: '" . $residues ."'"));      }   }   // we don't allow a genbank accession number for a contig   if($node->feature_type == 'contig' and $node->gbaccession){      form_set_error('gbaccession',t("Contigs cannot have a genbank accession number.  Please change the feature type or remove the accession number"));   }}/** *  When a node is requested by the user this function is called to allow us *  to add auxiliary data to the node object. * * @ingroup tripal_feature */function chado_feature_load($node){   // get the feature details from chado   $feature_id = chado_get_id_for_node('feature',$node);   $values = array('feature_id' => $feature_id);   $feature = tripal_core_generate_chado_var('feature',$values);   $additions->feature = $feature;   return $additions;}/** *   * * @ingroup tripal_feature */function tripal_feature_load_organism ($organism_id){   // add organism details   $sql = "SELECT * FROM {organism} WHERE organism_id = %d";   $previous_db = tripal_db_set_active('chado');  // use chado database   $organism = db_fetch_object(db_query($sql,$organism_id));   tripal_db_set_active($previous_db);  // now use drupal database   return $organism;}/** *   * * @ingroup tripal_feature */function tripal_feature_load_synonyms ($feature_id){   $sql = "SELECT S.name ".          "FROM {Feature_Synonym} FS ".          "  INNER JOIN {Synonym} S ".          "    ON FS.synonym_id = S.Synonym_id ".          "WHERE FS.feature_id = %d ".          "ORDER BY S.name ";   $previous_db = tripal_db_set_active('chado');  // use chado database   $results = db_query($sql,$feature_id);   tripal_db_set_active($previous_db);  // now use drupal database   $synonyms = array();   $i=0;   while($synonym = db_fetch_object($results)){      $synonyms[$i++] = $synonym;   }   return $synonyms;}/** *  * * @ingroup tripal_feature */function tripal_feature_load_properties ($feature_id){   $sql = "SELECT CVT.name as cvname, FS.type_id, FS.value, FS.rank,             CVT.definition, CVT.is_obsolete,              DBX.dbxref_id,DBX.accession,DB.name as dbname,              DB.urlprefix, DB.description as db_description, DB.url           FROM {featureprop} FS              INNER JOIN {cvterm} CVT ON FS.type_id = CVT.cvterm_id             INNER JOIN {dbxref} DBX ON CVT.dbxref_id = DBX.dbxref_id             INNER JOIN {db} DB      ON DB.db_id = DBX.db_id           WHERE FS.feature_id = %d           ORDER BY FS.rank ASC";   $previous_db = tripal_db_set_active('chado');  // use chado database   $results = db_query($sql,$feature_id);   tripal_db_set_active($previous_db);  // now use drupal database   $i=0;   $properties = array();   while($property = db_fetch_object($results)){      $properties[$i++] = $property;   }   return $properties;}/** *   * * @ingroup tripal_feature */function tripal_feature_load_references ($feature_id){   $sql = "SELECT F.uniquename,F.Feature_id,DBX.accession,DB.description as dbdesc, ".          "   DB.db_id, DB.name as db_name, DB.urlprefix,DBX.dbxref_id ".          "FROM {feature} F ".          "  INNER JOIN {feature_dbxref} FDBX on F.feature_id = FDBX.feature_id ".          "  INNER JOIN {dbxref} DBX on DBX.dbxref_id = FDBX.dbxref_id ".          "  INNER JOIN {db} on DB.db_id = DBX.db_id ".          "WHERE F.feature_id = %d ".          "ORDER BY DB.name ";   $previous_db = tripal_db_set_active('chado');  // use chado database   $results = db_query($sql,$feature_id);   tripal_db_set_active($previous_db);  // now use drupal database   $references = array();   $i=0;   while($accession = db_fetch_object($results)){      $references[$i++] = $accession;   }   return $references;}/** *   * * @ingroup tripal_feature */function tripal_feature_load_featurelocs ($feature_id,$side = 'as_parent',$aggregate = 1){   $sql = "SELECT              F.name, F.feature_id, F.uniquename,             FS.name as src_name,              FS.feature_id as src_feature_id,              FS.uniquename as src_uniquename,             CVT.name as cvname, CVT.cvterm_id,             CVTS.name as src_cvname, CVTS.cvterm_id as src_cvterm_id,             FL.fmin, FL.fmax, FL.is_fmin_partial, FL.is_fmax_partial,FL.strand,              FL.phase           FROM {featureloc} FL              INNER JOIN {feature} F on FL.feature_id = F.feature_id              INNER JOIN {feature} FS on FS.feature_id = FL.srcfeature_id              INNER JOIN {cvterm} CVT on F.type_id = CVT.cvterm_id              INNER JOIN {cvterm} CVTS on FS.type_id = CVTS.cvterm_id           ";   if(strcmp($side,'as_parent')==0){      $sql .= "WHERE FL.srcfeature_id = %d ";   }   if(strcmp($side,'as_child')==0){      $sql .= "WHERE FL.feature_id = %d ";   }   $previous_db = tripal_db_set_active('chado');  // use chado database   $flresults = db_query($sql, $feature_id);   tripal_db_set_active($previous_db);  // now use drupal database    // copy the results into an array   $i=0;   $featurelocs = array();   while($loc = db_fetch_object($flresults)){      // if a drupal node exists for this feature then add the nid to the      // results object      $sql = 'SELECT nid FROM {chado_feature} WHERE feature_id = %d';      $ffeature = db_fetch_object(db_query($sql, $loc->feature_id));      $sfeature = db_fetch_object(db_query($sql, $loc->src_feature_id));      $loc->fnid = $ffeature->nid;      $loc->snid = $sfeature->nid;      // add the result to the array      $featurelocs[$i++] = $loc;   }   // Add the relationship feature locs if aggregate is turned on   if($aggregate and strcmp($side,'as_parent')==0){       // get the relationships for this feature without substituting any children      // for the parent. We want all relationships      $relationships = tripal_feature_get_aggregate_relationships($feature_id,0);      foreach($relationships as $rindex => $rel){          // get the featurelocs for each of the relationship features         $rel_featurelocs = tripal_feature_load_featurelocs ($rel->subject_id,'as_child',0);         foreach($rel_featurelocs as $findex => $rfloc){            $featurelocs[$i++] = $rfloc;         }      }   }       usort($featurelocs,'tripal_feature_sort_locations');   return $featurelocs;}/** *  used to sort the feature locs by start position * * @ingroup tripal_feature */function tripal_feature_sort_locations($a,$b){   return strnatcmp($a->fmin, $b->fmin); }/** *   * * @ingroup tripal_feature */function tripal_feature_load_relationships ($feature_id,$side = 'as_subject'){   // get the relationships for this feature.  The query below is used for both   // querying the object and subject relationships   $sql = "SELECT              FS.name as subject_name,              FS.uniquename as subject_uniquename,              CVTS.name as subject_type,             CVTS.cvterm_id as subject_type_id,             FR.subject_id,                       FR.type_id as relationship_type_id,             CVT.name as rel_type,                  FO.name as object_name,              FO.uniquename as object_uniquename,              CVTO.name as object_type,             CVTO.cvterm_id as object_type_id,             FR.object_id,              FR.rank           FROM {feature_relationship} FR             INNER JOIN {cvterm} CVT ON FR.type_id = CVT.cvterm_id             INNER JOIN {feature} FS ON FS.feature_id = FR.subject_id             INNER JOIN {feature} FO ON FO.feature_id = FR.object_id             INNER JOIN {cvterm} CVTO ON FO.type_id = CVTO.cvterm_id             INNER JOIN {cvterm} CVTS ON FS.type_id = CVTS.cvterm_id   ";   if(strcmp($side,'as_object')==0){      $sql .= " WHERE FR.object_id = %d";   }   if(strcmp($side,'as_subject')==0){      $sql .= " WHERE FR.subject_id = %d";   }   $sql .= " ORDER BY FR.rank";   // get the relationships    $previous_db = tripal_db_set_active('chado');  // use chado database   $results = db_query($sql, $feature_id);   tripal_db_set_active($previous_db);  // now use drupal database   // iterate through the relationships, put these in an array and add   // in the Drupal node id if one exists   $i=0;   $nodesql = "SELECT nid FROM {chado_feature} WHERE feature_id = %d";   $relationships = array();   while($rel = db_fetch_object($results)){     $node = db_fetch_object(db_query($nodesql,$rel->subject_id));     if($node){        $rel->subject_nid = $node->nid;     }       $node = db_fetch_object(db_query($nodesql,$rel->object_id));     if($node){        $rel->object_nid = $node->nid;     }       $relationships[$i++] = $rel;         }   return $relationships;}/** *   * * @ingroup tripal_feature */function tripal_feature_get_aggregate_types($feature_id){   // get the feature details   $sql = 'SELECT type_id FROM {feature} WHERE feature_id = %d';   $previous_db = tripal_db_set_active('chado');  // use chado database   $feature = db_fetch_object(db_query($sql, $feature_id));   tripal_db_set_active($previous_db);  // now use drupal database   // check to see if this feature is of a type with an aggregate   $sql = "SELECT * FROM {tripal_feature_relagg} WHERE type_id = %d";   $types = array();   $results = db_query($sql,$feature->type_id);   while($agg = db_fetch_object($results)){      $types[] = $agg->rel_type_id;   }      return $types;}/** *   * * @ingroup tripal_feature */function tripal_feature_get_aggregate_relationships($feature_id, $substitute=1,  $levels=0, $base_type_id=NULL, $depth=0){   // we only want to recurse to as many levels deep as indicated by the    // $levels variable, but only if this variable is > 0. If 0 then we    // recurse until we reach the end of the relationships tree.   if($levels > 0 and $levels == $depth){      return NULL;   }   // first get the relationships for this feature   $relationships = tripal_feature_load_relationships($feature_id,'as_object');   // next, iterate through these relationships and descend, adding in those   // that are specified by the aggregator.   $i=0;   $new_relationships = array();   foreach($relationships as $rindex => $rel){      // set the base type id       if(!$base_type_id){         $base_type_id = $rel->object_type_id;      }       // check to see if we have an aggregator for this base type      $sql = "SELECT * FROM {tripal_feature_relagg} WHERE type_id = %d and rel_type_id = %d";      $agg = db_fetch_object(db_query($sql,$base_type_id,$rel->subject_type_id));      if($agg){         // if we're not going to substitute the resulting relationships for the         // parent then we need to add the parent to our list         if(!$substitute){            $new_relationships[$i++] = $rel;         }         // recurse all relationships          $agg_relationships = tripal_feature_get_aggregate_relationships(            $rel->subject_id,$levels,$base_type_id,$depth++);         // if we have an aggregate defined but we have no relationships beyond         // this point then there's nothing we can substitute          if(!$agg_relationships and $substitute){            $new_relationships[$i++] = $rel;         }         // merge all relationships into one array         foreach($agg_relationships as $aindex => $arel){            $new_relationships[$i++] = $arel;         }        }        else {         // if we don't have an aggregate then keep the current relationship         $new_relationships[$i++] = $rel;      }       }    return $new_relationships;}/** *   * * @ingroup tripal_feature */function tripal_feature_load_featureloc_sequences($feature_id,$featurelocs){   // if we don't have any featurelocs then no point in continuing   if(!$featurelocs){      return array();   }   // get the list of relationships (including any aggregators) and iterate   // through each one to find information needed to color-code the reference sequence   $relationships = tripal_feature_get_aggregate_relationships($feature_id);   if(!$relationships){      return array();   }   // iterate through each of the realtionships features and get their    // locations   foreach($relationships as $rindex => $rel){      // get the featurelocs for each of the relationship features      $rel_featurelocs = tripal_feature_load_featurelocs ($rel->subject_id,'as_child',0);         foreach($rel_featurelocs as $rfindex => $rel_featureloc){         // keep track of this unique source feature         $src = $rel_featureloc->src_feature_id ."-". $rel_featureloc->src_cvterm_id;         // copy over the results to the relationship object.  Since there can         // be more than one feature location for each relationship feature we          // use the '$src' variable to keep track of these.         $rel->featurelocs->$src->src_uniquename = $rel_featureloc->src_uniquename;         $rel->featurelocs->$src->src_cvterm_id  = $rel_featureloc->src_cvterm_id;         $rel->featurelocs->$src->src_cvname     = $rel_featureloc->src_cvname;         $rel->featurelocs->$src->fmin           = $rel_featureloc->fmin;         $rel->featurelocs->$src->fmax           = $rel_featureloc->fmax;         $rel->featurelocs->$src->src_name       = $rel_featureloc->src_name;         // keep track of the individual parts for each relationship          $start = $rel->featurelocs->$src->fmin;         $end   = $rel->featurelocs->$src->fmax;         $rel_locs[$src]['parts'][$start]['type']  = $rel->subject_type;         $rel_locs[$src]['parts'][$start]['start'] = $start;         $rel_locs[$src]['parts'][$start]['end']   = $end;      }   }   // the featurelocs array provided to the function contains the locations   // where this feature is found.   We want to get the sequence for each    // location and then annotate it with the parts found from the relationships   // locations determiend above.    $sql = "SELECT residues FROM {feature} WHERE feature_id = %d";   $floc_sequences = array();   foreach ($featurelocs as $featureloc){      // get the residues for this feature      $previous_db = tripal_db_set_active('chado');  // use chado database      $feature = db_fetch_object(db_query($sql,$featureloc->srcfeature_id->feature_id));      tripal_db_set_active($previous_db);  // now use drupal database      $src = $featureloc->srcfeature_id->feature_id ."-". $featureloc->srcfeature_id->type_id->cvterm_id;      // orient the parts to the beginning of the feature sequence      if (!empty($rel_locs[$src]['parts'])) {        $parts = $rel_locs[$src]['parts'];        usort($parts, 'tripal_feature_sort_rel_parts');        foreach ($parts as $start => $attrs){           $parts[$start]['start'] = $parts[$start]['start'] - $featureloc->fmin;           $parts[$start]['end']   = $parts[$start]['end'] - $featureloc->fmin;        }              $floc_sequences[$src]['src'] = $src;        $floc_sequences[$src]['type'] = $featureloc->feature_id->type_id->name;        $sequence = substr($feature->residues,$featureloc->fmin-1,($featureloc->fmax - $featureloc->fmin)+1);        $floc_sequences[$src]['formatted_seq'] =  tripal_feature_color_sequence (            $sequence,$parts);      }   }   return $floc_sequences;}/** *   * * @ingroup tripal_feature */function tripal_feature_load_organism_feature_counts($organism){   // don't show the browser if the settings in the admin page is turned off   // instead return the array indicating the status of the browser   $show_counts = variable_get('tripal_feature_summary_setting','show_feature_summary');   if(strcmp($show_counts,'show_feature_summary')!=0){      return array ('enabled' => false );   }   // get the feature counts.  This is dependent on a materialized view   // installed with the organism module   $sql = "      SELECT OFC.num_features,OFC.feature_type,CVT.definition      FROM {organism_feature_count} OFC        INNER JOIN {cvterm} CVT on OFC.cvterm_id = CVT.cvterm_id      WHERE organism_id = %d       ORDER BY num_features desc   ";   $previous_db = tripal_db_set_active('chado');  // use chado database   $org_features = db_query($sql,$organism->organism_id);   tripal_db_set_active($previous_db);  // now use drupal database   $i=0;   $types = array();   while($type = db_fetch_object($org_features)){      $types[$i++] = $type;   }   return array ( 'types' => $types, 'enabled' => true );}/** *  * * @ingroup tripal_feature */function tripal_feature_load_organism_feature_browser($organism){   // don't show the browser if the settings in the admin page is turned off   // instead return the array indicating the status of the browser   $show_browser = variable_get('tripal_feature_browse_setting','show_feature_browser');   if(strcmp($show_browser,'show_feature_browser')!=0){      return array ('enabled' => false);   }   # get the list of available sequence ontology terms for which   # we will build drupal pages from features in chado.  If a feature   # is not one of the specified typse we won't build a node for it.   $allowed_types = variable_get('chado_browser_feature_types','EST contig');   $allowed_types = preg_replace("/[\s\n\r]+/"," ",$allowed_types);   $so_terms = split(' ',$allowed_types);   $where_cvt = "";   foreach ($so_terms as $term){      $where_cvt .= "CVT.name = '$term' OR ";   }   $where_cvt = substr($where_cvt,0,strlen($where_cvt)-3);  # strip trailing 'OR'   // get the features for this organism   $sql  = "SELECT F.name,F.feature_id,F.uniquename,CVT.name as cvname ".           "FROM {feature} F ".              "  INNER JOIN {cvterm} CVT on F.type_id = CVT.cvterm_id ".            "WHERE organism_id = %s and ($where_cvt) ".            "ORDER BY feature_id ASC";   // the counting SQL   $csql  = "SELECT count(*) ".            "FROM {feature} F".            "  INNER JOIN {cvterm} CVT on F.type_id = CVT.cvterm_id ".            "WHERE organism_id = %s and ($where_cvt) ".            "GROUP BY organism_id ";   $previous_db = tripal_db_set_active('chado');  // use chado database   $org_features = pager_query($sql,10,0,$csql,$organism->organism_id);   tripal_db_set_active($previous_db);  // now use drupal database   $pager = theme('pager');   // prepare the query that will lookup node ids   $sql = "SELECT nid FROM {chado_feature} ".           "WHERE feature_id = %d";   $i=0;   $features = array();   while($feature = db_fetch_object($org_features)){      $node = db_fetch_object(db_query($sql,$feature->feature_id));      $feature->nid = $node->nid;      $features[$i++] = $feature;   }   return array ( 'features' => $features, 'pager' => $pager, 'enabled' => true );}/** * This generates the Feature Browse which can optionally be included on library pages * and shows all features belonging to the given library. This Browse can be shown/hidden * on the Feature Configuration page. * * @ingroup tripal_feature */function tripal_feature_load_library_feature_browser($library){   // don't show the browser if the settings in the admin page is turned off   // instead return the array indicating the status of the browser   $show_browser = variable_get('tripal_library_feature_browse_setting','show_feature_browser');   if(strcmp($show_browser,'show_feature_browser')!=0){      return array ('enabled' => false);   }   // get a list of feature types to include in the browser   $allowed_types = variable_get('chado_browser_feature_types','EST contig');   $allowed_types = preg_replace("/[\s\n\r]+/"," ",$allowed_types);   $so_terms = split(' ',$allowed_types);   $where_cvt = "";   foreach ($so_terms as $term){      $where_cvt .= "CVT.name = '$term' OR ";   }   $where_cvt = substr($where_cvt,0,strlen($where_cvt)-3);  # strip trailing 'OR'   // get the features for this library   $sql  = "SELECT F.name,F.feature_id,F.uniquename,CVT.name as cvname ".           "FROM {feature} F ".              "  INNER JOIN {cvterm} CVT on F.type_id = CVT.cvterm_id ".              "  INNER JOIN {library_feature} LF on F.feature_id = LF.feature_id ".              "  INNER JOIN {library} L on LF.library_id = L.library_id ".            "WHERE LF.library_id = %d and ($where_cvt) ".            "ORDER BY feature_id ASC";   // the counting SQL   $csql  = "SELECT count(*) ".            "FROM {feature} F".              "  INNER JOIN {cvterm} CVT on F.type_id = CVT.cvterm_id ".              "  INNER JOIN {library_feature} LF on F.feature_id = LF.feature_id ".              "  INNER JOIN {library} L on LF.library_id = L.library_id ".            "WHERE LF.library_id = %d and ($where_cvt) ".            "GROUP BY L.library_id ";   $previous_db = tripal_db_set_active('chado');  // use chado database   $org_features = pager_query($sql,10,0,$csql,$library->library_id);   tripal_db_set_active($previous_db);  // now use drupal database   $pager = theme('pager');   // prepare the query that will lookup node ids   $sql = "SELECT nid FROM {chado_feature} ".           "WHERE feature_id = %d";   $i=0;   $features = array();   while($feature = db_fetch_object($org_features)){      $node = db_fetch_object(db_query($sql,$feature->feature_id));      $feature->nid = $node->nid;      $features[$i++] = $feature;   }   return array ( 'features' => $features, 'pager' => $pager, 'enabled' => true );}/** *  used to sort the list of relationship objects by start position * * @ingroup tripal_feature */function tripal_feature_sort_rel_objects($a,$b){   return strnatcmp($a->fmin, $b->fmin);}/** *  used to sort the list of relationship parts by start position * * @ingroup tripal_feature */function tripal_feature_sort_rel_parts($a,$b){   return strnatcmp($a['start'], $b['start']); }/** *  * * @ingroup tripal_feature */function tripal_feature_color_sequence ($sequence,$parts){   $types = array();   // first get the list of types so we can create a color legend   foreach ($parts as $index => $child){       $type = $child['type'];      if(!in_array($type,$types)){         $types[] = $type;      }   }    $newseq .= "<div id=\"tripal_feature-featureloc_sequence-legend\">Legend: ";   foreach($types as $type){      $newseq .= "<span class=\"tripal_feature-featureloc_sequence-$type\">$type</span>";   }   $newseq .= "</div>";      // set the background color of the rows based on the type   $pos = 0;   $newseq .= "<pre id=\"tripal_feature-featureloc_sequence\">";   foreach ($parts as $index => $child){      $type = $child['type'];      $start = $child['start'];      $end = $child['end']+1;            $class = "class=\"tripal_feature-featureloc_sequence-$type\"";      // iterate through the sequence up to the end of the child      for ($i = $pos; $i < $end; $i++){              // if we're at the beginning of the child sequence then set the         // appropriate text color         if($pos == $start){            $newseq .= "<span $class>";            $func = 'uc';  // nucleotides within the child should be uppercase         }         $newseq .= $sequence{$pos};         $seqcount++;         if($seqcount % 60 == 0){            $newseq .= "\n";         }          $pos++;           if($pos == $end){            $newseq .= "</span>";            $func = 'lc';         }      }   }   $newseq .= "</pre>";   return $newseq;}/** *  This function customizes the view of the chado_feature node.  It allows *  us to generate the markup. * * @ingroup tripal_feature */function chado_feature_view ($node, $teaser = FALSE, $page = FALSE) {   if (!$teaser) {      // use drupal's default node view:      $node = node_prepare($node, $teaser);                 // if we're building the node for searching then      // we want to handle this within the module and      // not allow theme customization.  We don't want to      // index all items (such as DNA sequence).      if($node->build_mode == NODE_BUILD_SEARCH_INDEX){         $node->content['index_version'] = array(            '#value' => theme('tripal_feature_search_index',$node),            '#weight' => 1,         );      }      elseif($node->build_mode == NODE_BUILD_SEARCH_RESULT){         $node->content['index_version'] = array(            '#value' => theme('tripal_feature_search_results',$node),            '#weight' => 1,         );      }      else {         // do nothing here, let the theme derived template handle display      }   }   return $node;}/** * Display feature information for associated organisms. This function also * provides contents for indexing * * @ingroup tripal_feature */function tripal_feature_nodeapi(&$node, $op, $teaser, $page) {   switch ($op) {      // Note that this function only adds feature view to an organism node.      // The view of a feature node is controled by the theme *.tpl file      case 'view':         switch($node->type){            case 'chado_organism':               // Show feature browser               $types_to_show = array('chado_organism', 'chado_library');               if (in_array($node->type, $types_to_show, TRUE)) {                  $node->content['tripal_organism_feature_counts'] = array(                    '#value' => theme('tripal_organism_feature_counts', $node),                  );                  $node->content['tripal_organism_feature_browser'] = array(                    '#value' => theme('tripal_organism_feature_browser', $node),                  );               }               break;            case 'chado_library':               $node->content['tripal_library_feature_browser'] = array(                 '#value' => theme('tripal_library_feature_browser', $node),               );                              break;            default:                    }         break;   }}/** *  We need to let drupal know about our theme functions and their arguments. *  We create theme functions to allow users of the module to customize the *  look and feel of the output generated in this module * * @ingroup tripal_feature */function tripal_feature_theme () {   return array(      'tripal_feature_search_index' => array (         'arguments' => array('node'),      ),      'tripal_feature_search_results' => array (         'arguments' => array('node'),      ),      'tripal_organism_feature_browser' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_organism_feature_browser',      ),      'tripal_organism_feature_counts' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_organism_feature_counts',      ),      'tripal_library_feature_browser' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_library_feature_browser',      ),      'tripal_feature_base' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_base',      ),      'tripal_feature_sequence' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_sequence',      ),      'tripal_feature_synonyms' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_synonyms',      ),      'tripal_feature_featureloc_sequences' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_featureloc_sequences',      ),      'tripal_feature_references' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_references',      ),      'tripal_feature_properties' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_properties',      ),      'tripal_feature_featurelocs' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_featurelocs',      ),      'tripal_feature_relationships' => array (         'arguments' => array('node'=> null),         'template' => 'tripal_feature_relationships',      ),            'tripal_feature_edit_ALL_properties_form' => array(            'arguments' => array('form' => null),            'function' => 'theme_tripal_feature_edit_ALL_properties_form',        ),   );}/** * * * @ingroup tripal_feature */function tripal_feature_preprocess_tripal_organism_feature_counts(&$variables){   $organism = $variables['node']->organism;   $organism->feature_counts = tripal_feature_load_organism_feature_counts($organism);}/** *   * * @ingroup tripal_feature */function tripal_feature_preprocess_tripal_organism_feature_browser(&$variables){   $organism = $variables['node']->organism;   $organism->feature_browser = tripal_feature_load_organism_feature_browser($organism);}/** * Preprocessor function for the Library Feature Browser * * @ingroup tripal_feature */function tripal_feature_preprocess_tripal_library_feature_browser(&$variables){   $library = $variables['node']->library;   $library->feature_browser = tripal_feature_load_library_feature_browser($library);}/** * * * @ingroup tripal_feature */function tripal_feature_cv_chart($chart_id){  // The CV module will create the JSON array necessary for buillding a  // pie chart using jgChart and Google Charts.  We have to pass to it  // a table that contains count information, tell it which column   // contains the cvterm_id and provide a filter for getting the  // results we want from the table.  $organism_id = preg_replace("/^tripal_feature_cv_chart_(\d+)$/","$1",$chart_id);  $options = array(     count_mview      => 'organism_feature_count',     cvterm_id_column => 'cvterm_id',     count_column     => 'num_features',     size             => '550x200',     filter           => "CNT.organism_id = $organism_id",  );  return $options;}/** * * * @ingroup tripal_feature */function tripal_feature_cv_tree($tree_id){  // The CV module will create the JSON array necessary for buillding a  // pie chart using jgChart and Google Charts.  We have to pass to it  // a table that contains count information, tell it which column   // contains the cvterm_id and provide a filter for getting the  // results we want from the table.  $organism_id = preg_replace("/^tripal_feature_cv_tree_(\d+)$/","$1",$tree_id);  $options = array(     cv_id            => tripal_cv_get_cv_id('sequence'),     count_mview      => 'organism_feature_count',     cvterm_id_column => 'cvterm_id',     count_column     => 'num_features',     filter           => "CNT.organism_id = $organism_id",     label            => 'Features',  );  return $options;}/** *  This function is an extension of the chado_feature_view by providing *  the markup for the feature object THAT WILL BE INDEXED. * * @ingroup tripal_feature */function theme_tripal_feature_search_index ($node) {   $feature = $node->feature;   $content = '';   // get the accession prefix   $aprefix = variable_get('chado_feature_accession_prefix','ID');   $content .= "<h1>$feature->uniquename</h1>. ";   $content .= "<strong>$aprefix$feature->feature_id.</strong> ";   $content .= "$feature->cvname ";   $content .= "$feature->common_name ";   // add the synonyms of this feature to the text for searching   $synonyms = $node->synonyms;   if(count($synonyms) > 0){      foreach ($synonyms as $result){         $content .= "$result->name ";      }   }   return $content;}/** *  This function is an extension of the chado_feature_view by providing *  the markup for the feature object THAT WILL BE INDEXED. * * @ingroup tripal_feature */function theme_tripal_feature_search_results ($node) {   $feature = $node->feature;   $content = '';   // get the accession prefix   $aprefix = variable_get('chado_feature_accession_prefix','ID');   $content .= "Feature Name: <h1>$feature->uniquename</h1>. ";   $content .= "<strong>Accession: $aprefix$feature->feature_id.</strong>";   $content .= "Type: $feature->cvname. ";   $content .= "Organism: $feature->common_name. ";   // add the synonyms of this feature to the text for searching   $synonyms = $node->synonyms;   if(count($synonyms) > 0){      $content .= "Synonyms: ";      foreach ($synonyms as $result){         $content .= "$result->name, ";      }   }   return $content;}/** * * * @ingroup tripal_feature */function tripal_feature_set_vocabulary (){   //include the file containing the required functions for adding taxonomy vocabs   module_load_include('inc', 'taxonomy', 'taxonomy.admin');   // get the vocabularies so that we make sure we don't recreate   // the vocabs that already exist   $vocabularies = taxonomy_get_vocabularies();   $ft_vid = NULL;   $op_vid = NULL;   $lb_vid = NULL;   $an_vid = NULL;   // These taxonomic terms are hard coded because we   // konw we have these relationships in the chado tables   // through foreign key relationships.  The tripal   // modules that correspond to these chado "modules" don't   // need to be installed for the taxonomy to work.   foreach($vocabularies as $vocab){      if($vocab->name == 'Feature Type'){         $ft_vid = $vocab->vid;      }      if($vocab->name == 'Organism'){         $op_vid = $vocab->vid;      }      if($vocab->name == 'Library'){         $lb_vid = $vocab->vid;      }      if($vocab->name == 'Analysis'){         $an_vid = $vocab->vid;      }   }   if(!$ft_vid){      $form_state = array();      $values = array(         'name' => t('Feature Type'),         'nodes' => array('chado_feature' => 'chado_feature'),         'description' => t('The feature type (or SO cvterm for this feature).'),         'help' => t('Select the term that matches the feature '),         'tags' => 0,         'hierarchy' => 1,         'relations' => 1,         'multiple' => 0,         'required' => 0,         'weight' => 1,      );      drupal_execute('taxonomy_form_vocabulary', $form_state,$values);      drupal_execute('taxonomy_form_vocabulary', $form_state);   }   if(!$op_vid){      $form_state = array();      $values = array(         'name' => t('Organism'),         'nodes' => array('chado_feature' => 'chado_feature'),         'description' => t('The organism to which this feature belongs.'),         'help' => t('Select the term that matches the feature '),         'tags' => 0,         'hierarchy' => 1,         'relations' => 1,         'multiple' => 0,         'required' => 0,         'weight' => 2,      );      drupal_execute('taxonomy_form_vocabulary', $form_state,$values);      drupal_execute('taxonomy_form_vocabulary', $form_state);   }   if(!$lb_vid){      $form_state = array();      $values = array(         'name' => t('Library'),         'nodes' => array('chado_feature' => 'chado_feature'),         'description' => t('Chado features associated with a library are assigned the term associated with the library'),         'help' => t('Select the term that matches the feature '),         'tags' => 0,         'hierarchy' => 1,         'relations' => 1,         'multiple' => 0,         'required' => 0,         'weight' => 3,      );      drupal_execute('taxonomy_form_vocabulary', $form_state, $values);      drupal_execute('taxonomy_form_vocabulary', $form_state);   }   if(!$an_vid){      $form_state = array();      $values = array(         'name' => t('Analysis'),         'nodes' => array('chado_feature' => 'chado_feature'),         'description' => t('Any analysis to which this feature belongs.'),         'help' => t('Select the term that matches the feature '),         'tags' => 0,         'hierarchy' => 1,         'relations' => 1,         'multiple' => 1,         'required' => 0,         'weight' => 4,      );      drupal_execute('taxonomy_form_vocabulary', $form_state,$values);      drupal_execute('taxonomy_form_vocabulary', $form_state);   }}/** * * * @ingroup tripal_feature */function tripal_feature_del_vocabulary(){   //include the file containing the required functions for adding taxonomy vocabs   module_load_include('inc', 'taxonomy', 'taxonomy.admin');   // get the vocabularies   $vocabularies = taxonomy_get_vocabularies();   // These taxonomic terms are hard coded because we   // know we have these relationships in the chado tables   // through foreign key relationships.  The tripal   // modules that correspond to these chado "modules" don't   // need to be installed for the taxonomy to work.   foreach($vocabularies as $vocab){      if($vocab->name == 'Feature Type'){         taxonomy_del_vocabulary($vocab->vid);      }      if($vocab->name == 'Organism'){         taxonomy_del_vocabulary($vocab->vid);      }      if($vocab->name == 'Library'){         taxonomy_del_vocabulary($vocab->vid);      }      if($vocab->name == 'Analysis'){         taxonomy_del_vocabulary($vocab->vid);      }   }}/** * * * @ingroup tripal_feature */function tripal_features_set_taxonomy($max_sync = 0,$job_id = NULL){   // make sure our vocabularies are cleaned and reset before proceeding   tripal_feature_del_vocabulary();   tripal_feature_set_vocabulary();   // iterate through all drupal feature nodes and set the taxonomy   $results = db_query("SELECT * FROM {chado_feature}");   $nsql =  "SELECT * FROM {node} ".            "WHERE nid = %d";   $i = 0;   // load into ids array   $count = 0;   $chado_features = array();   while($chado_feature = db_fetch_object($results)){      $chado_features[$count] = $chado_feature;      $count++;   }   // Iterate through features that need to be synced   $interval = intval($count * 0.01);   foreach($chado_features as $chado_feature){      // update the job status every 1% features      if($job_id and $i % $interval == 0){         tripal_job_set_progress($job_id,intval(($i/$count)*100));      }      print "$i of $count: ";      $node = db_fetch_object(db_query($nsql,$chado_feature->nid));      tripal_feature_set_taxonomy($node,$chado_feature->feature_id);      $i++;   }}/** * * * @ingroup tripal_feature */function tripal_feature_set_taxonomy ($node,$feature_id){   // iterate through the taxonomy classes that have been   // selected by the admin user and make sure we only set those   $tax_classes = variable_get('tax_classes', '');   $do_ft = 0;   $do_op = 0;   $do_lb = 0;   $do_an = 0;   foreach($tax_classes as $class){      if(strcmp($class ,'organism')==0){         $do_op = 1;      }      if(strcmp($class,'feature_type')==0){         $do_ft = 1;      }      if(strcmp($class,'library')==0){         $do_lb = 1;      }      if(strcmp($class,'analysis')==0){         $do_an = 1;      }   }   // get the list of vocabularies and find our two vocabularies of interest   $vocabularies = taxonomy_get_vocabularies();   $ft_vid = NULL;   $op_vid = NULL;   $lb_vid = NULL;   $an_vid = NULL;   foreach($vocabularies as $vocab){      if($vocab->name == 'Feature Type'){         $ft_vid = $vocab->vid;      }      if($vocab->name == 'Organism'){         $op_vid = $vocab->vid;      }      if($vocab->name == 'Library'){         $lb_vid = $vocab->vid;      }      if($vocab->name == 'Analysis'){         $an_vid = $vocab->vid;      }   }   // get the cvterm and the organism for this feature   $sql = "SELECT CVT.name AS cvname, O.genus, O.species ".          "FROM {CVTerm} CVT ".          "  INNER JOIN Feature F on F.type_id = CVT.cvterm_id ".          "  INNER JOIN Organism O ON F.organism_id = O.organism_id ".          "WHERE F.feature_id = $feature_id";   $previous_db = tripal_db_set_active('chado');  // use chado database   $feature = db_fetch_object(db_query($sql));   tripal_db_set_active($previous_db);  // now use drupal database   // Set the feature type for this feature   if($do_ft && $ft_vid){      $tags["$ft_vid"] = "$feature->cvname";   }   // Set the organism for this feature type   if($do_op && $op_vid){      $tags["$op_vid"] = "$feature->genus $feature->species";   }   // get the library that this feature may belong to and add it as taxonomy   if($do_lb && $lb_vid){      $sql = "SELECT L.name ".             "FROM {Library} L ".             "  INNER JOIN Library_feature LF ON LF.library_id = L.library_id ".             "WHERE LF.feature_id = %d ";      $previous_db = tripal_db_set_active('chado');  // use chado database      $library = db_fetch_object(db_query($sql,$feature_id));      tripal_db_set_active($previous_db);  // now use drupal database      $tags["$lb_vid"] = "$library->name";   }   // now add the taxonomy to the node   $terms['tags'] = $tags;   taxonomy_node_save($node,$terms);   //   print "Setting $node->name: " . implode(", ",$tags) . "\n";   // get the analysis that this feature may belong to and add it as taxonomy   // We'll add each one individually since there may be more than one analysis   if($do_an && $an_vid){      $sql = "SELECT A.name ".             "FROM {Analysis} A ".             "  INNER JOIN Analysisfeature AF ON AF.analysis_id = A.analysis_id ".             "WHERE AF.feature_id = $feature_id ";      $results = db_query($sql);      $previous_db = tripal_db_set_active('chado');  // use chado database      $analysis_terms = array();      while($analysis=db_fetch_object($results)){         $tags2["$an_vid"] = "$analysis->name";         $terms['tags'] = $tags2;         taxonomy_node_save($node,$terms);      }      tripal_db_set_active($previous_db);  // now use drupal database   }}/** * * * @ingroup tripal_feature */function tripal_features_cleanup($dummy = NULL, $job_id = NULL) {   // build the SQL statments needed to check if nodes point to valid features   $dsql = "SELECT * FROM {node} WHERE type = 'chado_feature' order by nid";   $nsql = "SELECT * FROM {node} WHERE nid = %d";   $csql = "SELECT * FROM {chado_feature} where nid = %d ";   $cfsql= "SELECT * FROM {chado_feature}";    // load into nodes array   $results = db_query($dsql);   $count = 0;   $nodes = array();   while($node = db_fetch_object($results)){      $nodes[$count] = $node;      $count++;   }   // load the chado_features into an array   $results = db_query($cfsql);   $cnodes = array();   while($node = db_fetch_object($results)){      $cnodes[$count] = $node;      $count++;   }   $interval = intval($count * 0.01);   if($interval > 1){      $interval = 1;   }   // iterate through all of the chado_feature nodes and delete those  that aren't valid   foreach($nodes as $nid){      // update the job status every 1% features      if($job_id and $i % $interval == 0){         tripal_job_set_progress($job_id,intval(($i/$count)*100));      }      // check to see if the node has a corresponding entry      // in the chado_feature table. If not then delete the node.      $feature = db_fetch_object(db_query($csql,$nid->nid));      if(!$feature){         node_delete($nid->nid);         $message = "Missing in chado_feature table.... DELETING: $nid->nid\n";         watchdog('tripal_feature',$message,array(),WATCHDOG_WARNING);         continue;      }      $i++;   }   // iterate through all of the chado_feature nodes and delete those  that aren't valid   foreach($cnodes as $nid){      // update the job status every 1% features      if($job_id and $i % $interval == 0){         tripal_job_set_progress($job_id,intval(($i/$count)*100));      }      $node = db_fetch_object(db_query($nsql,$nid->nid));      if(!$node){         db_query("DELETE FROM {chado_feature} WHERE nid = $nid->nid");         $message = "chado_feature missing node.... DELETING: $nid->nid\n";         watchdog('tripal_feature',$message,array(),WATCHDOG_WARNING);      }      $i++;   }   return '';}/** * * * @ingroup tripal_feature */function tripal_feature_return_fasta($feature,$desc){      $fasta  = ">" . variable_get('chado_feature_accession_prefix','ID') . "$feature->feature_id|$feature->name";   $fasta .= " $desc\n";   $fasta .= wordwrap($feature->residues, 50, "\n", true);   $fasta .= "\n\n";   return $fasta;}/** * * * @ingroup tripal_feature */function tripal_feature_job_describe_args($callback,$args){   $new_args = array();   if($callback == 'tripal_feature_load_fasta'){      $new_args['FASTA file'] = $args[0];      $organism = tripal_core_chado_select('organism',array('genus','species'),array('organism_id' => $args[1]));      $new_args['Organism'] = $organism[0]->genus." ". $organism[0]->species;      $new_args['Sequence Type'] = $args[2];      $new_args['Name Match Type'] = $args[14];      $new_args['Name RE'] = $args[4];      $new_args['Unique Name RE'] = $args[5];      // add in the relationship arguments      $new_args['Relationship Type'] = $args[8];      $new_args['Relationship Parent RE'] = $args[9];      $new_args['Relationship Parent Type'] = $args[10];      // add in the database reference arguments      if($args[7]){         $db = tripal_core_chado_select('db',array('name'),array('db_id' => $args[7]));      }      $new_args['Database Reference'] = $db[0]->name;      $new_args['Accession RE'] = $args[6];      $new_args['Method'] = $args[11];      // add in the analysis       if($args[13]){         $analysis = tripal_core_chado_select('analysis',array('name'),array('analysis_id' => $args[13]));      }      $new_args['Analysis'] = $analysis[0]->name;   }   if($callback == 'tripal_feature_delete_features'){      if($args[0]){         $organism = tripal_core_chado_select('organism',array('genus','species'),array('organism_id' => $args[0]));         $new_args['Organism'] = $organism[0]->genus." ". $organism[0]->species;      } else {         $new_args['Organism'] = '';      }      if($args[1]){         $analysis = tripal_core_chado_select('analysis',array('name'),array('analysis_id' => $args[1]));         $new_args['Analysis'] = $analysis[0]->name;      } else {         $new_args['Analysis'] = '';      }            $new_args['Sequence Type'] = $args[2];      $new_args['Is Unique Name'] = $args[3];      $new_args['Features Names'] = $args[4];         }   if($callback == 'tripal_feature_sync_features'){      if($args[0]){         $organism = tripal_core_chado_select('organism',array('genus','species'),array('organism_id' => $args[0]));         $new_args['Organism'] = $organism[0]->genus." ". $organism[0]->species;      } else {         $new_args['Organism'] = '';      }      $new_args['Feature Types'] = $args[1];   }   return $new_args;}
 |