Skip to content

Commit

Permalink
Fix Backward Compatiblity Issue involving mysqli_execute_query (#1682)
Browse files Browse the repository at this point in the history
* Adds util function to make use of mysqli_execute_query for older versions of php

# Summary
`mysqli_execute_query` or `$mysqli->execute_query` function is an 8.2
only function provided by mysqli which could break portals that cannot
upgrade to 8.2 from 8 or are running 7.3. Solution is to make a util
function with the same api as mysqli_execute_query but will use the php
version to decide wether to use mysqli_execute_query or normal statement
binding.

* removing comment left over from prototyping
  • Loading branch information
MuchQuak authored Aug 28, 2024
1 parent b50a0db commit 6279f1e
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 35 deletions.
23 changes: 12 additions & 11 deletions classes/GeographicThesaurus.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php
include_once ($SERVER_ROOT . '/classes/Manager.php');
include_once($SERVER_ROOT. '/utilities/SymbUtil.php');

class GeographicThesaurus extends Manager {

Expand Down Expand Up @@ -121,7 +122,7 @@ public function editGeoUnit($postArr){
SQL;

try {
$this->conn->execute_query($sql, [
SymbUtil::execute_query($this->conn,$sql, [
$postArr['geoTerm'],
empty($postArr['abbreviation'])? null: $postArr['abbreviation'],
empty($postArr['iso2'])? null: $postArr['iso2'],
Expand All @@ -143,7 +144,7 @@ public function editGeoUnit($postArr){
SELECT * from geographicpolygon WHERE geoThesID = ?
SQL;

$polygon_exists = $this->conn->execute_query($sql, [htmlspecialchars($postArr['geoThesID'])]);
$polygon_exists = SymbUtil::execute_query($this->conn,$sql, [htmlspecialchars($postArr['geoThesID'])]);

if(!$polygon_exists) {
$this->errorMessage = 'ERROR saving polygon edits: '.$this->conn->error;
Expand All @@ -168,7 +169,7 @@ private function addPolygon($geoThesID, $polygon): bool {
CALL insertGeographicPolygon(?, ?);
SQL;
try {
$this->conn->execute_query($sql, [$geoThesID, $polygon]);
SymbUtil::execute_query($this->conn,$sql, [$geoThesID, $polygon]);
return true;
} catch (\Throwable $e) {
$this->errorMessage = 'ERROR saving new polygon: ' . $e->getMessage();
Expand All @@ -181,7 +182,7 @@ private function updatePolygon($geoThesID, $polygon) {
CALL updateGeographicPolygon(?, ?);
SQL;
try {
$this->conn->execute_query($sql, [$geoThesID, $polygon]);
SymbUtil::execute_query($this->conn,$sql, [$geoThesID, $polygon]);
return true;
} catch (\Throwable $e) {
$this->errorMessage = 'ERROR updatePolygon on '. $geoThesID .':' . $e->getMessage();
Expand All @@ -195,7 +196,7 @@ private function deletePolygon($geoThesID) {
SQL;

try {
$this->conn->execute_query($sql, [$geoThesID]);
SymbUtil::execute_query($this->conn,$sql, [$geoThesID]);
return true;
} catch (\Throwable $e) {
$this->errorMessage = 'ERROR deletePolygon on '. $geoThesID . ':' . $e->getMessage();
Expand Down Expand Up @@ -256,7 +257,7 @@ public function getChildren(array $parentIDs): array {
SQL;

try {
$result = $this->conn->execute_query($sql, $parentIDs);
$result = SymbUtil::execute_query($this->conn,$sql, $parentIDs);
$children = $result->fetch_all(MYSQLI_ASSOC);
$result->free();
$children_ids = array_map(fn($v) => $v["geoThesID"], $children);
Expand Down Expand Up @@ -505,7 +506,7 @@ public function getGBGeoList($countryCode){
SQL;

try {
$result = $this->conn->execute_query($sql, [$countryCode]);
$result = SymbUtil::execute_query($this->conn,$sql, [$countryCode]);
if(($row = $result->fetch_object()) && isset($retArr['ADM0'])) {
$retArr['ADM0']['geoThesID'] = $row->geoThesID;
if($row->polygonID) $retArr['ADM0']['polygon'] = 1;
Expand Down Expand Up @@ -729,7 +730,7 @@ public function addGeoBoundary(string $url, bool $addMissing = false, int $baseP
$sql = <<<'SQL'
UPDATE geographicthesaurus set iso3 = ? where geoThesID = ?
SQL;
$this->conn->execute_query($sql, [$iso, $geoThesIDs[$key]['geoThesID']]);
SymbUtil::execute_query($this->conn,$sql, [$iso, $geoThesIDs[$key]['geoThesID']]);
} catch (\Throwable $e) {
$this->errorMessage = 'ERROR updating iso3 to match boundaryISO:' . $e->getMessage();
}
Expand Down Expand Up @@ -799,7 +800,7 @@ public function searchGeothesaurus(string $geoterm, int|null $geolevel = null, s

$sql .= ' ORDER BY CHAR_LENGTH(g.geoterm), g.geoterm ';

$result = $this->conn->execute_query($sql, $params);
$result = SymbUtil::execute_query($this->conn,$sql, $params);

$geoterms = $result->fetch_all(MYSQLI_ASSOC);
for($i=0; $i < count($geoterms); $i++) {
Expand Down Expand Up @@ -882,7 +883,7 @@ public function getGeoThesIDByName(string $geoTerm, int $geoLevel = null, array
$params = array_merge($params, $parentIDs);
}
try {
$result = $this->conn->execute_query($sql, $params);
$result = SymbUtil::execute_query($this->conn,$sql, $params);
$geoThesID = $result->fetch_all(MYSQLI_ASSOC);
$result->free();
return $geoThesID;
Expand All @@ -906,7 +907,7 @@ private function getGeoThesIDByIso3($iso3, $geoLevel = null){
array_push($params, $geoLevel);
}
try {
$result = $this->conn->execute_query($sql, $params);
$result = SymbUtil::execute_query($this->conn,$sql, $params);
$geoThesID = $result->fetch_all(MYSQLI_ASSOC);
$result->free();
return $geoThesID;
Expand Down
4 changes: 3 additions & 1 deletion classes/OccurrenceEditorDeterminations.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php
include_once($SERVER_ROOT.'/classes/OccurrenceEditorManager.php');
include_once($SERVER_ROOT.'/utilities/SymbUtil.php');

if($LANG_TAG != 'en' && file_exists($SERVER_ROOT.'/content/lang/classes/OccurrenceEditorDeterminations.'.$LANG_TAG.'.php')) include_once($SERVER_ROOT.'/content/lang/classes/OccurrenceEditorDeterminations.'.$LANG_TAG.'.php');
else include_once($SERVER_ROOT.'/content/lang/classes/OccurrenceEditorDeterminations.en.php');

Expand Down Expand Up @@ -267,7 +269,7 @@ private function updateBaseOccurrence($detId){
INNER JOIN omoccurdeterminations od on od.occid = i.occid
SET tid = ? WHERE detid = ?;
SQL;
$this->conn->execute_query($sql, [$taxonArr['tid'], $detId]);
SymbUtil::execute_query($this->conn,$sql, [$taxonArr['tid'], $detId]);
}
}
}
Expand Down
44 changes: 23 additions & 21 deletions classes/OccurrenceEditorManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
include_once($SERVER_ROOT.'/config/dbconnection.php');
include_once($SERVER_ROOT.'/classes/OccurrenceDuplicate.php');
include_once($SERVER_ROOT.'/classes/UuidFactory.php');
include_once($SERVER_ROOT.'/utilities/SymbUtil.php');

if($LANG_TAG != 'en' && file_exists($SERVER_ROOT.'/content/lang/collections/editor/occurrenceeditor.'.$LANG_TAG.'.php')) include_once($SERVER_ROOT.'/content/lang/collections/editor/occurrenceeditor.'.$LANG_TAG.'.php');
else include_once($SERVER_ROOT.'/content/lang/collections/editor/occurrenceeditor.en.php');

Expand Down Expand Up @@ -1184,10 +1186,10 @@ private function addLegacyIdentifers($occid) : void {
$sql_cnt = 'SELECT COUNT(*) AS cnt FROM omoccuridentifiers oi join omoccurrences o on o.occid = oi.occid WHERE o.occid = ?';
$sql_insert = 'INSERT INTO omoccuridentifiers(occid, identifierName, identifierValue, notes, modifiedUid) select occid,"legacyOtherCatalogNumber" as identifierName, otherCatalogNumbers as identifierValue, "Auto generated during record merge" as notes, ? as modifiedUid from omoccurrences where occid = ?';
try {
$result_cnt = $this->conn->execute_query($sql_cnt, [$occid]);
$result_cnt = SymbUtil::execute_query($this->conn,$sql_cnt, [$occid]);
$cnt = ($result_cnt->fetch_assoc())["cnt"];
if($cnt === 0) {
$this->conn->execute_query($sql_insert,[$GLOBALS['SYMB_UID'], $occid]);
SymbUtil::execute_query($this->conn,$sql_insert,[$GLOBALS['SYMB_UID'], $occid]);
}
} catch (mysqli_sql_exception $e) {
error_log('Error: Failed to add otherCatalogNumbers to omoccuridentifiers for occid '. $occid . ' :' . $e->getMessage());
Expand Down Expand Up @@ -1216,7 +1218,7 @@ private function updateBaseOccurrence($detId){
INNER JOIN omoccurdeterminations od on od.occid = i.occid
SET tid = ? WHERE detid = ?;
SQL;
$this->conn->execute_query($sql, [$taxonArr['tid'], $detId]);
SymbUtil::execute_query($this->conn,$sql, [$taxonArr['tid'], $detId]);
}
}
}
Expand Down Expand Up @@ -1572,13 +1574,13 @@ public function deleteOccurrence($delOccid){
DELETE FROM omoccurrences WHERE occid = ?
SQL;
$stage = $LANG['ERROR_TRYING_TO_DELETE'];
$this->conn->execute_query($sqlDel, [$delOccid]);
SymbUtil::execute_query($this->conn, $sqlDel, [$delOccid]);

$sql = <<<SQL
UPDATE omcollectionstats SET recordcnt = recordcnt - 1 WHERE collid = ?
SQL;
$stage = $LANG['ERROR_TRYING_TO_UPDATE_COL_CNT'];
$this->conn->execute_query($sql, [$this->collId]);
SymbUtil::execute_query($this->conn, $sql, [$this->collId]);

return true;
} catch (\Throwable $th) {
Expand Down Expand Up @@ -1695,15 +1697,15 @@ public function mergeRecords($targetOccid,$sourceOccid){
if($sqlFrag){
$sqlIns = 'UPDATE IGNORE omoccurrences SET ' . substr($sqlFrag,1) . ' WHERE occid = ?';
$stage = $LANG['ABORT_DUE_TO_ERROR'];
$this->conn->execute_query($sqlIns, [$targetOccid]);
SymbUtil::execute_query($this->conn, $sqlIns, [$targetOccid]);
}

// Anon function for util of merging determinations
$get_current_determinations = function ($occid) {
$sql =<<<'SQL'
SELECT detid FROM omoccurdeterminations where occid = ? and isCurrent = 1;
SQL;
$result = $this->conn->execute_query($sql, [$occid]);
$result = SymbUtil::execute_query($this->conn, $sql, [$occid]);
return array_map(fn($v) => $v[0], $result->fetch_all());
};

Expand All @@ -1723,7 +1725,7 @@ public function mergeRecords($targetOccid,$sourceOccid){
AND source.identifiedBy = target.identifiedBy
);
SQL;
$this->conn->execute_query($sql, [
SymbUtil::execute_query($this->conn, $sql, [
//Update To This Occid
$targetOccid,
//From Options of This Occid
Expand All @@ -1743,7 +1745,7 @@ public function mergeRecords($targetOccid,$sourceOccid){
SET isCurrent = 0
WHERE occid = ? AND isCurrent = 1 AND detid NOT IN ($parameters);
SQL;
$this->conn->execute_query($sql, array_merge([$targetOccid], $currentDeterminations));
SymbUtil::execute_query($this->conn, $sql, array_merge([$targetOccid], $currentDeterminations));
}

// Get New Current determination and updateBaseOccurrence to match
Expand All @@ -1757,85 +1759,85 @@ public function mergeRecords($targetOccid,$sourceOccid){
UPDATE images SET occid = ? WHERE occid = ?;
SQL;
$stage = $LANG['ERROR_REMAPPING_IMAGES'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap paleo
if(isset($this->collMap['paleoActivated'])){
$sql = <<<'SQL'
UPDATE IGNORE omoccurpaleo SET occid = ? WHERE occid = ?;
SQL;
$stage = $LANG['ERROR_REMAPPING_PALEOS'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);
}

//Delete source occurrence edits
$sql = <<<'SQL'
DELETE FROM omoccuredits WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_OCC_EDITS'];
$this->conn->execute_query($sql, [$sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$sourceOccid]);

//Remap associations
$sql = <<<'SQL'
UPDATE IGNORE omoccurassociations SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_ASSOCS_1'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

$sql = <<<'SQL'
UPDATE IGNORE omoccurassociations SET occidAssociate = ? WHERE occidAssociate = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_ASSOCS_2'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap comments
$sql = <<<'SQL'
UPDATE IGNORE omoccurcomments SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_COMMENTS'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap genetic resources
$sql = <<<'SQL'
UPDATE IGNORE omoccurgenetic SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_GENETIC'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap identifiers
$sql = <<<'SQL'
UPDATE IGNORE omoccuridentifiers SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_OCCIDS'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap exsiccati
$sql = <<<'SQL'
UPDATE IGNORE omexsiccatiocclink SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_EXS'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap occurrence dataset links
$sql = <<<'SQL'
UPDATE IGNORE omoccurdatasetlink SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_DATASET'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap loans
$sql = <<<'SQL'
UPDATE IGNORE omoccurloanslink SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_LOANS'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

//Remap checklists voucher links
$sql = <<<'SQL'
UPDATE IGNORE fmvouchers SET occid = ? WHERE occid = ?
SQL;
$stage = $LANG['ERROR_REMAPPING_VOUCHER'];
$this->conn->execute_query($sql, [$targetOccid, $sourceOccid]);
SymbUtil::execute_query($this->conn, $sql, [$targetOccid, $sourceOccid]);

if(!$this->deleteOccurrence($sourceOccid)){
error_log(
Expand Down
5 changes: 3 additions & 2 deletions classes/OmCollections.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

include_once($SERVER_ROOT.'/classes/Manager.php');
include_once($SERVER_ROOT.'/classes/UuidFactory.php');
include_once($SERVER_ROOT.'/utilities/SymbUtil.php');

class OmCollections extends Manager{

Expand All @@ -16,14 +17,14 @@ public function __destruct(){
}

// Needed to
private function isCollUnique(String $collectionCode, String $institutionCode): bool {
public function isCollUnique(String $collectionCode, String $institutionCode): bool {
global $CLIENT_ROOT;
try {
$sql = <<<'SQL'
SELECT collectionName, collid FROM omcollections
WHERE collid != ? AND collectionCode = ? AND institutionCode = ?
SQL;
$result = $this->conn->execute_query($sql, [$this->collid, $collectionCode, $institutionCode]);
$result = SymbUtil::execute_query($this->conn, $sql, [$this->collid, $collectionCode, $institutionCode]);
if($col = $result->fetch_object()) {
$this->errorMessage = 'Error: Duplicate collection + institution code found in '
. '<a target="_blank" href="'
Expand Down
34 changes: 34 additions & 0 deletions utilities/SymbUtil.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
class SymbUtil {
/*
* This function is a wrapper for mysqli_execute_query. Not all Symbiota portals can update version so this an effort to fix backward compat issues
*
* @param mysqli $conn
* @param string $sql
* @param string $params
*/
static function execute_query(mysqli $conn, string $sql, array $params): mysqli_result | bool {
//This is supported from 4 to 8
$version = phpversion();
[$major, $minor, $patch] = explode('.', $version);

if($major >= 8 && $minor >= 2) {
return mysqli_execute_query($conn, $sql, $params);
} else {
$bind_params_str = '';
foreach($params as $param) {
//Could just bind string instead?
if(gettype($param) === 'string') {
$bind_params_str .= 's';
} else {
$bind_params_str .= 'i';
}
}
$stmt = $conn->prepare($sql);
$stmt->bind_param($bind_params_str,...$params);
$stmt->execute();
return $stmt->get_result();
}
}
}
?>

0 comments on commit 6279f1e

Please sign in to comment.