From 4870a4dc97602d8a498f1bed1cfee4ebd9f0477f Mon Sep 17 00:00:00 2001 From: Edward Gilbert Date: Wed, 10 Feb 2021 10:44:45 -0700 Subject: [PATCH 1/4] Exsiccati index bug - Bug fix that produced bad SQL when search term was supplied within an exsiccati search --- classes/ExsiccatiManager.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/classes/ExsiccatiManager.php b/classes/ExsiccatiManager.php index f25808a760..0a7843d975 100644 --- a/classes/ExsiccatiManager.php +++ b/classes/ExsiccatiManager.php @@ -209,11 +209,12 @@ public function getExsOccArr($id, $target = 'omenid'){ } public function exportExsiccatiAsCsv($searchTerm, $specimenOnly, $imagesOnly, $collId, $titleOnly){ - $fileName = 'exsiccatiOutput_'.time().'.csv'; + $fileName = 'exsiccatiOutput_'.time().'.txt'; header ('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header ('Content-Type: text/csv'); header ('Content-Disposition: attachment; filename="'.$fileName.'"'); $sqlInsert = ''; + $sqlWhere = ''; $fieldArr = array('titleID'=>'et.ometid', 'exsiccatiTitle'=>'et.title', 'abbreviation'=>'et.abbreviation', 'editors'=>'et.editor', 'range'=>'et.exsrange', 'startDate'=>'et.startdate', 'endDate'=>'et.enddate', 'source'=>'et.source', 'sourceIdentifier'=>'et.sourceIdentifier', 'titleNotes'=>'et.notes AS titleNotes'); if(!$titleOnly){ @@ -222,7 +223,7 @@ public function exportExsiccatiAsCsv($searchTerm, $specimenOnly, $imagesOnly, $c if($collId || $specimenOnly){ $sqlInsert .= 'INNER JOIN omexsiccatiocclink ol ON en.omenid = ol.omenid INNER JOIN omoccurrences o ON ol.occid = o.occid '; if($imagesOnly) $sqlInsert .= 'INNER JOIN images i ON o.occid = i.occid '; - if($collId) $sqlInsert .= 'WHERE o.collid = '.$collId.' '; + if($collId) $sqlWhere .= 'AND o.collid = '.$collId.' '; $fieldArr['occid'] = 'o.occid'; $fieldArr['catalogNumber'] = 'o.catalognumber'; $fieldArr['otherCatalogNumbers'] = 'o.othercatalognumbers'; @@ -239,10 +240,13 @@ public function exportExsiccatiAsCsv($searchTerm, $specimenOnly, $imagesOnly, $c } } if($searchTerm){ - $sqlInsert .= ($sqlInsert?'AND ':'WHERE ').'et.title LIKE "%'.$searchTerm.'%" OR et.abbreviation LIKE "%'.$searchTerm.'%" OR et.editor LIKE "%'.$searchTerm.'%" '; + $sqlWhere .= 'AND (et.title LIKE "%'.$searchTerm.'%" OR et.abbreviation LIKE "%'.$searchTerm.'%" OR et.editor LIKE "%'.$searchTerm.'%") '; } - $sql = 'SELECT '.implode(',',$fieldArr).' FROM omexsiccatititles et '.$sqlInsert.'ORDER BY et.title'; + $sql = 'SELECT '.implode(',',$fieldArr).' FROM omexsiccatititles et '.$sqlInsert; + if($sqlWhere) $sql .= 'WHERE '.substr($sqlWhere,3); + $sql .= 'ORDER BY et.title'; if(!$titleOnly) $sql .= ', en.exsnumber+0'; + echo $sql; exit; $rs = $this->conn->query($sql); if($rs->num_rows){ $out = fopen('php://output', 'w'); From 9fae4eefb8649c3ad0d5b5b0fa26c62ffa4563bc Mon Sep 17 00:00:00 2001 From: Edward Gilbert Date: Wed, 10 Feb 2021 10:51:14 -0700 Subject: [PATCH 2/4] Exsiccait indexing bug - Minor fix to previous code submit --- classes/ExsiccatiManager.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/classes/ExsiccatiManager.php b/classes/ExsiccatiManager.php index 0a7843d975..8bbb17c2a8 100644 --- a/classes/ExsiccatiManager.php +++ b/classes/ExsiccatiManager.php @@ -209,7 +209,7 @@ public function getExsOccArr($id, $target = 'omenid'){ } public function exportExsiccatiAsCsv($searchTerm, $specimenOnly, $imagesOnly, $collId, $titleOnly){ - $fileName = 'exsiccatiOutput_'.time().'.txt'; + $fileName = 'exsiccatiOutput_'.time().'.csv'; header ('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header ('Content-Type: text/csv'); header ('Content-Disposition: attachment; filename="'.$fileName.'"'); @@ -246,7 +246,6 @@ public function exportExsiccatiAsCsv($searchTerm, $specimenOnly, $imagesOnly, $c if($sqlWhere) $sql .= 'WHERE '.substr($sqlWhere,3); $sql .= 'ORDER BY et.title'; if(!$titleOnly) $sql .= ', en.exsnumber+0'; - echo $sql; exit; $rs = $this->conn->query($sql); if($rs->num_rows){ $out = fopen('php://output', 'w'); From 323ec4a4e2531fa9581272dd1effc75c1b374cb5 Mon Sep 17 00:00:00 2001 From: Edward Gilbert Date: Wed, 10 Feb 2021 10:52:50 -0700 Subject: [PATCH 3/4] Schema Adjustments - Add various fields to occurrence table --- .../schema-1.0/dev/db_schema_patch_pending.sql | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/config/schema-1.0/dev/db_schema_patch_pending.sql b/config/schema-1.0/dev/db_schema_patch_pending.sql index 30ef8bfde0..acb7ffcd9f 100644 --- a/config/schema-1.0/dev/db_schema_patch_pending.sql +++ b/config/schema-1.0/dev/db_schema_patch_pending.sql @@ -125,6 +125,13 @@ ALTER TABLE `referenceobject` ALTER TABLE `uploadspectemp` + ADD COLUMN `continent` VARCHAR(45) NULL AFTER `locationID`, + ADD COLUMN `islandGroup` VARCHAR(75) NULL AFTER `waterBody`, + ADD COLUMN `island` VARCHAR(75) NULL AFTER `islandGroup`, + ADD COLUMN `countryCode` VARCHAR(5) NULL AFTER `island`, + ADD COLUMN `parentLocationID` VARCHAR(150) NULL AFTER `locationID`, + ADD COLUMN `samplingProtocol` VARCHAR(150) NULL AFTER `parentLocationID`, + ADD COLUMN `georeferencedDate` DATETIME NULL AFTER `georeferencedBy`, ADD COLUMN `paleoJSON` TEXT NULL AFTER `exsiccatiNotes`; ALTER TABLE `uploadspectemp` @@ -449,9 +456,14 @@ CREATE TABLE `omoccurloanuser` ( CONSTRAINT `FK_occurloan_modifiedByUid` FOREIGN KEY (`modifiedByUid`) REFERENCES `users` (`uid`) ON DELETE SET NULL ON UPDATE CASCADE); -ALTER TABLE `omoccurrences` +ALTER TABLE `omoccurrences` + CHANGE COLUMN `eventID` `eventID` VARCHAR(150) NULL DEFAULT NULL, + CHANGE COLUMN `locationID` `locationID` VARCHAR(150) NULL DEFAULT NULL, CHANGE COLUMN `labelProject` `labelProject` varchar(250) DEFAULT NULL, CHANGE COLUMN `georeferenceRemarks` `georeferenceRemarks` VARCHAR(500) NULL DEFAULT NULL, + ADD COLUMN `georeferencedDate` DATETIME NULL AFTER `georeferencedBy`, + ADD COLUMN `parentLocationID` VARCHAR(150) NULL AFTER `locationID`, + ADD COLUMN `samplingProtocol` VARCHAR(150) NULL AFTER `parentLocationID`, DROP INDEX `idx_occrecordedby`; ALTER TABLE `omoccurrences` @@ -478,7 +490,7 @@ ALTER TABLE `omoccurrences` ADD UNIQUE INDEX `Index_gui` (`occurrenceID` ASC); ALTER TABLE `omoccurrences` -ADD INDEX `Index_latlng` (`decimalLatitude` ASC, `decimalLongitude` ASC); + ADD INDEX `Index_latlng` (`decimalLatitude` ASC, `decimalLongitude` ASC); DELETE FROM omoccurrencesfulltext WHERE locality IS NULL AND recordedby IS NULL; From 809cd1e4aea033ca6ddbee23675efb6bbaaf37be Mon Sep 17 00:00:00 2001 From: Edward Gilbert Date: Wed, 10 Feb 2021 11:14:25 -0700 Subject: [PATCH 4/4] Dynamic Checklist Generator dev - Fixed bug causing tool to fail that was introduced when adding variable sanitation code - Added code to ensure taxon filter being applied during various methods of applying a taxon terms - Extended Manager class into Dynamic Checklist class --- checklists/dynamicchecklist.php | 28 +++++++------- classes/DynamicChecklistManager.php | 60 ++++++++++++++++------------- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/checklists/dynamicchecklist.php b/checklists/dynamicchecklist.php index a52b322d99..a995fa6b34 100644 --- a/checklists/dynamicchecklist.php +++ b/checklists/dynamicchecklist.php @@ -1,5 +1,4 @@ createChecklist($lat, $lng, $radius, $radiusUnits, $tid); -} -else{ - $dynClid = $dynClManager->createDynamicChecklist($lat, $lng, $dynamicRadius, $tid); -} +if($taxa && !$tid) $tid = $dynClManager->getTid($taxa); +$dynClid = 0; +if($radius) $dynClid = $dynClManager->createChecklist($lat, $lng, $radius, $radiusUnits, $tid); +else $dynClid = $dynClManager->createDynamicChecklist($lat, $lng, $dynamicRadius, $tid); -if($interface == "key"){ - header("Location: ".$CLIENT_ROOT."/ident/key.php?dynclid=".$dynClid."&taxon=All Species"); -} -else{ - header("Location: ".$CLIENT_ROOT."/checklists/checklist.php?dynclid=".$dynClid); +if($dynClid){ + if($interface == "key"){ + header("Location: ".$CLIENT_ROOT."/ident/key.php?dynclid=".$dynClid."&taxon=All Species"); + } + else{ + header("Location: ".$CLIENT_ROOT."/checklists/checklist.php?dynclid=".$dynClid); + } } -ob_flush(); -flush(); +else echo 'ERROR generating checklist'; $dynClManager->removeOldChecklists(); ?> \ No newline at end of file diff --git a/classes/DynamicChecklistManager.php b/classes/DynamicChecklistManager.php index 279d32a974..cfe99e4c9b 100644 --- a/classes/DynamicChecklistManager.php +++ b/classes/DynamicChecklistManager.php @@ -1,28 +1,25 @@ conn = MySQLiConnectionFactory::getCon("write"); + parent::__construct(null,'write'); } public function __destruct(){ - if(!($this->conn === null)) $this->conn->close(); + parent::__destruct(); } public function createChecklist($lat, $lng, $radius, $radiusUnits, $tidFilter){ - global $SYMB_UID; - //Radius is a set value + //Radius is a set value if($radiusUnits == "mi") $radius = round($radius*1.6); $dynPk = 0; //Create checklist $sql = 'INSERT INTO fmdynamicchecklists(name,details,expiration,uid) '. 'VALUES ("'.round($lat,5).' '.round($lng,5).' within '.round($radius,1).' km","'.$lat.' '.$lng.' within '.$radius.' km","'. - date('Y-m-d',mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))).'",'.($SYMB_UID?$SYMB_UID:'NULL').')'; - //echo $sql; + date('Y-m-d',mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))).'",'.($GLOBALS['SYMB_UID']?$GLOBALS['SYMB_UID']:'NULL').')'; if($this->conn->query($sql)){ $dynPk = $this->conn->insert_id; //Add species to checklist @@ -36,35 +33,32 @@ public function createChecklist($lat, $lng, $radius, $radiusUnits, $tidFilter){ //$sql = 'SELECT count(o.tid) AS speccnt FROM omoccurgeoindex o '. // 'WHERE (o.DecimalLatitude BETWEEN lat1 AND lat2) AND (o.DecimalLongitude BETWEEN lng1 AND lng2)'; //$this->conn->query($sql); - + $sql = 'INSERT INTO fmdyncltaxalink (dynclid, tid) '. 'SELECT DISTINCT '.$dynPk.' AS dynpk, IF(t.rankid=220,t.tid,ts2.parenttid) as tid '. 'FROM omoccurgeoindex o INNER JOIN taxstatus ts ON o.tid = ts.tid '. 'INNER JOIN taxstatus ts2 ON ts.tidaccepted = ts2.tid '. 'INNER JOIN taxa t ON ts2.tid = t.tid '; if($tidFilter){ - $sql .= 'INNER JOIN taxaenumtree e ON ts2.tid = e.tid '; + $sql .= 'INNER JOIN taxaenumtree e ON ts2.tid = e.tid '; } $sql .= 'WHERE (t.rankid IN(220,230,240,260)) AND (ts.taxauthid = 1) AND (ts2.taxauthid = 1) '. 'AND (o.DecimalLatitude BETWEEN '.$lat1.' AND '.$lat2.') AND (o.DecimalLongitude BETWEEN '.$lng1.' AND '.$lng2.') '; if($tidFilter){ $sql .= 'and e.parentTid = '.$tidFilter; } - //echo $sql; exit; $this->conn->query($sql); } return $dynPk; } - + public function createDynamicChecklist($lat, $lng, $radiusUnit, $tidFilter){ - global $SYMB_UID; $dynPK = 0; $specCnt = 0; - $radius; - $latRadius; $lngRadius; - $lat1; $lat2; $lng1; $lng2; + $radius = 10; + $lat1 = 0; $lat2 = 0; $lng1 = 0; $lng2 = 0; $loopCnt = 1; while($specCnt < 2500 && $loopCnt < 10){ $radius = $radiusUnit*$loopCnt; @@ -74,7 +68,7 @@ public function createDynamicChecklist($lat, $lng, $radiusUnit, $tidFilter){ $lat2 = $lat + $latRadius; $lng1 = $lng - $lngRadius; $lng2 = $lng + $lngRadius; - + $sql1 = 'SELECT count(tid) AS speccnt '. 'FROM omoccurgeoindex '. 'WHERE (DecimalLatitude BETWEEN '.$lat1.' AND '.$lat2.') AND (DecimalLongitude BETWEEN '.$lng1.' AND '.$lng2.')'; @@ -85,12 +79,11 @@ public function createDynamicChecklist($lat, $lng, $radiusUnit, $tidFilter){ $rs1->free(); $loopCnt++; } - + $radius = $radius*1.60934; $sql2 = 'INSERT INTO fmdynamicchecklists(name,details,expiration,uid) '. 'VALUES ("'.round($lat,5).' '.round($lng,5).' within '.round($radius,1).' km","'.$lat.' '.$lng.' within '.$radius.' km","'. - date('Y-m-d',mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))).'",'.($SYMB_UID?$SYMB_UID:'NULL').')'; - //echo $sql; + date('Y-m-d',mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))).'",'.($GLOBALS['SYMB_UID']?$GLOBALS['SYMB_UID']:'NULL').')'; if($this->conn->query($sql2)){ $dynPK = $this->conn->insert_id; $sql3 = 'INSERT INTO fmdyncltaxalink (dynclid, tid) '. @@ -99,21 +92,36 @@ public function createDynamicChecklist($lat, $lng, $radiusUnit, $tidFilter){ 'INNER JOIN taxstatus ts2 ON ts.tidaccepted = ts2.tid '. 'INNER JOIN taxa t ON ts2.tid = t.tid '; if($tidFilter){ - $sql3 .= 'INNER JOIN taxaenumtree e ON ts2.tid = e.tid '; + $sql3 .= 'INNER JOIN taxaenumtree e ON ts2.tid = e.tid '; } $sql3 .= 'WHERE (t.rankid >= 220) AND (ts.taxauthid = 1) AND (ts2.taxauthid = 1) '. 'AND (o.DecimalLatitude BETWEEN '.$lat1.' AND '.$lat2.') AND (o.DecimalLongitude BETWEEN '.$lng1.' AND '.$lng2.')'; if($tidFilter){ $sql3 .= 'and e.parentTid = '.$tidFilter; } - //echo $sql3; exit; if(!$this->conn->query($sql3)){ - + $this->errorMessage = 'ERROR adding taxa to checklist: '.$this->conn->error; + echo $this->errorMessage; } } + else { + $this->errorMessage = 'ERROR building checklist: '.$this->conn->connect_error; + echo $this->errorMessage; + } return $dynPK; } - + + public function getTid($sciname){ + $tid = 0; + $sql = 'SELECT tid FROM taxa WHERE sciname = "'.$this->cleanInStr($sciname).'"'; + $rs = $this->conn->query($sql); + if($r = $rs->fetch_object()){ + $tid = $r->tid; + } + $rs->free(); + return $tid; + } + public function removeOldChecklists(){ //Remove any old checklists $sql1 = 'DELETE dcl.* '. @@ -122,6 +130,6 @@ public function removeOldChecklists(){ $this->conn->query($sql1); $sql2 = 'DELETE FROM fmdynamicchecklists WHERE expiration < NOW()'; $this->conn->query($sql2); - } + } } ?> \ No newline at end of file