From 73fcb96bb4729759e60fdbeabf7293a7f3eedb30 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Thu, 2 Jun 2022 11:38:09 +1000 Subject: [PATCH] Ensure only one data record per token. Applies to newly activated surveys --- .../limesurvey/admin/activate_functions.php | 4 +- .../expressions/LimeExpressionManager.php | 79 ++++++++++--------- include/limesurvey/save.php | 38 +++++---- 3 files changed, 66 insertions(+), 55 deletions(-) diff --git a/include/limesurvey/admin/activate_functions.php b/include/limesurvey/admin/activate_functions.php index 1998fc32..01d75007 100644 --- a/include/limesurvey/admin/activate_functions.php +++ b/include/limesurvey/admin/activate_functions.php @@ -408,8 +408,8 @@ function activateSurvey($postsid,$surveyid, $scriptname='admin.php') $execresult=$dict->ExecuteSQLArray($sqlarray,1); - //queXS Addition - add an index on the token - $createtokenindex = $dict->CreateIndexSQL("{$tabname}_idx", $tabname, array('token')); + //queXS Addition - add a UNIQUE index on the token + $createtokenindex = $dict->CreateIndexSQL("{$tabname}_idx", $tabname, array('token'),array('UNIQUE')); $dict->ExecuteSQLArray($createtokenindex, false) or safe_die ("Failed to create token index
$createtokenindex

".$connect->ErrorMsg()); if ($execresult==0 || $execresult==1) diff --git a/include/limesurvey/classes/expressions/LimeExpressionManager.php b/include/limesurvey/classes/expressions/LimeExpressionManager.php index 7913cd16..d55a895f 100644 --- a/include/limesurvey/classes/expressions/LimeExpressionManager.php +++ b/include/limesurvey/classes/expressions/LimeExpressionManager.php @@ -4646,44 +4646,49 @@ $_SESSION['datestamp']=$datestamp; if ($this->surveyOptions['active'] && !isset($_SESSION['srid'])) { - // Create initial insert row for this record - $sdata = array( - "datestamp"=>$datestamp, - "ipaddr"=>(($this->surveyOptions['ipaddr']) ? getIPAddress() : ''), - "startlanguage"=>$this->surveyOptions['startlanguage'], - "token"=>($this->surveyOptions['token']), - "refurl"=>(($this->surveyOptions['refurl']) ? getenv("HTTP_REFERER") : NULL), - "startdate"=>$datestamp, - ); - //One of the strengths of ADOdb's AutoExecute() is that only valid field names for $table are updated - if ($connect->AutoExecute($this->surveyOptions['tablename'], $sdata,'INSERT')) // Checked - { - $srid = $connect->Insert_ID($this->surveyOptions['tablename'],"id"); - $_SESSION['srid'] = $srid; - } - else - { - $message .= $this->gT("Unable to insert record into survey table: ") .$connect->ErrorMsg() . "
"; - $_SESSION['flashmessage'] = $message; - echo $message; - } - //Insert Row for Timings, if needed - if ($this->surveyOptions['savetimings']) { - $tdata = array( - 'id'=>$srid, - 'interviewtime'=>0 - ); - if ($connect->AutoExecute($this->surveyOptions['tablename_timings'], $tdata,'INSERT')) // Checked - { - $trid = $connect->Insert_ID($this->surveyOptions['tablename_timings'],"sid"); + $srid = $connect->GetOne("SELECT id FROM ".$this->surveyOptions['tablename']." WHERE token='".$this->surveyOptions['token']."'"); + if (is_null($srid)) { + // Create initial insert row for this record + $sdata = array( + "datestamp"=>$datestamp, + "ipaddr"=>(($this->surveyOptions['ipaddr']) ? getIPAddress() : ''), + "startlanguage"=>$this->surveyOptions['startlanguage'], + "token"=>($this->surveyOptions['token']), + "refurl"=>(($this->surveyOptions['refurl']) ? getenv("HTTP_REFERER") : NULL), + "startdate"=>$datestamp, + ); + //One of the strengths of ADOdb's AutoExecute() is that only valid field names for $table are updated + if ($connect->AutoExecute($this->surveyOptions['tablename'], $sdata,'INSERT')) // Checked + { + $srid = $connect->Insert_ID($this->surveyOptions['tablename'],"id"); + $_SESSION['srid'] = $srid; + } + else + { + $message .= $this->gT("Unable to insert record into survey table: ") .$connect->ErrorMsg() . "
"; + $_SESSION['flashmessage'] = $message; + echo $message; } - else - { - $message .= $this->gT("Unable to insert record into timings table "). $connect->ErrorMsg() . "
"; - $_SESSION['flashmessage'] = $message; - echo $message; - } - } + //Insert Row for Timings, if needed + if ($this->surveyOptions['savetimings']) { + $tdata = array( + 'id'=>$srid, + 'interviewtime'=>0 + ); + if ($connect->AutoExecute($this->surveyOptions['tablename_timings'], $tdata,'INSERT')) // Checked + { + $trid = $connect->Insert_ID($this->surveyOptions['tablename_timings'],"sid"); + } + else + { + $message .= $this->gT("Unable to insert record into timings table "). $connect->ErrorMsg() . "
"; + $_SESSION['flashmessage'] = $message; + echo $message; + } + } + } else { + $_SESSION['srid'] = $srid; + } } if (count($updatedValues) > 0 || $finished) diff --git a/include/limesurvey/save.php b/include/limesurvey/save.php index 0e25828d..8426ee13 100644 --- a/include/limesurvey/save.php +++ b/include/limesurvey/save.php @@ -130,22 +130,28 @@ //INSERT BLANK RECORD INTO "survey_x" if one doesn't already exist if (!isset($_SESSION['srid'])) { - $today = date_shift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust); - $sdata = array("datestamp"=>$today, - "ipaddr"=>getIPAddress(), - "startlanguage"=>$_SESSION['s_lang'], - "refurl"=>getenv("HTTP_REFERER"), - "token" => $_POST['token']); - //One of the strengths of ADOdb's AutoExecute() is that only valid field names for $table are updated - if ($connect->AutoExecute($thissurvey['tablename'], $sdata,'INSERT')) // Checked - { - $srid = $connect->Insert_ID($thissurvey['tablename'],"sid"); - $_SESSION['srid'] = $srid; - } - else - { - safe_die("Unable to insert record into survey table.

".$connect->ErrorMsg()); - } + $result = $connect->GetOne("SELECT id FROM ".$thissurvey['tablename']." WHERE token='{$_POST['token']}'"); + if (is_null($result)) { + + $today = date_shift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust); + $sdata = array("datestamp"=>$today, + "ipaddr"=>getIPAddress(), + "startlanguage"=>$_SESSION['s_lang'], + "refurl"=>getenv("HTTP_REFERER"), + "token" => $_POST['token']); + //One of the strengths of ADOdb's AutoExecute() is that only valid field names for $table are updated + if ($connect->AutoExecute($thissurvey['tablename'], $sdata,'INSERT')) // Checked + { + $srid = $connect->Insert_ID($thissurvey['tablename'],"sid"); + $_SESSION['srid'] = $srid; + } + else + { + safe_die("Unable to insert record into survey table.

".$connect->ErrorMsg()); + } + } else { + $_SESSION['srid'] = $result; + } } //CREATE ENTRY INTO "saved_control" $today = date_shift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust);