mirror of
https://github.com/YunoHost-Apps/limesurvey_ynh.git
synced 2024-09-03 19:36:32 +02:00
5200 lines
210 KiB
PHP
5200 lines
210 KiB
PHP
<?php
|
|
/*
|
|
* LimeSurvey
|
|
* Copyright (C) 2007-2011 The LimeSurvey Project Team / Carsten Schmitz
|
|
* All rights reserved.
|
|
* License: GNU/GPL License v2 or later, see LICENSE.php
|
|
* LimeSurvey is free software. This version may have been modified pursuant
|
|
* to the GNU General Public License, and as distributed it includes or
|
|
* is derivative of works licensed under the GNU General Public License or
|
|
* other free or open source software licenses.
|
|
* See COPYRIGHT.php for copyright notices and details.
|
|
*/
|
|
|
|
|
|
/**
|
|
* This function imports an old-school question group file (*.csv,*.sql)
|
|
*
|
|
* @param mixed $sFullFilePath Full file patch to the import file
|
|
* @param mixed $iNewSID Survey ID to which the question is attached
|
|
*/
|
|
function CSVImportGroup($sFullFilePath, $iNewSID)
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
|
|
$aLIDReplacements=array();
|
|
$aQIDReplacements = array(); // this array will have the "new qid" for the questions, the key will be the "old qid"
|
|
$aGIDReplacements = array();
|
|
$handle = fopen($sFullFilePath, "r");
|
|
while (!feof($handle))
|
|
{
|
|
$buffer = fgets($handle);
|
|
$bigarray[] = $buffer;
|
|
}
|
|
fclose($handle);
|
|
|
|
if (substr($bigarray[0], 0, 23) != "# LimeSurvey Group Dump")
|
|
{
|
|
$results['fatalerror'] = $clang->gT("This file is not a LimeSurvey question file. Import failed.");
|
|
$importversion=0;
|
|
}
|
|
else
|
|
{
|
|
$importversion=(int)trim(substr($bigarray[1],12));
|
|
}
|
|
|
|
if ((int)$importversion<112)
|
|
{
|
|
$results['fatalerror'] = $clang->gT("This file is too old. Only files from LimeSurvey version 1.50 (DBVersion 112) and newer are supported.");
|
|
}
|
|
|
|
for ($i=0; $i<9; $i++) //skipping the first lines that are not needed
|
|
{
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//GROUPS
|
|
if (array_search("# QUESTIONS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTIONS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUESTIONS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTIONS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$grouparray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//QUESTIONS
|
|
if (array_search("# ANSWERS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ANSWERS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# ANSWERS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ANSWERS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2)
|
|
{
|
|
$questionarray[] = $bigarray[$i];
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//ANSWERS
|
|
if (array_search("# CONDITIONS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# CONDITIONS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# CONDITIONS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# CONDITIONS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2)
|
|
{
|
|
$answerarray[] = str_replace("`default`", "`default_value`", $bigarray[$i]);
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//CONDITIONS
|
|
if (array_search("# LABELSETS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELSETS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# LABELSETS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELSETS TABLE\r\n", $bigarray);
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$conditionsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LABELSETS
|
|
if (array_search("# LABELS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# LABELS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$labelsetsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LABELS
|
|
if (array_search("# QUESTION_ATTRIBUTES TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTION_ATTRIBUTES TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUESTION_ATTRIBUTES TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTION_ATTRIBUTES TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$labelsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//Question attributes
|
|
if (!isset($noconditions) || $noconditions != "Y")
|
|
{
|
|
// stoppoint is the last line number
|
|
// this is an empty line after the QA CSV lines
|
|
$stoppoint = count($bigarray)-1;
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<=$stoppoint-1) {$question_attributesarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
$countgroups=0;
|
|
if (isset($questionarray))
|
|
{
|
|
$questionfieldnames=str_getcsv($questionarray[0],',','"');
|
|
unset($questionarray[0]);
|
|
$countquestions = 0;
|
|
}
|
|
|
|
if (isset($answerarray))
|
|
{
|
|
$answerfieldnames=str_getcsv($answerarray[0],',','"');
|
|
unset($answerarray[0]);
|
|
$countanswers = count($answerarray);
|
|
}
|
|
else {$countanswers=0;}
|
|
|
|
$aLanguagesSupported = array(); // this array will keep all the languages supported for the survey
|
|
|
|
$sBaseLanguage = Survey::model()->findByPk($iNewSID)->language;
|
|
$aLanguagesSupported[]=$sBaseLanguage; // adds the base language to the list of supported languages
|
|
$aLanguagesSupported=array_merge($aLanguagesSupported,Survey::model()->findByPk($iNewSID)->additionalLanguages);
|
|
|
|
|
|
|
|
|
|
// Let's check that imported objects support at least the survey's baselang
|
|
$langcode = Survey::model()->findByPk($iNewSID)->language;
|
|
if (isset($grouparray))
|
|
{
|
|
$groupfieldnames = str_getcsv($grouparray[0],',','"');
|
|
$langfieldnum = array_search("language", $groupfieldnames);
|
|
$gidfieldnum = array_search("gid", $groupfieldnames);
|
|
$groupssupportbaselang = doesImportArraySupportLanguage($grouparray,Array($gidfieldnum),$langfieldnum,$sBaseLanguage,true);
|
|
if (!$groupssupportbaselang)
|
|
{
|
|
$results['fatalerror']=$clang->gT("You can't import a group which doesn't support at least the survey base language.");
|
|
return $results;
|
|
}
|
|
}
|
|
|
|
if (isset($questionarray))
|
|
{
|
|
$langfieldnum = array_search("language", $questionfieldnames);
|
|
$qidfieldnum = array_search("qid", $questionfieldnames);
|
|
$questionssupportbaselang = doesImportArraySupportLanguage($questionarray,Array($qidfieldnum), $langfieldnum,$sBaseLanguage,true);
|
|
if (!$questionssupportbaselang)
|
|
{
|
|
$results['fatalerror']=$clang->gT("You can't import a question which doesn't support at least the survey base language.");
|
|
return $results;
|
|
}
|
|
}
|
|
|
|
if ($countanswers > 0)
|
|
{
|
|
$langfieldnum = array_search("language", $answerfieldnames);
|
|
$answercodefilednum1 = array_search("qid", $answerfieldnames);
|
|
$answercodefilednum2 = array_search("code", $answerfieldnames);
|
|
$answercodekeysarr = Array($answercodefilednum1,$answercodefilednum2);
|
|
$answerssupportbaselang = doesImportArraySupportLanguage($answerarray,$answercodekeysarr,$langfieldnum,$sBaseLanguage);
|
|
if (!$answerssupportbaselang)
|
|
{
|
|
$results['fatalerror']=$clang->gT("You can't import answers which doesn't support at least the survey base language.");
|
|
return $results;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count($labelsetsarray) > 1)
|
|
{
|
|
$labelsetfieldname = str_getcsv($labelsetsarray[0],',','"');
|
|
$langfieldnum = array_search("languages", $labelsetfieldname);
|
|
$lidfilednum = array_search("lid", $labelsetfieldname);
|
|
$labelsetssupportbaselang = doesImportArraySupportLanguage($labelsetsarray,Array($lidfilednum),$langfieldnum,$sBaseLanguage,true);
|
|
if (!$labelsetssupportbaselang)
|
|
{
|
|
$results['fatalerror']=$clang->gT("You can't import label sets which don't support the current survey's base language");
|
|
return $results;
|
|
}
|
|
}
|
|
// I assume that if a labelset supports the survey's baselang,
|
|
// then it's labels do support it as well
|
|
|
|
//DO ANY LABELSETS FIRST, SO WE CAN KNOW WHAT THEIR NEW LID IS FOR THE QUESTIONS
|
|
$results['labelsets']=0;
|
|
$qtypes = getQuestionTypeList("" ,"array");
|
|
$results['labels']=0;
|
|
$results['labelsets']=0;
|
|
$results['answers']=0;
|
|
$results['subquestions']=0;
|
|
|
|
//Do label sets
|
|
if (isset($labelsetsarray) && $labelsetsarray)
|
|
{
|
|
$csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets
|
|
$count=0;
|
|
foreach ($labelsetsarray as $lsa) {
|
|
$fieldorders =str_getcsv($labelsetsarray[0],',','"');
|
|
$fieldcontents=str_getcsv($lsa,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
$labelsetrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
// Save old labelid
|
|
$oldlid=$labelsetrowdata['lid'];
|
|
|
|
unset($labelsetrowdata['lid']);
|
|
$newvalues=array_values($labelsetrowdata);
|
|
$lsainsert = "INSERT INTO {{labelsets}} (".implode(',',array_keys($labelsetrowdata)).") VALUES (".implode(',',$newvalues).")"; //handle db prefix
|
|
$lsiresult=Yii::app()->db->createCommand($lsainsert)->query();
|
|
$results['labelsets']++;
|
|
// Get the new insert id for the labels inside this labelset
|
|
$newlid=getLastInsertID('{{labelsets}}');
|
|
|
|
if ($labelsarray) {
|
|
$count=0;
|
|
foreach ($labelsarray as $la) {
|
|
$lfieldorders =str_getcsv($labelsarray[0],',','"');
|
|
$lfieldcontents=str_getcsv($la,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
// Combine into one array with keys and values since its easier to handle
|
|
$labelrowdata=array_combine($lfieldorders,$lfieldcontents);
|
|
$labellid=$labelrowdata['lid'];
|
|
if ($importversion<=132)
|
|
{
|
|
$labelrowdata["assessment_value"]=(int)$labelrowdata["code"];
|
|
}
|
|
if ($labellid == $oldlid) {
|
|
$labelrowdata['lid']=$newlid;
|
|
|
|
// translate internal links
|
|
$labelrowdata['title']=translateLinks('label', $oldlid, $newlid, $labelrowdata['title']);
|
|
|
|
$newvalues=array_values($labelrowdata);
|
|
$lainsert = "INSERT INTO {{labels}} (".implode(',',array_keys($labelrowdata)).") VALUES (".implode(',',$newvalues).")"; //handle db prefix
|
|
$liresult=Yii::app()->db->createCommand($lainsert)->query();
|
|
if ($liresult!==false) $results['labels']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//CHECK FOR DUPLICATE LABELSETS
|
|
$thisset="";
|
|
|
|
$query2 = "SELECT code, title, sortorder, language, assessment_value
|
|
FROM {{labels}}
|
|
WHERE lid=".$newlid."
|
|
ORDER BY language, sortorder, code";
|
|
$result2 = Yii::app()->db->createCommand($query2);
|
|
foreach($result2->readAll() as $row2)
|
|
{
|
|
$row2 = array_values($row2);
|
|
$thisset .= implode('.', $row2);
|
|
} // while
|
|
$newcs=dechex(crc32($thisset)*1);
|
|
unset($lsmatch);
|
|
if (isset($csarray))
|
|
{
|
|
foreach($csarray as $key=>$val)
|
|
{
|
|
if ($val == $newcs)
|
|
{
|
|
$lsmatch=$key;
|
|
}
|
|
}
|
|
}
|
|
if (isset($lsmatch) || !Permission::model()->hasGlobalPermission('labelsets','import'))
|
|
{
|
|
//There is a matching labelset or the user is not allowed to edit labels -
|
|
// So, we will delete this one and refer to the matched one.
|
|
$query = "DELETE FROM {{labels}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->execute();
|
|
$results['labels']=$results['labels'] - $result;
|
|
|
|
$query = "DELETE FROM {{labelsets}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->execute();
|
|
$results['labelsets']=$results['labelsets']-$result;
|
|
$newlid=$lsmatch;
|
|
}
|
|
else
|
|
{
|
|
//There isn't a matching labelset, add this checksum to the $csarray array
|
|
$csarray[$newlid]=$newcs;
|
|
}
|
|
//END CHECK FOR DUPLICATES
|
|
$aLIDReplacements[$oldlid]=$newlid;
|
|
}
|
|
}
|
|
|
|
// Import groups
|
|
if (isset($grouparray) && $grouparray)
|
|
{
|
|
// do GROUPS
|
|
$gafieldorders=str_getcsv($grouparray[0],',','"');
|
|
unset($grouparray[0]);
|
|
$newgid = 0;
|
|
$group_order = 0; // just to initialize this variable
|
|
|
|
foreach ($grouparray as $ga)
|
|
{
|
|
$gacfieldcontents=str_getcsv($ga,',','"');
|
|
$grouprowdata=array_combine($gafieldorders,$gacfieldcontents);
|
|
|
|
// Skip not supported languages
|
|
if (!in_array($grouprowdata['language'],$aLanguagesSupported))
|
|
{
|
|
$skippedlanguages[]=$grouprowdata['language']; // this is for the message in the end.
|
|
continue;
|
|
}
|
|
|
|
// replace the sid
|
|
$iOldSID=$grouprowdata['sid'];
|
|
$grouprowdata['sid']=$iNewSID;
|
|
|
|
// replace the gid or remove it if needed (it also will calculate the group order if is a new group)
|
|
$oldgid=$grouprowdata['gid'];
|
|
if ($newgid == 0)
|
|
{
|
|
unset($grouprowdata['gid']);
|
|
|
|
// find the maximum group order and use this grouporder+1 to assign it to the new group
|
|
$qmaxgo = "select max(group_order) as maxgo from {{groups}} where sid=$iNewSID";
|
|
$gres = Yii::app()->db->createCommand($qmaxgo)->query();
|
|
$grow=$gres->read();
|
|
$group_order = $grow['maxgo']+1;
|
|
}
|
|
else
|
|
$grouprowdata['gid'] = $newgid;
|
|
|
|
$grouprowdata["group_order"]= $group_order;
|
|
|
|
// Everything set - now insert it
|
|
$grouprowdata=array_map('convertCSVReturnToReturn', $grouprowdata);
|
|
|
|
// translate internal links
|
|
$grouprowdata['group_name']=translateLinks('survey', $iOldSID, $iNewSID, $grouprowdata['group_name']);
|
|
$grouprowdata['description']=translateLinks('survey', $iOldSID, $iNewSID, $grouprowdata['description']);
|
|
|
|
$gres = Yii::app()->db->createCommand()->insert('{{groups}}', $grouprowdata);
|
|
|
|
//GET NEW GID .... if is not done before and we count a group if a new gid is required
|
|
if ($newgid == 0)
|
|
{
|
|
$newgid = getLastInsertID('{{groups}}');
|
|
$countgroups++;
|
|
}
|
|
}
|
|
// GROUPS is DONE
|
|
|
|
// Import questions
|
|
if (isset($questionarray) && $questionarray)
|
|
{
|
|
|
|
foreach ($questionarray as $qa)
|
|
{
|
|
$qacfieldcontents=str_getcsv($qa,',','"');
|
|
$questionrowdata=array_combine($questionfieldnames,$qacfieldcontents);
|
|
$questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata);
|
|
$questionrowdata["type"]=strtoupper($questionrowdata["type"]);
|
|
|
|
// Skip not supported languages
|
|
if (!in_array($questionrowdata['language'],$aLanguagesSupported))
|
|
continue;
|
|
|
|
// replace the sid
|
|
$questionrowdata["sid"] = $iNewSID;
|
|
|
|
// replace the gid (if the gid is not in the oldgid it means there is a problem with the exported record, so skip it)
|
|
if ($questionrowdata['gid'] == $oldgid)
|
|
$questionrowdata['gid'] = $newgid;
|
|
else
|
|
continue; // a problem with this question record -> don't consider
|
|
|
|
if (isset($aQIDReplacements[$questionrowdata['qid']]))
|
|
{
|
|
$questionrowdata['qid']=$aQIDReplacements[$questionrowdata['qid']];
|
|
}
|
|
else
|
|
{
|
|
$oldqid = $questionrowdata['qid'];
|
|
unset($questionrowdata['qid']);
|
|
}
|
|
|
|
// Save the following values - will need them for proper conversion later if ((int)$questionrowdata['lid']>0)
|
|
unset($oldlid1); unset($oldlid2);
|
|
if ((isset($questionrowdata['lid']) && $questionrowdata['lid']>0))
|
|
{
|
|
$oldlid1=$questionrowdata['lid'];
|
|
}
|
|
if ((isset($questionrowdata['lid1']) && $questionrowdata['lid1']>0))
|
|
{
|
|
$oldlid2=$questionrowdata['lid1'];
|
|
}
|
|
unset($questionrowdata['lid']);
|
|
unset($questionrowdata['lid1']);
|
|
if ($questionrowdata['type']=='W')
|
|
{
|
|
$questionrowdata['type']='!';
|
|
}
|
|
elseif ($questionrowdata['type']=='Z')
|
|
{
|
|
$questionrowdata['type']='L';
|
|
}
|
|
|
|
if (!isset($questionrowdata["question_order"]) || $questionrowdata["question_order"]=='') {$questionrowdata["question_order"]=0;}
|
|
|
|
$questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata);
|
|
|
|
// translate internal links
|
|
$questionrowdata['title']=translateLinks('survey', $iOldSID, $iNewSID, $questionrowdata['title']);
|
|
$questionrowdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $questionrowdata['question']);
|
|
$questionrowdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $questionrowdata['help']);
|
|
|
|
$newvalues=array_values($questionrowdata);
|
|
$qres = Yii::app()->db->createCommand()->insert('{{questions}}', $questionrowdata);
|
|
|
|
$results['questions']++;
|
|
|
|
//GET NEW QID .... if is not done before and we count a question if a new qid is required
|
|
if (isset($questionrowdata['qid']))
|
|
{
|
|
$saveqid=$questionrowdata['qid'];
|
|
}
|
|
else
|
|
{
|
|
$aQIDReplacements[$oldqid]=getLastInsertID('{{questions}}');
|
|
$saveqid=$aQIDReplacements[$oldqid];
|
|
}
|
|
$qtypes = getQuestionTypeList("" ,"array");
|
|
$aSQIDReplacements=array();
|
|
|
|
// Now we will fix up old label sets where they are used as answers
|
|
if ((isset($oldlid1) || isset($oldlid2)) && ($qtypes[$questionrowdata['type']]['answerscales']>0 || $qtypes[$questionrowdata['type']]['subquestions']>1))
|
|
{
|
|
$query="select * from {{labels}} where lid={$aLIDReplacements[$oldlid1]} and language='{$questionrowdata['language']}'";
|
|
$oldlabelsresult=Yii::app()->db->createCommand($query)->query();
|
|
foreach($oldlabelsresult->readAll() as $labelrow)
|
|
{
|
|
if (in_array($labelrow['language'],$aLanguagesSupported))
|
|
{
|
|
|
|
if ($qtypes[$questionrowdata['type']]['subquestions']<2)
|
|
{
|
|
$qinsert = "insert INTO {{answers}} (qid,code,answer,sortorder,language,assessment_value)
|
|
VALUES ({$aQIDReplacements[$oldqid]},'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."','".$labelrow['assessment_value']."')";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie($clang->gT("Error").": Failed to insert answer (lid1) <br />\n$qinsert<br />\n");
|
|
}
|
|
else
|
|
{
|
|
if (isset($aSQIDReplacements[$labelrow['code'].'_'.$saveqid])){
|
|
$fieldname='qid,';
|
|
$data=$aSQIDReplacements[$labelrow['code'].'_'.$saveqid].',';
|
|
}
|
|
else
|
|
{
|
|
$fieldname='' ;
|
|
$data='';
|
|
}
|
|
|
|
$qinsert = "insert INTO {{questions}} ($fieldname parent_qid,title,question,question_order,language,scale_id,type, sid, gid)
|
|
VALUES ($data{$aQIDReplacements[$oldqid]},'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."',1,'{$questionrowdata['type']}',{$questionrowdata['sid']},{$questionrowdata['gid']})";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie ($clang->gT("Error").": Failed to insert question <br />\n$qinsert<br />\n");
|
|
if ($fieldname=='')
|
|
{
|
|
$aSQIDReplacements[$labelrow['code'].'_'.$saveqid]=getLastInsertID('{{questions}}');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (isset($oldlid2) && $qtypes[$questionrowdata['type']]['answerscales']>1)
|
|
{
|
|
$query="select * from {{labels}} where lid={$aLIDReplacements[$oldlid2]} and language='{$questionrowdata['language']}'";
|
|
$oldlabelsresult=Yii::app()->db->createCommand($query)->query();
|
|
foreach($oldlabelsresult->readAll() as $labelrow)
|
|
{
|
|
$qinsert = "insert INTO {{answers}} (qid,code,answer,sortorder,language,assessment_value,scale_id)
|
|
VALUES ({$aQIDReplacements[$oldqid]},'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."','".$labelrow['assessment_value']."',1)";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie ($clang->gT("Error").": Failed to insert answer (lid2)<br />\n$qinsert<br />\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Do answers
|
|
$results['subquestions']=0;
|
|
if (isset($answerarray) && $answerarray)
|
|
{
|
|
foreach ($answerarray as $aa)
|
|
{
|
|
$answerfieldcontents=str_getcsv($aa,',','"');
|
|
$answerrowdata=array_combine($answerfieldnames,$answerfieldcontents);
|
|
if ($answerrowdata===false)
|
|
{
|
|
$importquestion.='<br />'.$clang->gT("Faulty line in import - fields and data don't match").":".implode(',',$answerfieldcontents);
|
|
}
|
|
// Skip not supported languages
|
|
if (!in_array($answerrowdata['language'],$aLanguagesSupported))
|
|
continue;
|
|
|
|
// replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this answer is orphan -> error, skip this record)
|
|
if (isset($aQIDReplacements[$answerrowdata["qid"]]))
|
|
$answerrowdata["qid"] = $aQIDReplacements[$answerrowdata["qid"]];
|
|
else
|
|
continue; // a problem with this answer record -> don't consider
|
|
|
|
if ($importversion<=132)
|
|
{
|
|
$answerrowdata["assessment_value"]=(int)$answerrowdata["code"];
|
|
}
|
|
// Convert default values for single select questions
|
|
$query = 'select type,gid from {{questions}} where qid='.$answerrowdata["qid"];
|
|
$res = Yii::app()->db->createCommand($query)->query();
|
|
$questiontemp = $res->read();
|
|
$oldquestion['newtype']=$questiontemp['type'];
|
|
$oldquestion['gid']=$questiontemp['gid'];
|
|
if ($answerrowdata['default_value']=='Y' && ($oldquestion['newtype']=='L' || $oldquestion['newtype']=='O' || $oldquestion['newtype']=='!'))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid']=$newqid;
|
|
$insertdata['language']=$answerrowdata['language'];
|
|
$insertdata['defaultvalue']=$answerrowdata['answer'];
|
|
$qres = Yii::app()->db->createCommand()->insert('{{defaultvalues}}', $insertdata);
|
|
}
|
|
// translate internal links
|
|
$answerrowdata['answer']=translateLinks('survey', $iOldSID, $iNewSID, $answerrowdata['answer']);
|
|
// Everything set - now insert it
|
|
$answerrowdata = array_map('convertCSVReturnToReturn', $answerrowdata);
|
|
|
|
if ($qtypes[$oldquestion['newtype']]['subquestions']>0) //hmmm.. this is really a subquestion
|
|
{
|
|
$questionrowdata=array();
|
|
if (isset($aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']])){
|
|
$questionrowdata['qid']=$aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']];
|
|
}
|
|
$questionrowdata['parent_qid']=$answerrowdata['qid'];;
|
|
$questionrowdata['sid']=$iNewSID;
|
|
$questionrowdata['gid']=$oldquestion['gid'];
|
|
$questionrowdata['title']=$answerrowdata['code'];
|
|
$questionrowdata['question']=$answerrowdata['answer'];
|
|
$questionrowdata['question_order']=$answerrowdata['sortorder'];
|
|
$questionrowdata['language']=$answerrowdata['language'];
|
|
$questionrowdata['type']=$oldquestion['newtype'];
|
|
|
|
$qres = Yii::app()->db->createCommand()->insert('{{questions}}', $questionrowdata);
|
|
if (!isset($questionrowdata['qid']))
|
|
{
|
|
$aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']]=getLastInsertID('{{questions}}');
|
|
}
|
|
|
|
$results['subquestions']++;
|
|
// also convert default values subquestions for multiple choice
|
|
if ($answerrowdata['default_value']=='Y' && ($oldquestion['newtype']=='M' || $oldquestion['newtype']=='P'))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid']=$newqid;
|
|
$insertdata['sqid']=$aSQIDReplacements[$answerrowdata['code']];
|
|
$insertdata['language']=$answerrowdata['language'];
|
|
$insertdata['defaultvalue']='Y';
|
|
$qres = Yii::app()->db->createCommand()->insert('{{defaultvalues}}', $insertdata);
|
|
}
|
|
|
|
}
|
|
else // insert answers
|
|
{
|
|
unset($answerrowdata['default_value']);
|
|
$ares = Yii::app()->db->createCommand()->insert('{{answers}}', $answerrowdata);
|
|
$results['answers']++;
|
|
}
|
|
|
|
}
|
|
}
|
|
// ANSWERS is DONE
|
|
|
|
// Fix sortorder of the groups - if users removed groups manually from the csv file there would be gaps
|
|
fixSortOrderGroups($surveyid);
|
|
//... and for the questions inside the groups
|
|
// get all group ids and fix questions inside each group
|
|
$gquery = "SELECT gid FROM {{groups}} where sid=$iNewSID group by gid ORDER BY gid"; //Get last question added (finds new qid)
|
|
$gres = Yii::app()->db->createCommand($gquery)->query();
|
|
foreach ($gres->readAll() as $grow)
|
|
{
|
|
Question::model()->updateQuestionOrder($grow['gid'], $iNewSID);
|
|
}
|
|
}
|
|
|
|
$results['question_attributes']=0;
|
|
// Finally the question attributes - it is called just once and only if there was a question
|
|
if (isset($question_attributesarray) && $question_attributesarray)
|
|
{//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES
|
|
$fieldorders=str_getcsv($question_attributesarray[0],',','"');
|
|
unset($question_attributesarray[0]);
|
|
|
|
foreach ($question_attributesarray as $qar) {
|
|
$fieldcontents=str_getcsv($qar,',','"');
|
|
$qarowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
// replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this attribute is orphan -> error, skip this record)
|
|
if (isset($aQIDReplacements[$qarowdata["qid"]]))
|
|
$qarowdata["qid"] = $aQIDReplacements[$qarowdata["qid"]];
|
|
else
|
|
continue; // a problem with this answer record -> don't consider
|
|
|
|
unset($qarowdata["qaid"]);
|
|
|
|
$result = Yii::app()->db->createCommand()->insert('{{question_attributes}}', $qarowdata);
|
|
if ($result!==false) $results['question_attributes']++;
|
|
}
|
|
}
|
|
// ATTRIBUTES is DONE
|
|
|
|
|
|
// TMSW Condition->Relevance: Anything needed here, other than call to LEM->ConvertConditionsToRelevance() when done?
|
|
|
|
// do CONDITIONS
|
|
$results['conditions']=0;
|
|
if (isset($conditionsarray) && $conditionsarray)
|
|
{
|
|
$fieldorders=str_getcsv($conditionsarray[0],',','"');
|
|
unset($conditionsarray[0]);
|
|
foreach ($conditionsarray as $car) {
|
|
$fieldcontents=str_getcsv($car,',','"');
|
|
$conditionrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
$oldqid = $conditionrowdata["qid"];
|
|
$oldcqid = $conditionrowdata["cqid"];
|
|
|
|
// replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this condition is orphan -> error, skip this record)
|
|
if (isset($aQIDReplacements[$oldqid]))
|
|
$conditionrowdata["qid"] = $aQIDReplacements[$oldqid];
|
|
else
|
|
continue; // a problem with this answer record -> don't consider
|
|
|
|
// replace the cqid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this condition is orphan -> error, skip this record)
|
|
if (isset($aQIDReplacements[$oldcqid]))
|
|
$conditionrowdata["cqid"] = $aQIDReplacements[$oldcqid];
|
|
else
|
|
continue; // a problem with this answer record -> don't consider
|
|
|
|
list($oldcsid, $oldcgid, $oldqidanscode) = explode("X",$conditionrowdata["cfieldname"],3);
|
|
|
|
if ($oldcgid != $oldgid) // this means that the condition is in another group (so it should not have to be been exported -> skip it
|
|
continue;
|
|
|
|
unset($conditionrowdata["cid"]);
|
|
|
|
// recreate the cfieldname with the new IDs
|
|
if (preg_match("/^\+/",$oldcsid))
|
|
{
|
|
$newcfieldname = '+'.$iNewSID . "X" . $newgid . "X" . $conditionrowdata["cqid"] .substr($oldqidanscode,strlen($oldqid));
|
|
}
|
|
else
|
|
{
|
|
$newcfieldname = $iNewSID . "X" . $newgid . "X" . $conditionrowdata["cqid"] .substr($oldqidanscode,strlen($oldqid));
|
|
}
|
|
|
|
$conditionrowdata["cfieldname"] = $newcfieldname;
|
|
if (!isset($conditionrowdata["method"]) || trim($conditionrowdata["method"])=='')
|
|
{
|
|
$conditionrowdata["method"]='==';
|
|
}
|
|
$newvalues=array_values($conditionrowdata);
|
|
$conditioninsert = "insert INTO {{conditions}} (".implode(',',array_keys($conditionrowdata)).") VALUES (".implode(',',$newvalues).")";
|
|
$result=Yii::app()->db->createCommand($conditioninsert)->query() or safeDie("Couldn't insert condition<br />$conditioninsert<br />");
|
|
$results['conditions']++;
|
|
}
|
|
}
|
|
LimeExpressionManager::RevertUpgradeConditionsToRelevance($iNewSID);
|
|
LimeExpressionManager::UpgradeConditionsToRelevance($iNewSID);
|
|
|
|
$results['groups']=1;
|
|
$results['newgid']=$newgid;
|
|
return $results;
|
|
}
|
|
|
|
|
|
/**
|
|
* This function imports a LimeSurvey .lsg question group XML file
|
|
*
|
|
* @param mixed $sFullFilePath The full filepath of the uploaded file
|
|
* @param mixed $iNewSID The new survey id - the group will always be added after the last group in the survey
|
|
*/
|
|
function XMLImportGroup($sFullFilePath, $iNewSID)
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
|
|
$aLanguagesSupported = array(); // this array will keep all the languages supported for the survey
|
|
|
|
$sBaseLanguage = Survey::model()->findByPk($iNewSID)->language;
|
|
$aLanguagesSupported[]=$sBaseLanguage; // adds the base language to the list of supported languages
|
|
$aLanguagesSupported=array_merge($aLanguagesSupported,Survey::model()->findByPk($iNewSID)->additionalLanguages);
|
|
$sXMLdata = file_get_contents($sFullFilePath);
|
|
$xml = simplexml_load_string($sXMLdata,'SimpleXMLElement',LIBXML_NONET);
|
|
if ($xml==false || $xml->LimeSurveyDocType!='Group') safeDie('This is not a valid LimeSurvey group structure XML file.');
|
|
$iDBVersion = (int) $xml->DBVersion;
|
|
$aQIDReplacements=array();
|
|
$results['defaultvalues']=0;
|
|
$results['answers']=0;
|
|
$results['question_attributes']=0;
|
|
$results['subquestions']=0;
|
|
$results['conditions']=0;
|
|
$results['groups']=0;
|
|
|
|
$importlanguages=array();
|
|
foreach ($xml->languages->language as $language)
|
|
{
|
|
$importlanguages[]=(string)$language;
|
|
}
|
|
|
|
if (!in_array($sBaseLanguage,$importlanguages))
|
|
{
|
|
$results['fatalerror'] = $clang->gT("The languages of the imported group file must at least include the base language of this survey.");
|
|
return $results;
|
|
}
|
|
// First get an overview of fieldnames - it's not useful for the moment but might be with newer versions
|
|
/*
|
|
$fieldnames=array();
|
|
foreach ($xml->questions->fields->fieldname as $fieldname )
|
|
{
|
|
$fieldnames[]=(string)$fieldname;
|
|
};*/
|
|
|
|
|
|
// Import group table ===================================================================================
|
|
|
|
|
|
$query = "SELECT MAX(group_order) AS maxgo FROM {{groups}} WHERE sid=$iNewSID";
|
|
$iGroupOrder = Yii::app()->db->createCommand($query)->queryScalar();
|
|
if ($iGroupOrder === false)
|
|
{
|
|
$iNewGroupOrder=0;
|
|
}
|
|
else
|
|
{
|
|
$iNewGroupOrder=$iGroupOrder+1;
|
|
}
|
|
|
|
foreach ($xml->groups->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$iOldSID=$insertdata['sid'];
|
|
$insertdata['sid']=$iNewSID;
|
|
$insertdata['group_order']=$iNewGroupOrder;
|
|
$oldgid=$insertdata['gid']; unset($insertdata['gid']); // save the old qid
|
|
|
|
// now translate any links
|
|
$insertdata['group_name']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['group_name']);
|
|
$insertdata['description']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['description']);
|
|
// Insert the new question
|
|
if (isset($aGIDReplacements[$oldgid]))
|
|
{
|
|
$insertdata['gid']=$aGIDReplacements[$oldgid];
|
|
}
|
|
if (isset($insertdata['gid'])) switchMSSQLIdentityInsert('groups',true);
|
|
|
|
$result = Yii::app()->db->createCommand()->insert('{{groups}}', $insertdata);
|
|
|
|
if (isset($insertdata['gid'])) switchMSSQLIdentityInsert('groups',false);
|
|
$results['groups']++;
|
|
|
|
if (!isset($aGIDReplacements[$oldgid]))
|
|
{
|
|
$newgid=getLastInsertID('{{groups}}');
|
|
$aGIDReplacements[$oldgid]=$newgid; // add old and new qid to the mapping array
|
|
}
|
|
}
|
|
|
|
|
|
// Import questions table ===================================================================================
|
|
|
|
// We have to run the question table data two times - first to find all main questions
|
|
// then for subquestions (because we need to determine the new qids for the main questions first)
|
|
|
|
|
|
$results['questions']=0;
|
|
if (isset($xml->questions))
|
|
{
|
|
foreach ($xml->questions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$iOldSID=$insertdata['sid'];
|
|
$insertdata['sid']=$iNewSID;
|
|
if (!isset($aGIDReplacements[$insertdata['gid']]) || trim($insertdata['title'])=='') continue; // Skip questions with invalid group id
|
|
$insertdata['gid']=$aGIDReplacements[$insertdata['gid']];
|
|
$oldqid=$insertdata['qid']; unset($insertdata['qid']); // save the old qid
|
|
|
|
// now translate any links
|
|
$insertdata['title']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['title']);
|
|
$insertdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']);
|
|
$insertdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']);
|
|
// Insert the new question
|
|
if (isset($aQIDReplacements[$oldqid]))
|
|
{
|
|
$insertdata['qid']=$aQIDReplacements[$oldqid];
|
|
}
|
|
if (isset($insertdata['qid'])) switchMSSQLIdentityInsert('questions',true);
|
|
|
|
$result = Yii::app()->db->createCommand()->insert('{{questions}}', $insertdata);
|
|
if (isset($insertdata['qid'])) switchMSSQLIdentityInsert('questions',false);
|
|
if (!isset($aQIDReplacements[$oldqid]))
|
|
{
|
|
$newqid=getLastInsertID('{{questions}}');
|
|
$aQIDReplacements[$oldqid]=$newqid; // add old and new qid to the mapping array
|
|
$results['questions']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Import subquestions --------------------------------------------------------------
|
|
if (isset($xml->subquestions))
|
|
{
|
|
|
|
foreach ($xml->subquestions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['sid']=$iNewSID;
|
|
if (!isset($aGIDReplacements[$insertdata['gid']])) continue; // Skip questions with invalid group id
|
|
$insertdata['gid']=$aGIDReplacements[(int)$insertdata['gid']];;
|
|
$oldsqid=(int)$insertdata['qid']; unset($insertdata['qid']); // save the old qid
|
|
if (!isset($aQIDReplacements[(int)$insertdata['parent_qid']])) continue; // Skip subquestions with invalid parent_qids
|
|
$insertdata['parent_qid']=$aQIDReplacements[(int)$insertdata['parent_qid']]; // remap the parent_qid
|
|
|
|
// now translate any links
|
|
$insertdata['title']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['title']);
|
|
$insertdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']);
|
|
$insertdata['help']=translateLinks('survey', $iOldSID, $iNewSID, !empty($insertdata['help']) ? $insertdata['help'] : '');
|
|
if (isset($aQIDReplacements[$oldsqid])){
|
|
$insertdata['qid']=$aQIDReplacements[$oldsqid];
|
|
}
|
|
if (isset($insertdata['qid'])) switchMSSQLIdentityInsert('questions',true);
|
|
|
|
$result = Yii::app()->db->createCommand()->insert('{{questions}}', $insertdata);
|
|
$newsqid=getLastInsertID('{{questions}}');
|
|
if (isset($insertdata['qid'])) switchMSSQLIdentityInsert('questions',true);
|
|
|
|
if (!isset($insertdata['qid']))
|
|
{
|
|
$aQIDReplacements[$oldsqid]=$newsqid; // add old and new qid to the mapping array
|
|
}
|
|
|
|
$results['subquestions']++;
|
|
}
|
|
}
|
|
|
|
// Import answers --------------------------------------------------------------
|
|
if(isset($xml->answers))
|
|
{
|
|
|
|
|
|
foreach ($xml->answers->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
if (!isset($aQIDReplacements[(int)$insertdata['qid']])) continue; // Skip questions with invalid group id
|
|
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the parent_qid
|
|
|
|
// now translate any links
|
|
$result = Yii::app()->db->createCommand()->insert('{{answers}}', $insertdata);
|
|
$results['answers']++;
|
|
}
|
|
}
|
|
|
|
// Import questionattributes --------------------------------------------------------------
|
|
if(isset($xml->question_attributes))
|
|
{
|
|
|
|
|
|
$aAllAttributes=questionAttributes(true);
|
|
|
|
foreach ($xml->question_attributes->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
unset($insertdata['qaid']);
|
|
if (!isset($aQIDReplacements[(int)$insertdata['qid']])) continue; // Skip questions with invalid group id
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the parent_qid
|
|
|
|
|
|
if ($iDBVersion<156 && isset($aAllAttributes[$insertdata['attribute']]['i18n']) && $aAllAttributes[$insertdata['attribute']]['i18n'])
|
|
{
|
|
foreach ($importlanguages as $sLanguage)
|
|
{
|
|
$insertdata['language']=$sLanguage;
|
|
$result = Yii::app()->db->createCommand()->insert('{{question_attributes}}', $insertdata);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$result = Yii::app()->db->createCommand()->insert('{{question_attributes}}', $insertdata);
|
|
}
|
|
$results['question_attributes']++;
|
|
}
|
|
}
|
|
|
|
|
|
// Import defaultvalues --------------------------------------------------------------
|
|
if(isset($xml->defaultvalues))
|
|
{
|
|
|
|
|
|
$results['defaultvalues']=0;
|
|
foreach ($xml->defaultvalues->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the qid
|
|
if ($insertdata['sqid']>0)
|
|
{
|
|
if (!isset($aQIDReplacements[(int)$insertdata['sqid']])) continue; // If SQID is invalid skip the default value
|
|
$insertdata['sqid']=$aQIDReplacements[(int)$insertdata['sqid']]; // remap the subquestion id
|
|
}
|
|
|
|
// now translate any links
|
|
$result = Yii::app()->db->createCommand()->insert('{{defaultvalues}}', $insertdata);
|
|
$results['defaultvalues']++;
|
|
}
|
|
}
|
|
|
|
// Import conditions --------------------------------------------------------------
|
|
if(isset($xml->conditions))
|
|
{
|
|
|
|
|
|
foreach ($xml->conditions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
// replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this condition is orphan -> error, skip this record)
|
|
if (isset($aQIDReplacements[$insertdata['qid']]))
|
|
{
|
|
$insertdata['qid']=$aQIDReplacements[$insertdata['qid']]; // remap the qid
|
|
}
|
|
else continue; // a problem with this answer record -> don't consider
|
|
if (isset($aQIDReplacements[$insertdata['cqid']]))
|
|
{
|
|
$insertdata['cqid']=$aQIDReplacements[$insertdata['cqid']]; // remap the qid
|
|
}
|
|
else continue; // a problem with this answer record -> don't consider
|
|
|
|
list($oldcsid, $oldcgid, $oldqidanscode) = explode("X",$insertdata["cfieldname"],3);
|
|
|
|
if ($oldcgid != $oldgid) // this means that the condition is in another group (so it should not have to be been exported -> skip it
|
|
continue;
|
|
|
|
unset($insertdata["cid"]);
|
|
|
|
// recreate the cfieldname with the new IDs
|
|
if (preg_match("/^\+/",$oldcsid))
|
|
{
|
|
$newcfieldname = '+'.$iNewSID . "X" . $newgid . "X" . $insertdata["cqid"] .substr($oldqidanscode,strlen($oldqid));
|
|
}
|
|
else
|
|
{
|
|
$newcfieldname = $iNewSID . "X" . $newgid . "X" . $insertdata["cqid"] .substr($oldqidanscode,strlen($oldqid));
|
|
}
|
|
|
|
$insertdata["cfieldname"] = $newcfieldname;
|
|
if (trim($insertdata["method"])=='')
|
|
{
|
|
$insertdata["method"]='==';
|
|
}
|
|
|
|
// now translate any links
|
|
$result = Yii::app()->db->createCommand()->insert('{{conditions}}', $insertdata);
|
|
$results['conditions']++;
|
|
}
|
|
}
|
|
LimeExpressionManager::RevertUpgradeConditionsToRelevance($iNewSID);
|
|
LimeExpressionManager::UpgradeConditionsToRelevance($iNewSID);
|
|
|
|
$results['newgid']=$newgid;
|
|
$results['labelsets']=0;
|
|
$results['labels']=0;
|
|
return $results;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* This function imports an old-school question file (*.csv,*.sql)
|
|
*
|
|
* @param mixed $sFullFilePath Full file patch to the import file
|
|
* @param mixed $iNewSID Survey ID to which the question is attached
|
|
* @param mixed $newgid Group ID top which the question is attached
|
|
*/
|
|
function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
|
|
$aLIDReplacements=array();
|
|
$aQIDReplacements=array(); // this array will have the "new qid" for the questions, the key will be the "old qid"
|
|
$aSQIDReplacements=array();
|
|
$results['labelsets']=0;
|
|
$results['labels']=0;
|
|
|
|
$handle = fopen($sFullFilePath, "r");
|
|
while (!feof($handle))
|
|
{
|
|
$buffer = fgets($handle); //To allow for very long survey welcomes (up to 10k)
|
|
$bigarray[] = $buffer;
|
|
}
|
|
fclose($handle);
|
|
$importversion=0;
|
|
// Now we try to determine the dataformat of the survey file.
|
|
if (substr($bigarray[1], 0, 24) == "# SURVEYOR QUESTION DUMP")
|
|
{
|
|
$importversion = 100; // version 1.0 or 0.99 file
|
|
}
|
|
elseif (substr($bigarray[0], 0, 26) == "# LimeSurvey Question Dump" || substr($bigarray[0], 0, 27) == "# PHPSurveyor Question Dump")
|
|
{ // This is a >1.0 version file - these files carry the version information to read in line two
|
|
$importversion=(integer)substr($bigarray[1], 12, 3);
|
|
}
|
|
else // unknown file - show error message
|
|
{
|
|
$results['fatalerror'] = $clang->gT("This file is not a LimeSurvey question file. Import failed.");
|
|
return $results;
|
|
}
|
|
|
|
if ((int)$importversion<112)
|
|
{
|
|
$results['fatalerror'] = $clang->gT("This file is too old. Only files from LimeSurvey version 1.50 (DBVersion 112) and newer are supported.");
|
|
return $results;
|
|
}
|
|
|
|
for ($i=0; $i<9; $i++) //skipping the first lines that are not needed
|
|
{
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//QUESTIONS
|
|
if (array_search("# ANSWERS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ANSWERS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# ANSWERS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ANSWERS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$questionarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//ANSWERS
|
|
if (array_search("# LABELSETS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELSETS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# LABELSETS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELSETS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$answerarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LABELSETS
|
|
if (array_search("# LABELS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# LABELS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$labelsetsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LABELS
|
|
if (array_search("# QUESTION_ATTRIBUTES TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTION_ATTRIBUTES TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUESTION_ATTRIBUTES TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTION_ATTRIBUTES TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$labelsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//QuestionAttribute
|
|
$stoppoint = count($bigarray);
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-1) {$question_attributesarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
if (isset($questionarray))
|
|
{
|
|
$questionfieldnames=str_getcsv($questionarray[0],',','"');
|
|
unset($questionarray[0]);
|
|
$countquestions = count($questionarray)-1;
|
|
}
|
|
else {$countquestions=0;}
|
|
|
|
if (isset($answerarray))
|
|
{
|
|
$answerfieldnames=str_getcsv($answerarray[0],',','"');
|
|
unset($answerarray[0]);
|
|
while (trim(reset($answerarray))=='')
|
|
{
|
|
array_shift($answerarray);
|
|
}
|
|
$countanswers = count($answerarray);
|
|
}
|
|
else {$countanswers=0;}
|
|
if (isset($labelsetsarray)) {$countlabelsets = count($labelsetsarray)-1;} else {$countlabelsets=0;}
|
|
if (isset($labelsarray)) {$countlabels = count($labelsarray)-1;} else {$countlabels=0;}
|
|
if (isset($question_attributesarray)) {$countquestion_attributes = count($question_attributesarray)-1;} else {$countquestion_attributes=0;}
|
|
|
|
$aLanguagesSupported = array(); // this array will keep all the languages supported for the survey
|
|
|
|
$sBaseLanguage = Survey::model()->findByPk($iNewSID)->language;
|
|
$aLanguagesSupported[]=$sBaseLanguage; // adds the base language to the list of supported languages
|
|
$aLanguagesSupported=array_merge($aLanguagesSupported,Survey::model()->findByPk($iNewSID)->additionalLanguages);
|
|
|
|
|
|
// Let's check that imported objects support at least the survey's baselang
|
|
|
|
if (isset($questionarray))
|
|
{
|
|
$langfieldnum = array_search("language", $questionfieldnames);
|
|
$qidfieldnum = array_search("qid", $questionfieldnames);
|
|
$questionssupportbaselang = doesImportArraySupportLanguage($questionarray, array($qidfieldnum), $langfieldnum, $sBaseLanguage);
|
|
if (!$questionssupportbaselang)
|
|
{
|
|
$results['fatalerror']=$clang->gT("You can't import a question which doesn't support at least the survey base language.");
|
|
return $results;
|
|
}
|
|
}
|
|
|
|
if ($countanswers > 0)
|
|
{
|
|
$langfieldnum = array_search("language", $answerfieldnames);
|
|
$answercodefilednum1 = array_search("qid", $answerfieldnames);
|
|
$answercodefilednum2 = array_search("code", $answerfieldnames);
|
|
$answercodekeysarr = Array($answercodefilednum1,$answercodefilednum2);
|
|
$answerssupportbaselang = doesImportArraySupportLanguage($answerarray,$answercodekeysarr,$langfieldnum,$sBaseLanguage);
|
|
if (!$answerssupportbaselang)
|
|
{
|
|
$results['fatalerror']=$clang->gT("You can't import answers which doesn't support at least the survey base language.");
|
|
return $results;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($countlabelsets > 0)
|
|
{
|
|
$labelsetfieldname = str_getcsv($labelsetsarray[0],',','"');
|
|
$langfieldnum = array_search("languages", $labelsetfieldname);
|
|
$lidfilednum = array_search("lid", $labelsetfieldname);
|
|
$labelsetssupportbaselang = doesImportArraySupportLanguage($labelsetsarray,Array($lidfilednum),$langfieldnum,$sBaseLanguage,true);
|
|
if (!$labelsetssupportbaselang)
|
|
{
|
|
$results['fatalerror']=$clang->gT("You can't import label sets which don't support the current survey's base language");
|
|
return $results;
|
|
}
|
|
}
|
|
// I assume that if a labelset supports the survey's baselang,
|
|
// then it's labels do support it as well
|
|
|
|
//DO ANY LABELSETS FIRST, SO WE CAN KNOW WHAT THEIR NEW LID IS FOR THE QUESTIONS
|
|
if (isset($labelsetsarray) && $labelsetsarray) {
|
|
$csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets
|
|
$count=0;
|
|
foreach ($labelsetsarray as $lsa) {
|
|
$fieldorders =str_getcsv($labelsetsarray[0],',','"');
|
|
$fieldcontents=str_getcsv($lsa,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
$results['labelsets']++;
|
|
|
|
$labelsetrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
// Save old labelid
|
|
$oldlid=$labelsetrowdata['lid'];
|
|
// set the new language
|
|
unset($labelsetrowdata['lid']);
|
|
$newvalues=array_values($labelsetrowdata);
|
|
$lsainsert = "INSERT INTO {{labelsets}} (".implode(',',array_keys($labelsetrowdata)).") VALUES (".implode(',',$newvalues).")"; //handle db prefix
|
|
$lsiresult=Yii::app()->db->createCommand($lsainsert)->query();
|
|
|
|
// Get the new insert id for the labels inside this labelset
|
|
$newlid=getLastInsertID('{{labelsets}}');
|
|
|
|
if ($labelsarray) {
|
|
$count=0;
|
|
foreach ($labelsarray as $la) {
|
|
$lfieldorders =str_getcsv($labelsarray[0],',','"');
|
|
$lfieldcontents=str_getcsv($la,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
// Combine into one array with keys and values since its easier to handle
|
|
$labelrowdata=array_combine($lfieldorders,$lfieldcontents);
|
|
$labellid=$labelrowdata['lid'];
|
|
if ($importversion<=132)
|
|
{
|
|
$labelrowdata["assessment_value"]=(int)$labelrowdata["code"];
|
|
}
|
|
|
|
if ($labellid == $oldlid) {
|
|
$labelrowdata['lid']=$newlid;
|
|
|
|
// translate internal links
|
|
$labelrowdata['title']=translateLinks('label', $oldlid, $newlid, $labelrowdata['title']);
|
|
|
|
$newvalues=array_values($labelrowdata);
|
|
if ($newvalues)
|
|
XSSFilterArray($newvalues);
|
|
$lainsert = "INSERT INTO {{labels}} (".implode(',',array_keys($labelrowdata)).") VALUES (".implode(',',$newvalues).")"; //handle db prefix
|
|
$liresult=Yii::app()->db->createCommand($lainsert)->query();
|
|
$results['labels']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//CHECK FOR DUPLICATE LABELSETS
|
|
$thisset="";
|
|
$query2 = "SELECT code, title, sortorder, language, assessment_value
|
|
FROM {{labels}}
|
|
WHERE lid=".$newlid."
|
|
ORDER BY language, sortorder, code";
|
|
$result2 = Yii::app()->db->createCommand($query2)->query() or safeDie("Died querying labelset $lid<br />$query2<br />");
|
|
|
|
foreach($result2->readAll() as $row2)
|
|
{
|
|
$row2 = array_values($row2);
|
|
$thisset .= implode('.', $row2);
|
|
} // while
|
|
$newcs=dechex(crc32($thisset)*1);
|
|
unset($lsmatch);
|
|
if (isset($csarray))
|
|
{
|
|
foreach($csarray as $key=>$val)
|
|
{
|
|
if ($val == $newcs)
|
|
{
|
|
$lsmatch=$key;
|
|
}
|
|
}
|
|
}
|
|
if (isset($lsmatch))
|
|
{
|
|
//There is a matching labelset. So, we will delete this one and refer
|
|
//to the matched one.
|
|
$query = "DELETE FROM {{labels}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->query() or safeDie("Couldn't delete labels<br />$query<br />");
|
|
$query = "DELETE FROM {{labelsets}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->query() or safeDie("Couldn't delete labelset<br />$query<br />");
|
|
$newlid=$lsmatch;
|
|
}
|
|
else
|
|
{
|
|
//There isn't a matching labelset, add this checksum to the $csarray array
|
|
$csarray[$newlid]=$newcs;
|
|
}
|
|
//END CHECK FOR DUPLICATES
|
|
$aLIDReplacements[$oldlid]=$newlid;
|
|
}
|
|
}
|
|
|
|
|
|
// Import questions
|
|
if (isset($questionarray) && $questionarray) {
|
|
|
|
//Assuming we will only import one question at a time we will now find out the maximum question order in this group
|
|
//and save it for later
|
|
$query = "SELECT MAX(question_order) AS maxqo FROM {{questions}} WHERE sid=$iNewSID AND gid=$newgid";
|
|
$aRow = Yii::app()->db->createCommand($query)->queryRow();
|
|
|
|
if ($aRow == false)
|
|
{
|
|
$newquestionorder=0;
|
|
}
|
|
else
|
|
{
|
|
$newquestionorder = $aRow['maxqo'];
|
|
$newquestionorder++;
|
|
}
|
|
|
|
foreach ($questionarray as $qa)
|
|
{
|
|
$qacfieldcontents=str_getcsv($qa,',','"');
|
|
$questionrowdata=array_combine($questionfieldnames,$qacfieldcontents);
|
|
|
|
// Skip not supported languages
|
|
if (!in_array($questionrowdata['language'],$aLanguagesSupported))
|
|
continue;
|
|
|
|
// replace the sid
|
|
$oldqid = $questionrowdata['qid'];
|
|
$iOldSID = $questionrowdata['sid'];
|
|
$oldgid = $questionrowdata['gid'];
|
|
|
|
// Remove qid field if there is no newqid; and set it to newqid if it's set
|
|
if (!isset($newqid))
|
|
{
|
|
unset($questionrowdata['qid']);
|
|
}
|
|
else
|
|
{
|
|
$questionrowdata['qid'] = $newqid;
|
|
}
|
|
|
|
$questionrowdata["sid"] = $iNewSID;
|
|
$questionrowdata["gid"] = $newgid;
|
|
$questionrowdata["question_order"] = $newquestionorder;
|
|
|
|
// Save the following values - will need them for proper conversion later if ((int)$questionrowdata['lid']>0)
|
|
if ((int)$questionrowdata['lid']>0)
|
|
{
|
|
$oldquestion['lid1']=(int)$questionrowdata['lid'];
|
|
}
|
|
if ((int)$questionrowdata['lid1']>0)
|
|
{
|
|
$oldquestion['lid2']=(int)$questionrowdata['lid1'];
|
|
}
|
|
$oldquestion['oldtype']=$questionrowdata['type'];
|
|
|
|
// Unset label set IDs and convert question types
|
|
unset($questionrowdata['lid']);
|
|
unset($questionrowdata['lid1']);
|
|
if ($questionrowdata['type']=='W')
|
|
{
|
|
$questionrowdata['type']='!';
|
|
}
|
|
elseif ($questionrowdata['type']=='Z')
|
|
{
|
|
$questionrowdata['type']='L';
|
|
}
|
|
$oldquestion['newtype']=$questionrowdata['type'];
|
|
|
|
$questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata);
|
|
|
|
// translate internal links
|
|
$questionrowdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $questionrowdata['question']);
|
|
$questionrowdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $questionrowdata['help']);
|
|
|
|
$newvalues=array_values($questionrowdata);
|
|
if ($newvalues)
|
|
XSSFilterArray($newvalues);
|
|
$questionrowdata=array_combine(array_keys($questionrowdata),$newvalues);
|
|
$iQID=Question::model()->insertRecords($questionrowdata);
|
|
|
|
// set the newqid only if is not set
|
|
if (!isset($newqid))
|
|
{
|
|
$newqid=$iQID;
|
|
}
|
|
}
|
|
$qtypes = getQuestionTypeList("" ,"array");
|
|
$results['answers']=0;
|
|
$results['subquestions']=0;
|
|
|
|
|
|
// Now we will fix up old label sets where they are used as answers
|
|
if ((isset($oldquestion['lid1']) || isset($oldquestion['lid2'])) && ($qtypes[$oldquestion['newtype']]['answerscales']>0 || $qtypes[$oldquestion['newtype']]['subquestions']>1))
|
|
{
|
|
$query="select * from {{labels}} where lid={$aLIDReplacements[$oldquestion['lid1']]} ";
|
|
$oldlabelsresult=Yii::app()->db->createCommand($query)->query();
|
|
foreach($oldlabelsresult->readAll() as $labelrow)
|
|
{
|
|
if (in_array($labelrow['language'],$aLanguagesSupported)){
|
|
if ($labelrow)
|
|
XSSFilterArray($labelrow);
|
|
if ($qtypes[$oldquestion['newtype']]['subquestions']<2)
|
|
{
|
|
$qinsert = "insert INTO {{answers}} (qid,code,answer,sortorder,language,assessment_value,scale_id)
|
|
VALUES ($newqid,'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."','".$labelrow['assessment_value']."',0)";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie ("Error: Failed to insert answer <br />\n$qinsert<br />\n");
|
|
$results['answers']++;
|
|
}
|
|
else
|
|
{
|
|
if (isset($aSQIDReplacements[$labelrow['code']])){
|
|
$fieldname='qid,';
|
|
$data=$aSQIDReplacements[$labelrow['code']].',';
|
|
}
|
|
else{
|
|
$fieldname='' ;
|
|
$data='';
|
|
}
|
|
|
|
$qinsert = "insert INTO {{questions}} ($fieldname sid,gid,parent_qid,title,question,question_order,language,scale_id,type)
|
|
VALUES ($data $iNewSID,$newgid,$newqid,'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."',1,'".$oldquestion['newtype']."')";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie ("Error: Failed to insert subquestion <br />\n$qinsert<br />\n");
|
|
if ($fieldname=='')
|
|
{
|
|
$aSQIDReplacements[$labelrow['code']]=getLastInsertID('{{questions}}');
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isset($oldquestion['lid2']) && $qtypes[$oldquestion['newtype']]['answerscales']>1)
|
|
{
|
|
$query="select * from {{labels}} where lid={$aLIDReplacements[$oldquestion['lid2']]}";
|
|
$oldlabelsresult=Yii::app()->db->createCommand($query)->query();
|
|
foreach($oldlabelsresult->readAll() as $labelrow)
|
|
{
|
|
if ($labelrow)
|
|
XSSFilterArray($labelrow);
|
|
if (in_array($labelrow['language'],$aLanguagesSupported)){
|
|
$qinsert = "insert INTO {{answers}} (qid,code,answer,sortorder,language,assessment_value,scale_id)
|
|
VALUES ($newqid,'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."','".$labelrow['assessment_value']."',1)";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie($clang->gT("Error").": Failed to insert answer <br />\n$qinsert<br />\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Do answers
|
|
if (isset($answerarray) && $answerarray)
|
|
{
|
|
foreach ($answerarray as $aa)
|
|
{
|
|
$answerfieldcontents=str_getcsv($aa,',','"');
|
|
$answerrowdata=array_combine($answerfieldnames,$answerfieldcontents);
|
|
if ($answerrowdata===false)
|
|
{
|
|
$importquestion.='<br />'.$clang->gT("Faulty line in import - fields and data don't match").":".implode(',',$answerfieldcontents);
|
|
}
|
|
// Skip not supported languages
|
|
if (!in_array($answerrowdata['language'],$aLanguagesSupported))
|
|
continue;
|
|
$code=$answerrowdata["code"];
|
|
$thisqid=$answerrowdata["qid"];
|
|
$answerrowdata["qid"]=$newqid;
|
|
|
|
|
|
if ($importversion<=132)
|
|
{
|
|
$answerrowdata["assessment_value"]=(int)$answerrowdata["code"];
|
|
}
|
|
|
|
// Convert default values for single select questions
|
|
if ($answerrowdata['default_value']=='Y' && ($oldquestion['newtype']=='L' || $oldquestion['newtype']=='O' || $oldquestion['newtype']=='!'))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid']=$newqid;
|
|
$insertdata['language']=$answerrowdata['language'];
|
|
$insertdata['defaultvalue']=$answerrowdata['answer'];
|
|
|
|
$dvalue = new DefaultValue;
|
|
foreach ($insertdata as $k => $v)
|
|
$dvalue->$k = $v;
|
|
$qres = $dvalue->save();
|
|
|
|
}
|
|
// translate internal links
|
|
$answerrowdata['answer']=translateLinks('survey', $iOldSID, $iNewSID, $answerrowdata['answer']);
|
|
// Everything set - now insert it
|
|
$answerrowdata = array_map('convertCSVReturnToReturn', $answerrowdata);
|
|
|
|
if ($qtypes[$oldquestion['newtype']]['subquestions']>0) //hmmm.. this is really a subquestion
|
|
{
|
|
$questionrowdata=array();
|
|
if (isset($aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']])){
|
|
$questionrowdata['qid']=$aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']];
|
|
}
|
|
$questionrowdata['parent_qid']=$answerrowdata['qid'];
|
|
$questionrowdata['sid']=$iNewSID;
|
|
$questionrowdata['gid']=$newgid;
|
|
$questionrowdata['title']=$answerrowdata['code'];
|
|
$questionrowdata['question']=$answerrowdata['answer'];
|
|
$questionrowdata['question_order']=$answerrowdata['sortorder'];
|
|
$questionrowdata['language']=$answerrowdata['language'];
|
|
$questionrowdata['type']=$oldquestion['newtype'];
|
|
if ($questionrowdata)
|
|
XSSFilterArray($questionrowdata);
|
|
$question = new Question;
|
|
foreach ($questionrowdata as $k => $v)
|
|
$question->$k = $v;
|
|
$qres = $question->save();
|
|
if (!isset($questionrowdata['qid']))
|
|
{
|
|
$aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']]=getLastInsertID($question->tableName());
|
|
}
|
|
$results['subquestions']++;
|
|
// also convert default values subquestions for multiple choice
|
|
if ($answerrowdata['default_value']=='Y' && ($oldquestion['newtype']=='M' || $oldquestion['newtype']=='P'))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid']=$newqid;
|
|
$insertdata['sqid']=$aSQIDReplacements[$answerrowdata['code']];
|
|
$insertdata['language']=$answerrowdata['language'];
|
|
$insertdata['defaultvalue']='Y';
|
|
|
|
$qres = $CI->defaultvalues_model->insertRecords($insertdata) or safeDie("Error: Failed to insert defaultvalue <br />\n");
|
|
}
|
|
|
|
}
|
|
else // insert answers
|
|
{
|
|
unset($answerrowdata['default_value']);
|
|
|
|
$answer = new Answer;
|
|
foreach ($answerrowdata as $k => $v)
|
|
$answer->$k = $v;
|
|
$ares = $answer->save();
|
|
$results['answers']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
$results['question_attributes']=0;
|
|
// Finally the question attributes - it is called just once and only if there was a question
|
|
if (isset($question_attributesarray) && $question_attributesarray)
|
|
{//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES
|
|
$fieldorders =str_getcsv($question_attributesarray[0],',','"');
|
|
unset($question_attributesarray[0]);
|
|
foreach ($question_attributesarray as $qar) {
|
|
$fieldcontents=str_getcsv($qar,',','"');
|
|
$qarowdata=array_combine($fieldorders,$fieldcontents);
|
|
$qarowdata["qid"]=$newqid;
|
|
unset($qarowdata["qaid"]);
|
|
$attr = new QuestionAttribute;
|
|
if ($qarowdata)
|
|
XSSFilterArray($qarowdata);
|
|
foreach ($qarowdata as $k => $v)
|
|
$attr->$k = $v;
|
|
$result = $attr->save();
|
|
$results['question_attributes']++;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
LimeExpressionManager::SetDirtyFlag(); // so refreshes syntax highlighting
|
|
|
|
$results['newqid']=$newqid;
|
|
$results['questions']=1;
|
|
$results['newqid']=$newqid;
|
|
return $results;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* This function imports a LimeSurvey .lsq question XML file
|
|
*
|
|
* @param mixed $sFullFilePath The full filepath of the uploaded file
|
|
* @param mixed $iNewSID The new survey id
|
|
* @param mixed $newgid The new question group id -the question will always be added after the last question in the group
|
|
*/
|
|
function XMLImportQuestion($sFullFilePath, $iNewSID, $newgid)
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
$aLanguagesSupported = array(); // this array will keep all the languages supported for the survey
|
|
$sBaseLanguage = Survey::model()->findByPk($iNewSID)->language;
|
|
$aLanguagesSupported[]=$sBaseLanguage; // adds the base language to the list of supported languages
|
|
$aLanguagesSupported=array_merge($aLanguagesSupported,Survey::model()->findByPk($iNewSID)->additionalLanguages);
|
|
$sXMLdata = file_get_contents($sFullFilePath);
|
|
$xml = simplexml_load_string($sXMLdata,'SimpleXMLElement',LIBXML_NONET);
|
|
if ($xml->LimeSurveyDocType!='Question') safeDie('This is not a valid LimeSurvey question structure XML file.');
|
|
$iDBVersion = (int) $xml->DBVersion;
|
|
$aQIDReplacements=array();
|
|
$aSQIDReplacements=array(0=>0);
|
|
|
|
$results['defaultvalues']=0;
|
|
$results['answers']=0;
|
|
$results['question_attributes']=0;
|
|
$results['subquestions']=0;
|
|
|
|
$importlanguages=array();
|
|
foreach ($xml->languages->language as $language)
|
|
{
|
|
$importlanguages[]=(string)$language;
|
|
}
|
|
|
|
if (!in_array($sBaseLanguage,$importlanguages))
|
|
{
|
|
$results['fatalerror'] = $clang->gT("The languages of the imported question file must at least include the base language of this survey.");
|
|
return $results;
|
|
}
|
|
// First get an overview of fieldnames - it's not useful for the moment but might be with newer versions
|
|
/*
|
|
$fieldnames=array();
|
|
foreach ($xml->questions->fields->fieldname as $fieldname )
|
|
{
|
|
$fieldnames[]=(string)$fieldname;
|
|
};*/
|
|
|
|
|
|
// Import questions table ===================================================================================
|
|
|
|
// We have to run the question table data two times - first to find all main questions
|
|
// then for subquestions (because we need to determine the new qids for the main questions first)
|
|
|
|
|
|
$query = "SELECT MAX(question_order) AS maxqo FROM {{questions}} WHERE sid=$iNewSID AND gid=$newgid";
|
|
$res = Yii::app()->db->createCommand($query)->query();
|
|
$resrow = $res->read();
|
|
$newquestionorder = $resrow['maxqo'] + 1;
|
|
if (is_null($newquestionorder))
|
|
{
|
|
$newquestionorder=0;
|
|
}
|
|
else
|
|
{
|
|
$newquestionorder++;
|
|
}
|
|
foreach ($xml->questions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$iOldSID=$insertdata['sid'];
|
|
$insertdata['sid']=$iNewSID;
|
|
$insertdata['gid']=$newgid;
|
|
$insertdata['question_order']=$newquestionorder;
|
|
$oldqid=$insertdata['qid']; unset($insertdata['qid']); // save the old qid
|
|
|
|
// now translate any links
|
|
$insertdata['title']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['title']);
|
|
$insertdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']);
|
|
$insertdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']);
|
|
// Insert the new question
|
|
if (isset($aQIDReplacements[$oldqid]))
|
|
{
|
|
$insertdata['qid']=$aQIDReplacements[$oldqid];
|
|
}
|
|
|
|
$ques = new Question;
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
foreach ($insertdata as $k => $v)
|
|
$ques->$k = $v;
|
|
$result = $ques->save();
|
|
if (!$result)
|
|
{
|
|
$results['fatalerror'] = CHtml::errorSummary($ques,$clang->gT("The question could not be imported for the following reasons:"));
|
|
return $results;
|
|
}
|
|
if (!isset($aQIDReplacements[$oldqid]))
|
|
{
|
|
$newqid=getLastInsertID($ques->tableName());
|
|
$aQIDReplacements[$oldqid]=$newqid; // add old and new qid to the mapping array
|
|
}
|
|
}
|
|
|
|
// Import subquestions --------------------------------------------------------------
|
|
if (isset($xml->subquestions))
|
|
{
|
|
foreach ($xml->subquestions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['sid']=$iNewSID;
|
|
$insertdata['gid']=$newgid;
|
|
$oldsqid=(int)$insertdata['qid']; unset($insertdata['qid']); // save the old qid
|
|
$insertdata['parent_qid']=$aQIDReplacements[(int)$insertdata['parent_qid']]; // remap the parent_qid
|
|
|
|
// now translate any links
|
|
|
|
$insertdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']);
|
|
if (isset($insertdata['help']))
|
|
{
|
|
$insertdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']);
|
|
}
|
|
if (isset($aQIDReplacements[$oldsqid])){
|
|
$insertdata['qid']=$aQIDReplacements[$oldsqid];
|
|
}
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
$ques = new Question;
|
|
foreach ($insertdata as $k => $v)
|
|
$ques->$k = $v;
|
|
$result = $ques->save();
|
|
$newsqid=getLastInsertID($ques->tableName());
|
|
if (!isset($insertdata['qid']))
|
|
{
|
|
$aQIDReplacements[$oldsqid]=$newsqid; // add old and new qid to the mapping array
|
|
}
|
|
$results['subquestions']++;
|
|
}
|
|
}
|
|
|
|
// Import answers --------------------------------------------------------------
|
|
if(isset($xml->answers))
|
|
{
|
|
|
|
|
|
foreach ($xml->answers->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the parent_qid
|
|
|
|
// now translate any links
|
|
$answers = new Answer;
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
foreach ($insertdata as $k => $v)
|
|
$answers->$k = $v;
|
|
$result = $answers->save();
|
|
$results['answers']++;
|
|
}
|
|
}
|
|
|
|
// Import questionattributes --------------------------------------------------------------
|
|
if(isset($xml->question_attributes))
|
|
{
|
|
|
|
|
|
$aAllAttributes=questionAttributes(true);
|
|
foreach ($xml->question_attributes->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
unset($insertdata['qaid']);
|
|
$insertdata['qid']=$aQIDReplacements[(integer)$insertdata['qid']]; // remap the parent_qid
|
|
|
|
|
|
if ($iDBVersion<156 && isset($aAllAttributes[$insertdata['attribute']]['i18n']) && $aAllAttributes[$insertdata['attribute']]['i18n'])
|
|
{
|
|
foreach ($importlanguages as $sLanguage)
|
|
{
|
|
$insertdata['language']=$sLanguage;
|
|
$attributes = new QuestionAttribute;
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
foreach ($insertdata as $k => $v)
|
|
$attributes->$k = $v;
|
|
$result = $attributes->save();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$attributes = new QuestionAttribute;
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
foreach ($insertdata as $k => $v)
|
|
$attributes->$k = $v;
|
|
$result = $attributes->save();
|
|
}
|
|
$results['question_attributes']++;
|
|
}
|
|
}
|
|
|
|
|
|
// Import defaultvalues --------------------------------------------------------------
|
|
if(isset($xml->defaultvalues))
|
|
{
|
|
|
|
|
|
$results['defaultvalues']=0;
|
|
foreach ($xml->defaultvalues->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the qid
|
|
$insertdata['sqid']=$aSQIDReplacements[(int)$insertdata['sqid']]; // remap the subquestion id
|
|
|
|
// now translate any links
|
|
$default = new DefaultValue;
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
foreach ($insertdata as $k => $v)
|
|
$default->$k = $v;
|
|
$result = $default->save();
|
|
$results['defaultvalues']++;
|
|
}
|
|
}
|
|
LimeExpressionManager::SetDirtyFlag(); // so refreshes syntax highlighting
|
|
|
|
$results['newqid']=$newqid;
|
|
$results['questions']=1;
|
|
$results['labelsets']=0;
|
|
$results['labels']=0;
|
|
return $results;
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* CSVImportLabelset()
|
|
* Function responsible to import label set from CSV format.
|
|
* @param mixed $sFullFilePath
|
|
* @param mixed $options
|
|
* @return
|
|
*/
|
|
function CSVImportLabelset($sFullFilePath, $options)
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
$results['labelsets']=0;
|
|
$results['labels']=0;
|
|
$results['warnings']=array();
|
|
$csarray=buildLabelSetCheckSumArray();
|
|
//$csarray is now a keyed array with the Checksum of each of the label sets, and the lid as the key
|
|
|
|
$handle = fopen($sFullFilePath, "r");
|
|
while (!feof($handle))
|
|
{
|
|
$buffer = fgets($handle); //To allow for very long survey welcomes (up to 10k)
|
|
$bigarray[] = $buffer;
|
|
}
|
|
fclose($handle);
|
|
if (substr($bigarray[0], 0, 27) != "# LimeSurvey Label Set Dump" && substr($bigarray[0], 0, 28) != "# PHPSurveyor Label Set Dump")
|
|
{
|
|
$results['fatalerror']=$clang->gT("This file is not a LimeSurvey label set file. Import failed.");
|
|
return $results;
|
|
}
|
|
|
|
for ($i=0; $i<9; $i++) //skipping the first lines that are not needed
|
|
{
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LABEL SETS
|
|
if (array_search("# LABELS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# LABELS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$labelsetsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
|
|
//LABELS
|
|
$stoppoint = count($bigarray)-1;
|
|
|
|
for ($i=0; $i<$stoppoint; $i++)
|
|
{
|
|
// do not import empty lines
|
|
if (trim($bigarray[$i])!='')
|
|
{
|
|
$labelsarray[] = $bigarray[$i];
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
|
|
|
|
|
|
$countlabelsets = count($labelsetsarray)-1;
|
|
$countlabels = count($labelsarray)-1;
|
|
|
|
|
|
if (isset($labelsetsarray) && $labelsetsarray) {
|
|
$count=0;
|
|
foreach ($labelsetsarray as $lsa) {
|
|
$fieldorders =str_getcsv($labelsetsarray[0],',','"');
|
|
$fieldcontents=str_getcsv($lsa,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
$labelsetrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
// Save old labelid
|
|
$oldlid=$labelsetrowdata['lid'];
|
|
// set the new language
|
|
|
|
unset($labelsetrowdata['lid']);
|
|
|
|
if ($newvalues)
|
|
XSSFilterArray($newvalues);
|
|
// Insert the label set entry and get the new insert id for the labels inside this labelset
|
|
$newlid=LabelSet::model()->insertRecords($labelsetrowdata);
|
|
$results['labelsets']++;
|
|
|
|
|
|
if ($labelsarray) {
|
|
$count=0;
|
|
$lfieldorders=str_getcsv($labelsarray[0],',','"');
|
|
unset($labelsarray[0]);
|
|
foreach ($labelsarray as $la) {
|
|
|
|
$lfieldcontents=str_getcsv($la,',','"');
|
|
// Combine into one array with keys and values since its easier to handle
|
|
$labelrowdata=array_combine($lfieldorders,$lfieldcontents);
|
|
$labellid=$labelrowdata['lid'];
|
|
|
|
if ($labellid == $oldlid) {
|
|
$labelrowdata['lid']=$newlid;
|
|
|
|
// translate internal links
|
|
$labelrowdata['title']=translateLinks('label', $oldlid, $newlid, $labelrowdata['title']);
|
|
if (!isset($labelrowdata["assessment_value"]))
|
|
{
|
|
$labelrowdata["assessment_value"]=(int)$labelrowdata["code"];
|
|
}
|
|
|
|
if ($newvalues)
|
|
XSSFilterArray($newvalues);
|
|
Label::model()->insertRecords($labelrowdata);
|
|
$results['labels']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//CHECK FOR DUPLICATE LABELSETS
|
|
|
|
if (isset($_POST['checkforduplicates']))
|
|
{
|
|
$thisset="";
|
|
$query2 = "SELECT code, title, sortorder, language, assessment_value
|
|
FROM {{labels}}
|
|
WHERE lid=".$newlid."
|
|
ORDER BY language, sortorder, code";
|
|
$result2 = Yii::app()->db->createCommand($query2)->query() or safeDie("Died querying labelset $lid<br />$query2<br />");
|
|
foreach($result2->readAll() as $row2)
|
|
{
|
|
$row2 = array_values($row2);
|
|
$thisset .= implode('.', $row2);
|
|
} // while
|
|
$newcs=dechex(crc32($thisset)*1);
|
|
unset($lsmatch);
|
|
|
|
if (isset($csarray) && $options['checkforduplicates']=='on')
|
|
{
|
|
foreach($csarray as $key=>$val)
|
|
{
|
|
// echo $val."-".$newcs."<br/>"; For debug purposes
|
|
if ($val == $newcs)
|
|
{
|
|
$lsmatch=$key;
|
|
}
|
|
}
|
|
}
|
|
if (isset($lsmatch))
|
|
{
|
|
//There is a matching labelset. So, we will delete this one and refer
|
|
//to the matched one.
|
|
$query = "DELETE FROM {{labels}} WHERE lid=$newlid";
|
|
$result = Yii::app()->db->createCommand($query)->execute() or safeDie("Couldn't delete labels<br />$query<br />");
|
|
$query = "DELETE FROM {{labelsets}} WHERE lid=$newlid";
|
|
$result = Yii::app()->db->createCommand($query)->execute() or safeDie("Couldn't delete labelset<br />$query<br />");
|
|
$newlid=$lsmatch;
|
|
$results['warnings'][]=$clang->gT("Label set was not imported because the same label set already exists.")." ".sprintf($clang->gT("Existing LID: %s"),$newlid);
|
|
|
|
}
|
|
//END CHECK FOR DUPLICATES
|
|
}
|
|
}
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
|
|
/**
|
|
* XMLImportLabelsets()
|
|
* Function resp[onsible to import a labelset from XML format.
|
|
* @param mixed $sFullFilePath
|
|
* @param mixed $options
|
|
* @return
|
|
*/
|
|
function XMLImportLabelsets($sFullFilePath, $options)
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
$sXMLdata = file_get_contents($sFullFilePath);
|
|
$xml = simplexml_load_string($sXMLdata,'SimpleXMLElement',LIBXML_NONET);
|
|
if ($xml->LimeSurveyDocType!='Label set') safeDie('This is not a valid LimeSurvey label set structure XML file.');
|
|
$iDBVersion = (int) $xml->DBVersion;
|
|
$csarray=buildLabelSetCheckSumArray();
|
|
$aLSIDReplacements=array();
|
|
$results['labelsets']=0;
|
|
$results['labels']=0;
|
|
$results['warnings']=array();
|
|
|
|
// Import labels table ===================================================================================
|
|
|
|
|
|
foreach ($xml->labelsets->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$oldlsid=$insertdata['lid'];
|
|
unset($insertdata['lid']); // save the old qid
|
|
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
// Insert the new question
|
|
$result = Yii::app()->db->createCommand()->insert('{{labelsets}}', $insertdata);
|
|
$results['labelsets']++;
|
|
|
|
$newlsid=getLastInsertID('{{labelsets}}');
|
|
$aLSIDReplacements[$oldlsid]=$newlsid; // add old and new lsid to the mapping array
|
|
}
|
|
|
|
|
|
// Import labels table ===================================================================================
|
|
|
|
|
|
if (isset($xml->labels->rows->row))
|
|
foreach ($xml->labels->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['lid']=$aLSIDReplacements[$insertdata['lid']];
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
$result = Yii::app()->db->createCommand()->insert('{{labels}}', $insertdata);
|
|
$results['labels']++;
|
|
}
|
|
|
|
//CHECK FOR DUPLICATE LABELSETS
|
|
|
|
if (isset($_POST['checkforduplicates']))
|
|
{
|
|
foreach (array_values($aLSIDReplacements) as $newlid)
|
|
{
|
|
$thisset="";
|
|
$query2 = "SELECT code, title, sortorder, language, assessment_value
|
|
FROM {{labels}}
|
|
WHERE lid=".$newlid."
|
|
ORDER BY language, sortorder, code";
|
|
$result2 = Yii::app()->db->createCommand($query2)->query();
|
|
foreach($result2->readAll() as $row2)
|
|
{
|
|
$row2 = array_values($row2);
|
|
$thisset .= implode('.', $row2);
|
|
} // while
|
|
$newcs=dechex(crc32($thisset)*1);
|
|
unset($lsmatch);
|
|
|
|
if (isset($csarray) && $options['checkforduplicates']=='on')
|
|
{
|
|
foreach($csarray as $key=>$val)
|
|
{
|
|
if ($val == $newcs)
|
|
{
|
|
$lsmatch=$key;
|
|
}
|
|
}
|
|
}
|
|
if (isset($lsmatch))
|
|
{
|
|
//There is a matching labelset. So, we will delete this one and refer
|
|
//to the matched one.
|
|
$query = "DELETE FROM {{labels}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->execute();
|
|
$results['labels']=$results['labels']-$result;
|
|
$query = "DELETE FROM {{labelsets}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->query();
|
|
|
|
$results['labelsets']--;
|
|
$newlid=$lsmatch;
|
|
$results['warnings'][]=$clang->gT("Label set was not imported because the same label set already exists.")." ".sprintf($clang->gT("Existing LID: %s"),$newlid);
|
|
|
|
}
|
|
}
|
|
//END CHECK FOR DUPLICATES
|
|
}
|
|
return $results;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* This function imports the old CSV data from 1.50 to 1.87 or older. Starting with 1.90 (DBVersion 143) there is an XML format instead
|
|
*
|
|
* @param array $sFullFilePath
|
|
* @returns array Information of imported questions/answers/etc.
|
|
*/
|
|
function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=true)
|
|
{
|
|
Yii::app()->loadHelper('database');
|
|
$clang = Yii::app()->lang;
|
|
|
|
$handle = fopen($sFullFilePath, "r");
|
|
while (!feof($handle))
|
|
{
|
|
|
|
$buffer = fgets($handle);
|
|
$bigarray[] = $buffer;
|
|
}
|
|
fclose($handle);
|
|
|
|
$aIgnoredAnswers=array();
|
|
$aSQIDReplacements=array();
|
|
$aLIDReplacements=array();
|
|
$aGIDReplacements=array();
|
|
$substitutions=array();
|
|
$aQuestionCodeReplacements=array();
|
|
$aQuotaReplacements=array();
|
|
$importresults['importwarnings']=array();
|
|
$importresults['question_attributes']=0;
|
|
|
|
if (isset($bigarray[0])) $bigarray[0]=removeBOM($bigarray[0]);
|
|
|
|
// Now we try to determine the dataformat of the survey file.
|
|
$importversion=0;
|
|
if (isset($bigarray[1]) && isset($bigarray[4])&& (substr($bigarray[1], 0, 22) == "# SURVEYOR SURVEY DUMP"))
|
|
{
|
|
$importversion = 100; // Version 0.99 or 1.0 file
|
|
}
|
|
elseif
|
|
(substr($bigarray[0], 0, 24) == "# LimeSurvey Survey Dump" || substr($bigarray[0], 0, 25) == "# PHPSurveyor Survey Dump")
|
|
{ // Seems to be a >1.0 version file - these files carry the version information to read in line two
|
|
$importversion=substr($bigarray[1], 12, 3);
|
|
}
|
|
else // unknown file - show error message
|
|
{
|
|
$importresults['error'] = $clang->gT("This file is not a LimeSurvey survey file. Import failed.")."\n";
|
|
return $importresults;
|
|
}
|
|
|
|
if ((int)$importversion<112)
|
|
{
|
|
$importresults['error'] = $clang->gT("This file is too old. Only files from LimeSurvey version 1.50 (DBVersion 112) and newer are supported.");
|
|
return $importresults;
|
|
}
|
|
|
|
// okay.. now lets drop the first 9 lines and get to the data
|
|
// This works for all versions
|
|
for ($i=0; $i<9; $i++)
|
|
{
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
|
|
//SURVEYS
|
|
if (array_search("# GROUPS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# GROUPS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# GROUPS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# GROUPS TABLE\r\n", $bigarray);
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$surveyarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//GROUPS
|
|
if (array_search("# QUESTIONS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTIONS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUESTIONS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTIONS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$grouparray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//QUESTIONS
|
|
if (array_search("# ANSWERS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ANSWERS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# ANSWERS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ANSWERS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2)
|
|
{
|
|
$questionarray[] = $bigarray[$i];
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//ANSWERS
|
|
if (array_search("# CONDITIONS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# CONDITIONS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# CONDITIONS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# CONDITIONS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2)
|
|
{
|
|
$answerarray[] = str_replace("`default`", "`default_value`", $bigarray[$i]);
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//CONDITIONS
|
|
if (array_search("# LABELSETS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELSETS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# LABELSETS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELSETS TABLE\r\n", $bigarray);
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$conditionsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LABELSETS
|
|
if (array_search("# LABELS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# LABELS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# LABELS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$labelsetsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LABELS
|
|
if (array_search("# QUESTION_ATTRIBUTES TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTION_ATTRIBUTES TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUESTION_ATTRIBUTES TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUESTION_ATTRIBUTES TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$labelsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//Question attributes
|
|
if (array_search("# ASSESSMENTS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ASSESSMENTS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# ASSESSMENTS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# ASSESSMENTS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
if ($i<$stoppoint-2) {$question_attributesarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
|
|
//ASSESSMENTS
|
|
if (array_search("# SURVEYS_LANGUAGESETTINGS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# SURVEYS_LANGUAGESETTINGS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# SURVEYS_LANGUAGESETTINGS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# SURVEYS_LANGUAGESETTINGS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
// if ($i<$stoppoint-2 || $i==count($bigarray)-1)
|
|
if ($i<$stoppoint-2)
|
|
{
|
|
$assessmentsarray[] = $bigarray[$i];
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//LANGAUGE SETTINGS
|
|
if (array_search("# QUOTA TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUOTA TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUOTA TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUOTA TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
// if ($i<$stoppoint-2 || $i==count($bigarray)-1)
|
|
//$bigarray[$i]= trim($bigarray[$i]);
|
|
if (isset($bigarray[$i]) && (trim($bigarray[$i])!=''))
|
|
{
|
|
if (strpos($bigarray[$i],"#")===0)
|
|
{
|
|
unset($bigarray[$i]);
|
|
unset($bigarray[$i+1]);
|
|
unset($bigarray[$i+2]);
|
|
break ;
|
|
}
|
|
else
|
|
{
|
|
$surveylsarray[] = $bigarray[$i];
|
|
}
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//QUOTA
|
|
if (array_search("# QUOTA_MEMBERS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUOTA_MEMBERS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUOTA_MEMBERS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUOTA_MEMBERS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
// if ($i<$stoppoint-2 || $i==count($bigarray)-1)
|
|
if ($i<$stoppoint-2)
|
|
{
|
|
$quotaarray[] = $bigarray[$i];
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
//QUOTA MEMBERS
|
|
if (array_search("# QUOTA_LANGUAGESETTINGS TABLE\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUOTA_LANGUAGESETTINGS TABLE\n", $bigarray);
|
|
}
|
|
elseif (array_search("# QUOTA_LANGUAGESETTINGS TABLE\r\n", $bigarray))
|
|
{
|
|
$stoppoint = array_search("# QUOTA_LANGUAGESETTINGS TABLE\r\n", $bigarray);
|
|
}
|
|
else
|
|
{
|
|
$stoppoint = count($bigarray)-1;
|
|
}
|
|
for ($i=0; $i<=$stoppoint+1; $i++)
|
|
{
|
|
// if ($i<$stoppoint-2 || $i==count($bigarray)-1)
|
|
if ($i<$stoppoint-2)
|
|
{
|
|
$quotamembersarray[] = $bigarray[$i];
|
|
}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
|
|
//Whatever is the last table - currently
|
|
//QUOTA LANGUAGE SETTINGS
|
|
$stoppoint = count($bigarray)-1;
|
|
for ($i=0; $i<$stoppoint-1; $i++)
|
|
{
|
|
if ($i<=$stoppoint) {$quotalsarray[] = $bigarray[$i];}
|
|
unset($bigarray[$i]);
|
|
}
|
|
$bigarray = array_values($bigarray);
|
|
|
|
if (isset($surveyarray)) {$importresults['surveys'] = count($surveyarray);} else {$importresults['surveys'] = 0;}
|
|
if (isset($surveylsarray)) {$importresults['languages'] = count($surveylsarray)-1;} else {$importresults['languages'] = 1;}
|
|
if (isset($grouparray)) {$importresults['groups'] = count($grouparray)-1;} else {$importresults['groups'] = 0;}
|
|
if (isset($questionarray)) {$importresults['questions'] = count($questionarray);} else {$importresults['questions']=0;}
|
|
if (isset($answerarray)) {$importresults['answers'] = count($answerarray);} else {$importresults['answers']=0;}
|
|
if (isset($conditionsarray)) {$importresults['conditions'] = count($conditionsarray);} else {$importresults['conditions']=0;}
|
|
if (isset($labelsetsarray)) {$importresults['labelsets'] = count($labelsetsarray);} else {$importresults['labelsets']=0;}
|
|
if (isset($assessmentsarray)) {$importresults['assessments']=count($assessmentsarray);} else {$importresults['assessments']=0;}
|
|
if (isset($quotaarray)) {$importresults['quota']=count($quotaarray);} else {$importresults['quota']=0;}
|
|
if (isset($quotamembersarray)) {$importresults['quotamembers']=count($quotamembersarray);} else {$importresults['quotamembers']=0;}
|
|
if (isset($quotalsarray)) {$importresults['quotals']=count($quotalsarray);} else {$importresults['quotals']=0;}
|
|
|
|
// CREATE SURVEY
|
|
|
|
if ($importresults['surveys']>0){$importresults['surveys']--;};
|
|
if ($importresults['answers']>0){$importresults['answers']=($importresults['answers']-1)/$importresults['languages'];};
|
|
if ($importresults['groups']>0){$countgroups=($importresults['groups']-1)/$importresults['languages'];};
|
|
if ($importresults['questions']>0){$importresults['questions']=($importresults['questions']-1)/$importresults['languages'];};
|
|
if ($importresults['assessments']>0){$importresults['assessments']--;};
|
|
if ($importresults['conditions']>0){$importresults['conditions']--;};
|
|
if ($importresults['labelsets']>0){$importresults['labelsets']--;};
|
|
if ($importresults['quota']>0){$importresults['quota']--;};
|
|
$sfieldorders =str_getcsv($surveyarray[0],',','"');
|
|
$sfieldcontents=str_getcsv($surveyarray[1],',','"');
|
|
$surveyrowdata=array_combine($sfieldorders,$sfieldcontents);
|
|
$iOldSID=$surveyrowdata["sid"];
|
|
|
|
if (!$iOldSID)
|
|
{
|
|
if ($importingfrom == "http")
|
|
{
|
|
$importsurvey .= "<br /><div class='warningheader'>".$clang->gT("Error")."</div><br />\n";
|
|
$importsurvey .= $clang->gT("Import of this survey file failed")."<br />\n";
|
|
$importsurvey .= $clang->gT("File does not contain LimeSurvey data in the correct format.")."<br /><br />\n"; //Couldn't find the SID - cannot continue
|
|
$importsurvey .= "<input type='submit' value='".$clang->gT("Main Admin Screen")."' onclick=\"window.open('$scriptname', '_top')\" />\n";
|
|
$importsurvey .= "</div>\n";
|
|
unlink($sFullFilePath); //Delete the uploaded file
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
$clang->eT("Import of this survey file failed")."\n".$clang->gT("File does not contain LimeSurvey data in the correct format.")."\n";
|
|
return;
|
|
}
|
|
}
|
|
if($iDesiredSurveyId!=NULL)
|
|
{
|
|
$iNewSID = GetNewSurveyID($iDesiredSurveyId);
|
|
}
|
|
else
|
|
{
|
|
$iNewSID = GetNewSurveyID($iOldSID);
|
|
}
|
|
|
|
|
|
$insert=$surveyarray[0];
|
|
$sfieldorders =str_getcsv($surveyarray[0],',','"');
|
|
$sfieldcontents=str_getcsv($surveyarray[1],',','"');
|
|
$surveyrowdata=array_combine($sfieldorders,$sfieldcontents);
|
|
// Set new owner ID
|
|
$surveyrowdata['owner_id']=Yii::app()->session['loginID'];
|
|
// Set new survey ID
|
|
$surveyrowdata['sid']=$iNewSID;
|
|
$surveyrowdata['active']='N';
|
|
|
|
if (validateTemplateDir($surveyrowdata['template'])!==$surveyrowdata['template']) $importresults['importwarnings'][] = sprintf($clang->gT('Template %s not found, please review when activating.'),$surveyrowdata['template']);
|
|
|
|
//if (isset($surveyrowdata['datecreated'])) {$surveyrowdata['datecreated'] = $connect->BindTimeStamp($surveyrowdata['datecreated']);}
|
|
unset($surveyrowdata['attribute1']);
|
|
unset($surveyrowdata['attribute2']);
|
|
unset($surveyrowdata['usestartdate']);
|
|
unset($surveyrowdata['attributedescriptions']);
|
|
unset($surveyrowdata['notification']);
|
|
unset($surveyrowdata['useexpiry']);
|
|
unset($surveyrowdata['url']);
|
|
unset($surveyrowdata['lastpage']);
|
|
if (isset($surveyrowdata['private'])){
|
|
$surveyrowdata['anonymized']=$surveyrowdata['private'];
|
|
unset($surveyrowdata['private']);
|
|
}
|
|
if (isset($surveyrowdata['startdate'])) {unset($surveyrowdata['startdate']);}
|
|
$surveyrowdata['bounce_email']=$surveyrowdata['adminemail'];
|
|
if (empty($surveyrowdata['datecreated'])) {$surveyrowdata['datecreated'] = new CDbExpression('NOW()'); }
|
|
|
|
$iNewSID = Survey::model()->insertNewSurvey($surveyrowdata) or safeDie ("<br />".$clang->gT("Import of this survey file failed")."<br />{$surveyarray[0]}<br /><br />\n" );
|
|
|
|
// Now import the survey language settings
|
|
$fieldorders=str_getcsv($surveylsarray[0],',','"');
|
|
unset($surveylsarray[0]);
|
|
foreach ($surveylsarray as $slsrow) {
|
|
$fieldcontents=str_getcsv($slsrow,',','"');
|
|
$surveylsrowdata=array_combine($fieldorders,$fieldcontents);
|
|
// convert back the '\'.'n' char from the CSV file to true return char "\n"
|
|
$surveylsrowdata=array_map('convertCSVReturnToReturn', $surveylsrowdata);
|
|
// Convert the \n return char from welcometext to <br />
|
|
|
|
// translate internal links
|
|
if ($bTranslateLinks)
|
|
{
|
|
$surveylsrowdata['surveyls_title']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_title']);
|
|
$surveylsrowdata['surveyls_description']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_description']);
|
|
$surveylsrowdata['surveyls_welcometext']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_welcometext']);
|
|
$surveylsrowdata['surveyls_urldescription']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_urldescription']);
|
|
$surveylsrowdata['surveyls_email_invite']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_email_invite']);
|
|
$surveylsrowdata['surveyls_email_remind']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_email_remind']);
|
|
$surveylsrowdata['surveyls_email_register']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_email_register']);
|
|
$surveylsrowdata['surveyls_email_confirm']=translateLinks('survey', $iOldSID, $iNewSID, $surveylsrowdata['surveyls_email_confirm']);
|
|
}
|
|
unset($surveylsrowdata['lastpage']);
|
|
unset($surveylsrowdata['surveyls_attributecaptions']);
|
|
$surveylsrowdata['surveyls_survey_id']=$iNewSID;
|
|
|
|
$lsiresult = SurveyLanguageSetting::model()->insertNewSurvey($surveylsrowdata) or safeDie("<br />".$clang->gT("Import of this survey file failed")."<br />");
|
|
|
|
}
|
|
|
|
// The survey languagesettings are imported now
|
|
$aLanguagesSupported = array(); // this array will keep all the languages supported for the survey
|
|
|
|
$sBaseLanguage = Survey::model()->findByPk($iNewSID)->language;
|
|
$aLanguagesSupported[]=$sBaseLanguage; // adds the base language to the list of supported languages
|
|
$aLanguagesSupported=array_merge($aLanguagesSupported,Survey::model()->findByPk($iNewSID)->additionalLanguages);
|
|
|
|
|
|
// Create survey permissions
|
|
Permission::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'],$iNewSID);
|
|
|
|
$importresults['deniedcountls'] =0;
|
|
|
|
|
|
$qtypes = getQuestionTypeList("" ,"array");
|
|
$results['labels']=0;
|
|
$results['labelsets']=0;
|
|
$results['answers']=0;
|
|
$results['subquestions']=0;
|
|
|
|
//Do label sets
|
|
if (isset($labelsetsarray) && $labelsetsarray)
|
|
{
|
|
$csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets
|
|
$count=0;
|
|
foreach ($labelsetsarray as $lsa) {
|
|
$fieldorders =str_getcsv($labelsetsarray[0],',','"');
|
|
$fieldcontents=str_getcsv($lsa,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
$labelsetrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
// Save old labelid
|
|
$oldlid=$labelsetrowdata['lid'];
|
|
|
|
unset($labelsetrowdata['lid']);
|
|
|
|
$lblsets=LabelSet::model();
|
|
// Get the new insert id for the labels inside this labelset
|
|
$newlid = $lblsets->insertRecords($labelsetrowdata);
|
|
$results['labelsets']++;
|
|
|
|
if ($labelsarray) {
|
|
$count=0;
|
|
foreach ($labelsarray as $la) {
|
|
$lfieldorders =str_getcsv($labelsarray[0],',','"');
|
|
$lfieldcontents=str_getcsv($la,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
// Combine into one array with keys and values since its easier to handle
|
|
$labelrowdata=array_combine($lfieldorders,$lfieldcontents);
|
|
$labellid=$labelrowdata['lid'];
|
|
if ($importversion<=132)
|
|
{
|
|
$labelrowdata["assessment_value"]=(int)$labelrowdata["code"];
|
|
}
|
|
if ($labellid == $oldlid) {
|
|
$labelrowdata['lid']=$newlid;
|
|
|
|
// translate internal links
|
|
if ($bTranslateLinks) $labelrowdata['title']=translateLinks('label', $oldlid, $newlid, $labelrowdata['title']);
|
|
|
|
$liresult = Label::model()->insertRecords($labelrowdata);
|
|
|
|
if ($liresult!==false) $results['labels']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
//CHECK FOR DUPLICATE LABELSETS
|
|
$thisset="";
|
|
|
|
$query2 = "SELECT code, title, sortorder, language, assessment_value
|
|
FROM {{labels}}
|
|
WHERE lid=".$newlid."
|
|
ORDER BY language, sortorder, code";
|
|
$result2 = Yii::app()->db->createCommand($query2)->query() or die("Died querying labelset $lid<br />");
|
|
|
|
foreach($result2->readAll() as $row2)
|
|
{
|
|
$row2 = array_values($row2);
|
|
$thisset .= implode('.', $row2);
|
|
} // while
|
|
$newcs=dechex(crc32($thisset)*1);
|
|
unset($lsmatch);
|
|
if (isset($csarray))
|
|
{
|
|
foreach($csarray as $key=>$val)
|
|
{
|
|
if ($val == $newcs)
|
|
{
|
|
$lsmatch=$key;
|
|
}
|
|
}
|
|
}
|
|
if (isset($lsmatch) || Permission::model()->hasGlobalPermission('labelsets','import'))
|
|
{
|
|
//There is a matching labelset or the user is not allowed to edit labels -
|
|
// So, we will delete this one and refer to the matched one.
|
|
|
|
$query = "DELETE FROM {{labels}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->execute();
|
|
$results['labels']=$results['labels']-$result;
|
|
|
|
$query = "DELETE FROM {{labelsets}} WHERE lid=$newlid";
|
|
$result=Yii::app()->db->createCommand($query)->execute();
|
|
$results['labelsets']=$results['labelsets']-$result;
|
|
$newlid=$lsmatch;
|
|
}
|
|
else
|
|
{
|
|
//There isn't a matching labelset, add this checksum to the $csarray array
|
|
$csarray[$newlid]=$newcs;
|
|
}
|
|
//END CHECK FOR DUPLICATES
|
|
$aLIDReplacements[$oldlid]=$newlid;
|
|
}
|
|
}
|
|
|
|
// Import groups
|
|
if (isset($grouparray) && $grouparray)
|
|
{
|
|
// do GROUPS
|
|
$gafieldorders=str_getcsv($grouparray[0],',','"');
|
|
unset($grouparray[0]);
|
|
foreach ($grouparray as $ga)
|
|
{
|
|
$gacfieldcontents=str_getcsv($ga,',','"');
|
|
$grouprowdata=array_combine($gafieldorders,$gacfieldcontents);
|
|
|
|
//Now an additional integrity check if there are any groups not belonging into this survey
|
|
if ($grouprowdata['sid'] != $iOldSID)
|
|
{
|
|
$results['fatalerror'] = $clang->gT("A group in the CSV/SQL file is not part of the same survey. The import of the survey was stopped.")."<br />\n";
|
|
return $results;
|
|
}
|
|
$grouprowdata['sid']=$iNewSID;
|
|
// remember group id
|
|
$oldgid=$grouprowdata['gid'];
|
|
|
|
//update/remove the old group id
|
|
if (isset($aGIDReplacements[$oldgid]))
|
|
$grouprowdata['gid'] = $aGIDReplacements[$oldgid];
|
|
else
|
|
unset($grouprowdata['gid']);
|
|
|
|
// Everything set - now insert it
|
|
$grouprowdata=array_map('convertCSVReturnToReturn', $grouprowdata);
|
|
|
|
// translate internal links
|
|
if ($bTranslateLinks)
|
|
{
|
|
$grouprowdata['group_name']=translateLinks('survey', $iOldSID, $iNewSID, $grouprowdata['group_name']);
|
|
$grouprowdata['description']=translateLinks('survey', $iOldSID, $iNewSID, $grouprowdata['description']);
|
|
}
|
|
|
|
if (isset($grouprowdata['gid'])) switchMSSQLIdentityInsert('groups',true);
|
|
|
|
|
|
$sInsertID = QuestionGroup::model()->insertRecords($grouprowdata) or safeDie($clang->gT('Error').": Failed to insert group<br />\<br />\n");
|
|
|
|
if (isset($grouprowdata['gid'])) switchMSSQLIdentityInsert('groups',false);
|
|
if (!isset($grouprowdata['gid']))
|
|
{
|
|
$aGIDReplacements[$oldgid]=$sInsertID;
|
|
}
|
|
}
|
|
// Fix sortorder of the groups - if users removed groups manually from the csv file there would be gaps
|
|
fixSortOrderGroups($iNewSID);
|
|
}
|
|
// GROUPS is DONE
|
|
|
|
// Import questions
|
|
if (isset($questionarray) && $questionarray)
|
|
{
|
|
$qafieldorders=str_getcsv($questionarray[0],',','"');
|
|
unset($questionarray[0]);
|
|
foreach ($questionarray as $qa)
|
|
{
|
|
$qacfieldcontents=str_getcsv($qa,',','"');
|
|
$questionrowdata=array_combine($qafieldorders,$qacfieldcontents);
|
|
$questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata);
|
|
$questionrowdata["type"]=strtoupper($questionrowdata["type"]);
|
|
|
|
// Skip not supported languages
|
|
if (!in_array($questionrowdata['language'],$aLanguagesSupported))
|
|
continue;
|
|
|
|
// replace the sid
|
|
$questionrowdata["sid"] = $iNewSID;
|
|
// Skip if gid is invalid
|
|
if (!isset($aGIDReplacements[$questionrowdata['gid']])) continue;
|
|
$questionrowdata["gid"] = $aGIDReplacements[$questionrowdata['gid']];
|
|
if (isset($aQIDReplacements[$questionrowdata['qid']]))
|
|
{
|
|
$questionrowdata['qid']=$aQIDReplacements[$questionrowdata['qid']];
|
|
}
|
|
else
|
|
{
|
|
$oldqid=$questionrowdata['qid'];
|
|
unset($questionrowdata['qid']);
|
|
}
|
|
|
|
unset($oldlid1); unset($oldlid2);
|
|
if ((isset($questionrowdata['lid']) && $questionrowdata['lid']>0))
|
|
{
|
|
$oldlid1=$questionrowdata['lid'];
|
|
}
|
|
if ((isset($questionrowdata['lid1']) && $questionrowdata['lid1']>0))
|
|
{
|
|
$oldlid2=$questionrowdata['lid1'];
|
|
}
|
|
unset($questionrowdata['lid']);
|
|
unset($questionrowdata['lid1']);
|
|
if ($questionrowdata['type']=='W')
|
|
{
|
|
$questionrowdata['type']='!';
|
|
}
|
|
elseif ($questionrowdata['type']=='Z')
|
|
{
|
|
$questionrowdata['type']='L';
|
|
$aIgnoredAnswers[]=$oldqid;
|
|
}
|
|
|
|
if (!isset($questionrowdata["question_order"]) || $questionrowdata["question_order"]=='') {$questionrowdata["question_order"]=0;}
|
|
// translate internal links
|
|
if ($bTranslateLinks)
|
|
{
|
|
$questionrowdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $questionrowdata['question']);
|
|
$questionrowdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $questionrowdata['help']);
|
|
}
|
|
$oQuestion = new Question();
|
|
$oQuestion->setAttributes($questionrowdata, false);
|
|
|
|
// Try to fix question title for valid question code enforcement
|
|
if(!$oQuestion->validate(array('title')))
|
|
{
|
|
$sOldTitle=$oQuestion->title;
|
|
$sNewTitle=preg_replace("/[^A-Za-z0-9]/", '', $sOldTitle);
|
|
if (is_numeric(substr($sNewTitle,0,1)))
|
|
{
|
|
$sNewTitle='q' . $sNewTitle;
|
|
}
|
|
$oQuestion->title =$sNewTitle;
|
|
}
|
|
|
|
$attempts = 0;
|
|
// Try to fix question title for unique question code enforcement
|
|
while (!$oQuestion->validate(array('title')))
|
|
{
|
|
if (!isset($index))
|
|
{
|
|
$index = 0;
|
|
$rand = mt_rand(0, 1024);
|
|
}
|
|
else
|
|
{
|
|
$index++;
|
|
}
|
|
$sNewTitle='r' . $rand . 'q' . $index;
|
|
$oQuestion->title = $sNewTitle;
|
|
$attempts++;
|
|
if ($attempts > 10)
|
|
{
|
|
safeDie($clang->gT("Error").": Failed to resolve question code problems after 10 attempts.<br />");
|
|
}
|
|
}
|
|
if (!$oQuestion->save())
|
|
{
|
|
// safeDie($clang->gT("Error while saving: "). print_r($oQuestion->errors, true));
|
|
//
|
|
// In PHP 5.2.10 a bug is triggered that resets the foreach loop when inserting a record
|
|
// Problem is that it is the default PHP version on Ubuntu 12.04 LTS (which is currently very common in use)
|
|
// For this reason we ignore insertion errors (because it is most likely a duplicate)
|
|
// and continue with the next one
|
|
continue;
|
|
}
|
|
// Set a warning if question title was updated
|
|
if(isset($sNewTitle))
|
|
{
|
|
$importresults['importwarnings'][] = sprintf($clang->gT("Question code %s was updated to %s."),$sOldTitle,$sNewTitle);
|
|
$aQuestionCodeReplacements[$sOldTitle]=$sNewTitle;
|
|
unset($sNewTitle);
|
|
unset($sOldTitle);
|
|
}
|
|
$sInsertID = $oQuestion->qid;
|
|
if (isset($questionrowdata['qid'])) {
|
|
switchMSSQLIdentityInsert('questions',false);
|
|
$saveqid=$questionrowdata['qid'];
|
|
}
|
|
else
|
|
{
|
|
$saveqid=$aQIDReplacements[$oldqid]=$sInsertID;
|
|
}
|
|
|
|
// Now we will fix up old label sets where they are used as answers
|
|
if (((isset($oldlid1) && isset($aLIDReplacements[$oldlid1])) || (isset($oldlid2) && isset($aLIDReplacements[$oldlid2]))) && ($qtypes[$questionrowdata['type']]['answerscales']>0 || $qtypes[$questionrowdata['type']]['subquestions']>1))
|
|
{
|
|
|
|
$query="select * from {{labels}} where lid={$aLIDReplacements[$oldlid1]} and language='{$questionrowdata['language']}'";
|
|
$oldlabelsresult=Yii::app()->db->createCommand($query)->query();
|
|
foreach($oldlabelsresult->readAll() as $labelrow)
|
|
{
|
|
if (in_array($labelrow['language'],$aLanguagesSupported))
|
|
{
|
|
|
|
if ($qtypes[$questionrowdata['type']]['subquestions']<2)
|
|
{
|
|
$aInsertData=array('qid'=>$aQIDReplacements[$oldqid],'code'=>$labelrow['code'],'answer'=>$labelrow['title'],'sortorder'=>$labelrow['sortorder'],'language'=>$labelrow['language'],'assessment_value'=>$labelrow['assessment_value']);
|
|
Answer::model()->insertRecords($aInsertData) or safeDie($clang->gT("Error").": Failed to insert data [4]<br />");
|
|
}
|
|
else
|
|
{
|
|
if (isset($aSQIDReplacements[$labelrow['code'].'_'.$saveqid])){
|
|
$fieldname='qid,';
|
|
$data=$aSQIDReplacements[$labelrow['code'].'_'.$saveqid].',';
|
|
}
|
|
else{
|
|
$fieldname='' ;
|
|
$data='';
|
|
}
|
|
|
|
$qinsert = "insert INTO {{questions}} ($fieldname parent_qid,title,question,question_order,language,scale_id,type, sid, gid)
|
|
VALUES ($data{$aQIDReplacements[$oldqid]},'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."',1,'{$questionrowdata['type']}',{$questionrowdata['sid']},{$questionrowdata['gid']})";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie ($clang->gT("Error").": Failed to insert question <br />\n$qinsert<br />\n");
|
|
if ($fieldname=='')
|
|
{
|
|
$aSQIDReplacements[$labelrow['code'].'_'.$saveqid]=getLastInsertID('{{questions}}');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (isset($oldlid2) && $qtypes[$questionrowdata['type']]['answerscales']>1)
|
|
{
|
|
|
|
$query="select * from {{labels}} where lid={$aLIDReplacements[$oldlid2]} and language='{$questionrowdata['language']}'";
|
|
$oldlabelsresult=Yii::app()->db->createCommand($query)->query();
|
|
foreach($oldlabelsresult->readAll() as $labelrow)
|
|
|
|
{
|
|
$qinsert = "insert INTO {{answers}} (qid,code,answer,sortorder,language,assessment_value,scale_id)
|
|
VALUES ({$aQIDReplacements[$oldqid]},'".$labelrow['code']."','".$labelrow['title']."','".$labelrow['sortorder']."','".$labelrow['language']."','".$labelrow['assessment_value']."',1)";
|
|
$qres = Yii::app()->db->createCommand($qinsert)->query() or safeDie ($clang->gT("Error").": Failed to insert answer (lid2)<br />\n$qinsert<br />\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//Do answers
|
|
if (isset($answerarray) && $answerarray)
|
|
{
|
|
$answerfieldnames = str_getcsv($answerarray[0],',','"');
|
|
unset($answerarray[0]);
|
|
|
|
foreach ($answerarray as $aa)
|
|
{
|
|
$answerfieldcontents = str_getcsv($aa,',','"');
|
|
$answerrowdata = array_combine($answerfieldnames,$answerfieldcontents);
|
|
if (in_array($answerrowdata['qid'],$aIgnoredAnswers))
|
|
{
|
|
// Due to a bug in previous LS versions there may be orphaned answers with question type Z (which is now L)
|
|
// this way they are ignored
|
|
continue;
|
|
}
|
|
if ($answerrowdata===false)
|
|
{
|
|
$importquestion.='<br />'.$clang->gT("Faulty line in import - fields and data don't match").":".implode(',',$answerfieldcontents);
|
|
}
|
|
// Skip not supported languages
|
|
if (!in_array($answerrowdata['language'],$aLanguagesSupported))
|
|
continue;
|
|
|
|
// replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this answer is orphan -> error, skip this record)
|
|
if (isset($aQIDReplacements[$answerrowdata["qid"]]))
|
|
$answerrowdata["qid"] = $aQIDReplacements[$answerrowdata["qid"]];
|
|
else
|
|
continue; // a problem with this answer record -> don't consider
|
|
|
|
if ($importversion<=132)
|
|
{
|
|
$answerrowdata["assessment_value"]=(int)$answerrowdata["code"];
|
|
}
|
|
// Convert default values for single select questions
|
|
$query1 = 'select type,gid from {{questions}} where qid='.$answerrowdata["qid"];
|
|
|
|
$resultquery1 = Yii::app()->db->createCommand($query1)->query();
|
|
$questiontemp=$resultquery1->read();
|
|
|
|
$oldquestion['newtype']=$questiontemp['type'];
|
|
$oldquestion['gid']=$questiontemp['gid'];
|
|
if ($answerrowdata['default_value']=='Y' && ($oldquestion['newtype']=='L' || $oldquestion['newtype']=='O' || $oldquestion['newtype']=='!'))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid']=$newqid;
|
|
$insertdata['language']=$answerrowdata['language'];
|
|
$insertdata['defaultvalue']=$answerrowdata['answer'];
|
|
$qres = DefaultValue::model()->insertRecords($insertdata) or safeDie ("Error: Failed to insert defaultvalue <br />");
|
|
}
|
|
// translate internal links
|
|
if ($bTranslateLinks)
|
|
{
|
|
$answerrowdata['answer']=translateLinks('survey', $iOldSID, $iNewSID, $answerrowdata['answer']);
|
|
}
|
|
// Everything set - now insert it
|
|
$answerrowdata = array_map('convertCSVReturnToReturn', $answerrowdata);
|
|
|
|
if ($qtypes[$oldquestion['newtype']]['subquestions']>0) //hmmm.. this is really a subquestion
|
|
{
|
|
$questionrowdata=array();
|
|
if (isset($aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']])){
|
|
$questionrowdata['qid']=$aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']];
|
|
}
|
|
$questionrowdata['parent_qid']=$answerrowdata['qid'];;
|
|
$questionrowdata['sid']=$iNewSID;
|
|
$questionrowdata['gid']=$oldquestion['gid'];
|
|
$questionrowdata['title']=$answerrowdata['code'];
|
|
$questionrowdata['question']=$answerrowdata['answer'];
|
|
$questionrowdata['question_order']=$answerrowdata['sortorder'];
|
|
$questionrowdata['language']=$answerrowdata['language'];
|
|
$questionrowdata['type']=$oldquestion['newtype'];
|
|
if (isset($questionrowdata['qid'])) switchMSSQLIdentityInsert('questions',true);
|
|
if ($questionrowdata)
|
|
XSSFilterArray($questionrowdata);
|
|
|
|
$question = new Question();
|
|
$question->setAttributes($questionrowdata, false);
|
|
// Try to fix question title for valid question code enforcement
|
|
if(!$question->validate(array('title')))
|
|
{
|
|
$sOldTitle=$question->title;
|
|
$sNewTitle=preg_replace("/[^A-Za-z0-9]/", '', $sOldTitle);
|
|
if (is_numeric(substr($sNewTitle,0,1)))
|
|
{
|
|
$sNewTitle='sq' . $sNewTitle;
|
|
}
|
|
$question->title =$sNewTitle;
|
|
}
|
|
$attempts = 0;
|
|
// Try to fix question title for unique question code enforcement
|
|
while (!$question->validate(array('title')))
|
|
{
|
|
if (!isset($index))
|
|
{
|
|
$index = 0;
|
|
$rand = mt_rand(0, 1024);
|
|
}
|
|
else
|
|
{
|
|
$index++;
|
|
}
|
|
$sNewTitle='r' . $rand . 'sq' . $index;
|
|
$question->title = $sNewTitle;
|
|
$attempts++;
|
|
if ($attempts > 10)
|
|
{
|
|
safeDie($clang->gT("Error").": Failed to resolve question code problems after 10 attempts.<br />");
|
|
}
|
|
}
|
|
if (!$question->save())
|
|
{
|
|
// safeDie($clang->gT("Error while saving: "). print_r($question->errors, true));
|
|
//
|
|
// In PHP 5.2.10 and some later versions a bug is triggered that resets the foreach loop when inserting a record
|
|
// Problem is that it is the default PHP version on Ubuntu 12.04 LTS (which is currently very common in use)
|
|
// For this reason we ignore insertion errors (because it is most likely a duplicate)
|
|
// and continue with the next one
|
|
continue;
|
|
}
|
|
// Set a warning if question title was updated
|
|
if(isset($sNewTitle))
|
|
{
|
|
$importresults['importwarnings'][] = sprintf($clang->gT("Title of subquestion %s was updated to %s."),$sOldTitle,$sNewTitle);// Maybe add the question title ?
|
|
$aQuestionCodeReplacements[$sOldTitle]=$sNewTitle;
|
|
unset($sNewTitle);
|
|
unset($sOldTitle);
|
|
}
|
|
$questionrowdata = $question->qid;
|
|
if (!isset($questionrowdata['qid']))
|
|
{
|
|
$aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']]=$sInsertID;
|
|
}
|
|
else
|
|
{
|
|
switchMSSQLIdentityInsert('questions',false);
|
|
}
|
|
|
|
$results['subquestions']++;
|
|
// also convert default values subquestions for multiple choice
|
|
if ($answerrowdata['default_value']=='Y' && ($oldquestion['newtype']=='M' || $oldquestion['newtype']=='P'))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid']=$newqid;
|
|
$insertdata['sqid']=$aSQIDReplacements[$answerrowdata['code']];
|
|
$insertdata['language']=$answerrowdata['language'];
|
|
$insertdata['defaultvalue']='Y';
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
$qres = DefaultValue::model()->insertRecords($insertdata) or safeDie("Error: Failed to insert defaultvalue <br />");
|
|
}
|
|
|
|
}
|
|
else // insert answers
|
|
{
|
|
unset($answerrowdata['default_value']);
|
|
if ($answerrowdata)
|
|
XSSFilterArray($answerrowdata);
|
|
$ares = Answer::model()->insertRecords($answerrowdata) or safeDie("Error: Failed to insert answer<br />");
|
|
$results['answers']++;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// get all group ids and fix questions inside each group
|
|
$gquery = "SELECT gid FROM {{groups}} where sid=$iNewSID group by gid ORDER BY gid"; //Get last question added (finds new qid)
|
|
$gres = Yii::app()->db->createCommand($gquery)->query();
|
|
foreach ($gres->readAll() as $grow)
|
|
{
|
|
Question::model()->updateQuestionOrder($grow['gid'], $iNewSID);
|
|
}
|
|
|
|
//We've built two arrays along the way - one containing the old SID, GID and QIDs - and their NEW equivalents
|
|
//and one containing the old 'extended fieldname' and its new equivalent. These are needed to import conditions and question_attributes.
|
|
if (isset($question_attributesarray) && $question_attributesarray) {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES
|
|
$fieldorders =str_getcsv($question_attributesarray[0],',','"');
|
|
unset($question_attributesarray[0]);
|
|
foreach ($question_attributesarray as $qar) {
|
|
$fieldcontents=str_getcsv($qar,',','"');
|
|
$qarowdata=array_combine($fieldorders,$fieldcontents);
|
|
$newqid="";
|
|
$qarowdata["qid"]=$aQIDReplacements[$qarowdata["qid"]];
|
|
unset($qarowdata["qaid"]);
|
|
$result=QuestionAttribute::model()->insertRecords($qarowdata);
|
|
if ($result>0) {$importresults['question_attributes']++;}
|
|
}
|
|
}
|
|
|
|
if (isset($assessmentsarray) && $assessmentsarray) {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUTES
|
|
$fieldorders=str_getcsv($assessmentsarray[0],',','"');
|
|
unset($assessmentsarray[0]);
|
|
foreach ($assessmentsarray as $qar)
|
|
{
|
|
$fieldcontents=str_getcsv($qar,',','"');
|
|
$asrowdata=array_combine($fieldorders,$fieldcontents);
|
|
if (isset($asrowdata['link']))
|
|
{
|
|
if (trim($asrowdata['link'])!='') $asrowdata['message']=$asrowdata['message'].'<br /><a href="'.$asrowdata['link'].'">'.$asrowdata['link'].'</a>';
|
|
unset($asrowdata['link']);
|
|
}
|
|
if ($asrowdata["gid"]>0)
|
|
{
|
|
$asrowdata["gid"]=$aGIDReplacements[$asrowdata["gid"]];
|
|
}
|
|
|
|
$asrowdata["sid"]=$iNewSID;
|
|
unset($asrowdata["id"]);
|
|
|
|
$result=Assessment::model()->insertRecords($asrowdata) or safeDie("Couldn't insert assessment<br />");
|
|
|
|
unset($newgid);
|
|
}
|
|
}
|
|
|
|
if (isset($quotaarray) && $quotaarray) {//ONLY DO THIS IF THERE ARE QUOTAS
|
|
$fieldorders=str_getcsv($quotaarray[0],',','"');
|
|
unset($quotaarray[0]);
|
|
foreach ($quotaarray as $qar)
|
|
{
|
|
$fieldcontents=str_getcsv($qar,',','"');
|
|
$asrowdata=array_combine($fieldorders,$fieldcontents);
|
|
$asrowdata["sid"]=$iNewSID;
|
|
$oldid = $asrowdata["id"];
|
|
unset($asrowdata["id"]);
|
|
$quotadata[]=$asrowdata; //For use later if needed
|
|
$sInsertID=Quota::model()->insertRecords($asrowdata) or safeDie ("Couldn't insert quota<br />");
|
|
$aQuotaReplacements[$oldid]=$sInsertID;
|
|
}
|
|
}
|
|
|
|
if (isset($quotamembersarray) && $quotamembersarray) {//ONLY DO THIS IF THERE ARE QUOTA MEMBERS
|
|
$count=0;
|
|
foreach ($quotamembersarray as $qar) {
|
|
|
|
$fieldorders =str_getcsv($quotamembersarray[0],',','"');
|
|
$fieldcontents=str_getcsv($qar,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
$asrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
$iOldSID=$asrowdata["sid"];
|
|
$oldqid=$asrowdata['qid'];
|
|
$oldquotaid=$asrowdata['quota_id'];
|
|
|
|
$newquotaid=$aQuotaReplacements[$oldquotaid];
|
|
|
|
$asrowdata["sid"]=$iNewSID;
|
|
$asrowdata["qid"]=$aQIDReplacements[$oldqid];
|
|
$asrowdata["quota_id"]=$newquotaid;
|
|
unset($asrowdata["id"]);
|
|
|
|
$result=QuotaMember::model()->insertRecords($asrowdata) or safeDie("Couldn't insert quota<br />");
|
|
|
|
}
|
|
}
|
|
|
|
if (isset($quotalsarray) && $quotalsarray) {//ONLY DO THIS IF THERE ARE QUOTA LANGUAGE SETTINGS
|
|
$count=0;
|
|
foreach ($quotalsarray as $qar) {
|
|
|
|
$fieldorders =str_getcsv($quotalsarray[0],',','"');
|
|
$fieldcontents=str_getcsv($qar,',','"');
|
|
if ($count==0) {$count++; continue;}
|
|
|
|
$asrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
$newquotaid="";
|
|
$oldquotaid=$asrowdata['quotals_quota_id'];
|
|
|
|
$newquotaid=$aQuotaReplacements[$oldquotaid];
|
|
|
|
$asrowdata["quotals_quota_id"]=$newquotaid;
|
|
unset($asrowdata["quotals_id"]);
|
|
|
|
$result=QuotaLanguageSetting::model()->insertRecords($asrowdata) or safeDie("Couldn't insert quota<br />");
|
|
}
|
|
}
|
|
|
|
//if there are quotas, but no quotals, then we need to create default dummy for each quota (this handles exports from pre-language quota surveys)
|
|
if ($importresults['quota'] > 0 && (!isset($importresults['quotals']) || $importresults['quotals'] == 0)) {
|
|
$i=0;
|
|
$defaultsurveylanguage=isset($defaultsurveylanguage) ? $defaultsurveylanguage : "en";
|
|
foreach($aQuotaReplacements as $oldquotaid=>$newquotaid) {
|
|
$asrowdata=array("quotals_quota_id" => $newquotaid,
|
|
"quotals_language" => $defaultsurveylanguage,
|
|
"quotals_name" => $quotadata[$i]["name"],
|
|
"quotals_message" => $clang->gT("Sorry your responses have exceeded a quota on this survey."),
|
|
"quotals_url" => "",
|
|
"quotals_urldescrip" => "");
|
|
$i++;
|
|
}
|
|
|
|
$result=QuotaLanguageSetting::model()->insertRecords($asrowdata) or safeDie("Couldn't insert quota<br />");
|
|
$countquotals=$i;
|
|
}
|
|
|
|
// Do conditions
|
|
if (isset($conditionsarray) && $conditionsarray) {//ONLY DO THIS IF THERE ARE CONDITIONS!
|
|
$fieldorders =str_getcsv($conditionsarray[0],',','"');
|
|
unset($conditionsarray[0]);
|
|
// Exception for conditions based on attributes
|
|
$aQIDReplacements[0]=0;
|
|
foreach ($conditionsarray as $car) {
|
|
$fieldcontents=str_getcsv($car,',','"');
|
|
$conditionrowdata=array_combine($fieldorders,$fieldcontents);
|
|
|
|
unset($conditionrowdata["cid"]);
|
|
if (!isset($conditionrowdata["method"]) || trim($conditionrowdata["method"])=='')
|
|
{
|
|
$conditionrowdata["method"]='==';
|
|
}
|
|
if (!isset($conditionrowdata["scenario"]) || trim($conditionrowdata["scenario"])=='')
|
|
{
|
|
$conditionrowdata["scenario"]=1;
|
|
}
|
|
$oldcqid=$conditionrowdata["cqid"];
|
|
$query = 'select gid from {{questions}} where qid='.$aQIDReplacements[$conditionrowdata["cqid"]];
|
|
$res=Yii::app()->db->createCommand($query)->query();
|
|
$resrow = $res->read();
|
|
|
|
$oldgid=array_search($resrow['gid'],$aGIDReplacements);
|
|
$conditionrowdata["qid"]=$aQIDReplacements[$conditionrowdata["qid"]];
|
|
$conditionrowdata["cqid"]=$aQIDReplacements[$conditionrowdata["cqid"]];
|
|
$oldcfieldname=$conditionrowdata["cfieldname"];
|
|
$conditionrowdata["cfieldname"]=str_replace($iOldSID.'X'.$oldgid.'X'.$oldcqid,$iNewSID.'X'.$aGIDReplacements[$oldgid].'X'.$conditionrowdata["cqid"],$conditionrowdata["cfieldname"]);
|
|
|
|
$result=Condition::model()->insertRecords($conditionrowdata) or safeDie("Couldn't insert condition<br />");
|
|
|
|
}
|
|
}
|
|
replaceExpressionCodes($iNewSID,$aQuestionCodeReplacements);
|
|
LimeExpressionManager::RevertUpgradeConditionsToRelevance($iNewSID);
|
|
LimeExpressionManager::UpgradeConditionsToRelevance($iNewSID);
|
|
LimeExpressionManager::SetSurveyId($iNewSID);
|
|
|
|
$importresults['importversion']=$importversion;
|
|
$importresults['newsid']=$iNewSID;
|
|
$importresults['oldsid']=$iOldSID;
|
|
return $importresults;
|
|
}
|
|
|
|
|
|
function importSurveyFile($sFullFilePath, $bTranslateLinksFields, $sNewSurveyName=NULL, $DestSurveyID=NULL)
|
|
{
|
|
$aPathInfo = pathinfo($sFullFilePath);
|
|
if (isset($aPathInfo['extension']))
|
|
{
|
|
$sExtension = $aPathInfo['extension'];
|
|
}
|
|
else
|
|
{
|
|
$sExtension = "";
|
|
}
|
|
if (isset($sExtension) && strtolower($sExtension) == 'csv')
|
|
{
|
|
return CSVImportSurvey($sFullFilePath, $DestSurveyID, $bTranslateLinksFields);
|
|
}
|
|
elseif (isset($sExtension) && strtolower($sExtension) == 'lss')
|
|
{
|
|
return XMLImportSurvey($sFullFilePath, null, $sNewSurveyName, $DestSurveyID, $bTranslateLinksFields);
|
|
}
|
|
elseif (isset($sExtension) && strtolower($sExtension) == 'txt')
|
|
{
|
|
return TSVImportSurvey($sFullFilePath);
|
|
}
|
|
elseif (isset($sExtension) && strtolower($sExtension) == 'lsa') // Import a survey archive
|
|
{
|
|
Yii::import("application.libraries.admin.pclzip.pclzip", true);
|
|
$pclzip = new PclZip(array('p_zipname' => $sFullFilePath));
|
|
$aFiles = $pclzip->listContent();
|
|
|
|
if ($pclzip->extract(PCLZIP_OPT_PATH, Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR, PCLZIP_OPT_BY_EREG, '/(lss|lsr|lsi|lst)$/') == 0)
|
|
{
|
|
unset($pclzip);
|
|
}
|
|
// Step 1 - import the LSS file and activate the survey
|
|
foreach ($aFiles as $aFile)
|
|
{
|
|
if (pathinfo($aFile['filename'], PATHINFO_EXTENSION) == 'lss')
|
|
{
|
|
//Import the LSS file
|
|
$aImportResults = XMLImportSurvey(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename'], null, null, null, true, false);
|
|
// Activate the survey
|
|
Yii::app()->loadHelper("admin/activate");
|
|
$activateoutput = activateSurvey($aImportResults['newsid']);
|
|
unlink(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename']);
|
|
break;
|
|
}
|
|
}
|
|
// Step 2 - import the responses file
|
|
foreach ($aFiles as $aFile)
|
|
{
|
|
if (pathinfo($aFile['filename'], PATHINFO_EXTENSION) == 'lsr')
|
|
{
|
|
//Import the LSS file
|
|
$aResponseImportResults = XMLImportResponses(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename'], $aImportResults['newsid'], $aImportResults['FieldReMap']);
|
|
$aImportResults = array_merge($aResponseImportResults, $aImportResults);
|
|
unlink(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename']);
|
|
break;
|
|
}
|
|
}
|
|
// Step 3 - import the tokens file - if exists
|
|
foreach ($aFiles as $aFile)
|
|
{
|
|
if (pathinfo($aFile['filename'], PATHINFO_EXTENSION) == 'lst')
|
|
{
|
|
Yii::app()->loadHelper("admin/token");
|
|
if (createTokenTable($aImportResults['newsid']))
|
|
$aTokenCreateResults = array('tokentablecreated' => true);
|
|
$aImportResults = array_merge($aTokenCreateResults, $aImportResults);
|
|
$aTokenImportResults = XMLImportTokens(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename'], $aImportResults['newsid']);
|
|
$aImportResults = array_merge_recursive($aTokenImportResults, $aImportResults);
|
|
$aImportResults['importwarnings']=array_merge($aImportResults['importwarnings'],$aImportResults['warnings']);
|
|
unlink(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename']);
|
|
break;
|
|
}
|
|
}
|
|
// Step 4 - import the timings file - if exists
|
|
Yii::app()->db->schema->refresh();
|
|
foreach ($aFiles as $aFile)
|
|
{
|
|
if (pathinfo($aFile['filename'], PATHINFO_EXTENSION) == 'lsi' && tableExists("survey_{$aImportResults['newsid']}_timings"))
|
|
{
|
|
$aTimingsImportResults = XMLImportTimings(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename'], $aImportResults['newsid'], $aImportResults['FieldReMap']);
|
|
$aImportResults = array_merge($aTimingsImportResults, $aImportResults);
|
|
unlink(Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . $aFile['filename']);
|
|
break;
|
|
}
|
|
}
|
|
return $aImportResults;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* This function imports a LimeSurvey .lss survey XML file
|
|
*
|
|
* @param mixed $sFullFilePath The full filepath of the uploaded file
|
|
*/
|
|
function XMLImportSurvey($sFullFilePath,$sXMLdata=NULL,$sNewSurveyName=NULL,$iDesiredSurveyId=NULL, $bTranslateInsertansTags=true, $bConvertInvalidQuestionCodes=true)
|
|
{
|
|
Yii::app()->loadHelper('database');
|
|
$clang = Yii::app()->lang;
|
|
|
|
$aGIDReplacements = array();
|
|
if ($sXMLdata == NULL)
|
|
{
|
|
$sXMLdata = file_get_contents($sFullFilePath);
|
|
}
|
|
$xml = @simplexml_load_string($sXMLdata,'SimpleXMLElement',LIBXML_NONET);
|
|
|
|
if (!$xml || $xml->LimeSurveyDocType!='Survey')
|
|
{
|
|
$results['error'] = $clang->gT("This is not a valid LimeSurvey survey structure XML file.");
|
|
return $results;
|
|
}
|
|
|
|
$iDBVersion = (int) $xml->DBVersion;
|
|
$aQIDReplacements=array();
|
|
$aQuestionCodeReplacements=array();
|
|
$aQuotaReplacements=array();
|
|
$results['defaultvalues']=0;
|
|
$results['answers']=0;
|
|
$results['surveys']=0;
|
|
$results['questions']=0;
|
|
$results['subquestions']=0;
|
|
$results['question_attributes']=0;
|
|
$results['groups']=0;
|
|
$results['assessments']=0;
|
|
$results['quota']=0;
|
|
$results['quotals']=0;
|
|
$results['quotamembers']=0;
|
|
$results['survey_url_parameters']=0;
|
|
$results['importwarnings']=array();
|
|
|
|
|
|
$aLanguagesSupported=array();
|
|
foreach ($xml->languages->language as $language)
|
|
{
|
|
$aLanguagesSupported[]=(string)$language;
|
|
}
|
|
$results['languages']=count($aLanguagesSupported);
|
|
|
|
// Import surveys table ====================================================
|
|
|
|
foreach ($xml->surveys->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
|
|
$iOldSID=$results['oldsid']=$insertdata['sid'];
|
|
if($iDesiredSurveyId!=NULL)
|
|
{
|
|
$insertdata['wishSID']=GetNewSurveyID($iDesiredSurveyId);
|
|
}
|
|
else
|
|
{
|
|
$insertdata['wishSID']=$iOldSID;
|
|
}
|
|
|
|
if ($iDBVersion<145)
|
|
{
|
|
if(isset($insertdata['private'])) $insertdata['anonymized']=$insertdata['private'];
|
|
unset($insertdata['private']);
|
|
unset($insertdata['notification']);
|
|
}
|
|
|
|
//Make sure it is not set active
|
|
$insertdata['active']='N';
|
|
//Set current user to be the owner
|
|
$insertdata['owner_id']=Yii::app()->session['loginID'];
|
|
|
|
if (isset($insertdata['bouncetime']) && $insertdata['bouncetime'] == '')
|
|
{
|
|
$insertdata['bouncetime'] = NULL;
|
|
}
|
|
|
|
if (isset($insertdata['showXquestions']))
|
|
{
|
|
$insertdata['showxquestions']=$insertdata['showXquestions'];
|
|
unset($insertdata['showXquestions']);
|
|
}
|
|
if (isset($insertdata['googleAnalyticsStyle']))
|
|
{
|
|
$insertdata['googleanalyticsstyle']=$insertdata['googleAnalyticsStyle'];
|
|
unset($insertdata['googleAnalyticsStyle']);
|
|
}
|
|
if (isset($insertdata['googleAnalyticsAPIKey']))
|
|
{
|
|
$insertdata['googleanalyticsapikey']=$insertdata['googleAnalyticsAPIKey'];
|
|
unset($insertdata['googleAnalyticsAPIKey']);
|
|
}
|
|
if (isset($insertdata['allowjumps']))
|
|
{
|
|
$insertdata['questionindex']= ($insertdata['allowjumps']=="Y")?1:0;
|
|
unset($insertdata['allowjumps']);
|
|
}
|
|
/* Remove unknow column */
|
|
$aSurveyModelsColumns=Survey::model()->attributes;
|
|
$aSurveyModelsColumns['wishSID']=null;// To force a sid surely
|
|
$aBadData=array_diff_key($insertdata, $aSurveyModelsColumns);
|
|
$insertdata=array_intersect_key ($insertdata,$aSurveyModelsColumns);
|
|
// Fill a optionnal array of error
|
|
foreach($aBadData as $key=>$value)
|
|
{
|
|
$results['importwarnings'][]=sprintf($clang->gT("This survey setting has not been imported: %s => %s"),$key,$value);
|
|
}
|
|
|
|
$iNewSID = $results['newsid'] = Survey::model()->insertNewSurvey($insertdata) or safeDie($clang->gT("Error").": Failed to insert data [1]<br />");
|
|
|
|
$results['surveys']++;
|
|
}
|
|
|
|
|
|
// Import survey languagesettings table ===================================================================================
|
|
|
|
|
|
|
|
foreach ($xml->surveys_languagesettings->rows->row as $row)
|
|
{
|
|
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
if (!in_array($insertdata['surveyls_language'],$aLanguagesSupported)) continue;
|
|
// Assign new survey ID
|
|
$insertdata['surveyls_survey_id']=$iNewSID;
|
|
// Assign new survey name (if a copy)
|
|
if ($sNewSurveyName != NULL)
|
|
{
|
|
$insertdata['surveyls_title']=$sNewSurveyName;
|
|
}
|
|
if ($bTranslateInsertansTags)
|
|
{
|
|
$insertdata['surveyls_title']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_title']);
|
|
if (isset($insertdata['surveyls_description'])) $insertdata['surveyls_description']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_description']);
|
|
if (isset($insertdata['surveyls_welcometext'])) $insertdata['surveyls_welcometext']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_welcometext']);
|
|
if (isset($insertdata['surveyls_urldescription']))$insertdata['surveyls_urldescription']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_urldescription']);
|
|
if (isset($insertdata['surveyls_email_invite'])) $insertdata['surveyls_email_invite']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_invite']);
|
|
if (isset($insertdata['surveyls_email_remind'])) $insertdata['surveyls_email_remind']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_remind']);
|
|
if (isset($insertdata['surveyls_email_register'])) $insertdata['surveyls_email_register']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_register']);
|
|
if (isset($insertdata['surveyls_email_confirm'])) $insertdata['surveyls_email_confirm']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_confirm']);
|
|
}
|
|
if (isset($insertdata['surveyls_attributecaptions']) && substr($insertdata['surveyls_attributecaptions'],0,1)!='{')
|
|
{
|
|
unset($insertdata['surveyls_attributecaptions']);
|
|
}
|
|
|
|
|
|
|
|
$result = SurveyLanguageSetting::model()->insertNewSurvey($insertdata) or safeDie($clang->gT("Error").": Failed to insert data [2]<br />");
|
|
}
|
|
|
|
|
|
// Import groups table ===================================================================================
|
|
|
|
|
|
if (isset($xml->groups->rows->row))
|
|
{
|
|
foreach ($xml->groups->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
if (!in_array($insertdata['language'],$aLanguagesSupported)) continue;
|
|
$iOldSID=$insertdata['sid'];
|
|
$insertdata['sid']=$iNewSID;
|
|
$oldgid=$insertdata['gid']; unset($insertdata['gid']); // save the old qid
|
|
|
|
// now translate any links
|
|
if ($bTranslateInsertansTags)
|
|
{
|
|
$insertdata['group_name']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['group_name']);
|
|
$insertdata['description']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['description']);
|
|
}
|
|
// Insert the new group
|
|
if (isset($aGIDReplacements[$oldgid]))
|
|
{
|
|
switchMSSQLIdentityInsert('groups',true);
|
|
$insertdata['gid']=$aGIDReplacements[$oldgid];
|
|
}
|
|
$newgid = QuestionGroup::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data [3]<br />");
|
|
$results['groups']++;
|
|
|
|
if (!isset($aGIDReplacements[$oldgid]))
|
|
{
|
|
$aGIDReplacements[$oldgid]=$newgid; // add old and new qid to the mapping array
|
|
}
|
|
else
|
|
{
|
|
switchMSSQLIdentityInsert('groups',false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Import questions table ===================================================================================
|
|
|
|
// We have to run the question table data two times - first to find all main questions
|
|
// then for subquestions (because we need to determine the new qids for the main questions first)
|
|
if(isset($xml->questions)) // there could be surveys without a any questions
|
|
{
|
|
|
|
foreach ($xml->questions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
if (!in_array($insertdata['language'],$aLanguagesSupported) || $insertdata['gid']==0) continue;
|
|
$iOldSID=$insertdata['sid'];
|
|
$insertdata['sid']=$iNewSID;
|
|
$insertdata['gid']=$aGIDReplacements[$insertdata['gid']];
|
|
$oldqid=$insertdata['qid']; unset($insertdata['qid']); // save the old qid
|
|
|
|
// now translate any links
|
|
if ($bTranslateInsertansTags)
|
|
{
|
|
$insertdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']);
|
|
$insertdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']);
|
|
}
|
|
// Insert the new question
|
|
if (isset($aQIDReplacements[$oldqid]))
|
|
{
|
|
$insertdata['qid']=$aQIDReplacements[$oldqid];
|
|
switchMSSQLIdentityInsert('questions',true);
|
|
|
|
}
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
|
|
if (!$bConvertInvalidQuestionCodes)
|
|
{
|
|
$sScenario='archiveimport';
|
|
}
|
|
else
|
|
{
|
|
$sScenario='import';
|
|
}
|
|
$oQuestion = new Question($sScenario);
|
|
$oQuestion->setAttributes($insertdata, false);
|
|
|
|
// Try to fix question title for valid question code enforcement
|
|
if(!$oQuestion->validate(array('title')))
|
|
{
|
|
$sOldTitle=$oQuestion->title;
|
|
$sNewTitle=preg_replace("/[^A-Za-z0-9]/", '', $sOldTitle);
|
|
if (is_numeric(substr($sNewTitle,0,1)))
|
|
{
|
|
$sNewTitle='q' . $sNewTitle;
|
|
}
|
|
$oQuestion->title =$sNewTitle;
|
|
}
|
|
|
|
$attempts = 0;
|
|
// Try to fix question title for unique question code enforcement
|
|
while (!$oQuestion->validate(array('title')))
|
|
{
|
|
if (!isset($index))
|
|
{
|
|
$index = 0;
|
|
$rand = mt_rand(0, 1024);
|
|
}
|
|
else
|
|
{
|
|
$index++;
|
|
}
|
|
$sNewTitle='r' . $rand . 'q' . $index;
|
|
$oQuestion->title = $sNewTitle;
|
|
$attempts++;
|
|
if ($attempts > 10)
|
|
{
|
|
safeDie($clang->gT("Error").": Failed to resolve question code problems after 10 attempts.<br />");
|
|
}
|
|
}
|
|
if (!$oQuestion->save())
|
|
{
|
|
// safeDie($clang->gT("Error while saving: "). print_r($oQuestion->errors, true));
|
|
//
|
|
// In PHP 5.2.10 a bug is triggered that resets the foreach loop when inserting a record
|
|
// Problem is that it is the default PHP version on Ubuntu 12.04 LTS (which is currently very common in use)
|
|
// For this reason we ignore insertion errors (because it is most likely a duplicate)
|
|
// and continue with the next one
|
|
continue;
|
|
}
|
|
// Set a warning if question title was updated
|
|
if(isset($sNewTitle))
|
|
{
|
|
$results['importwarnings'][] = sprintf($clang->gT("Question code %s was updated to %s."),$sOldTitle,$sNewTitle);
|
|
$aQuestionCodeReplacements[$sOldTitle]=$sNewTitle;
|
|
unset($sNewTitle);
|
|
unset($sOldTitle);
|
|
}
|
|
$newqid = $oQuestion->qid;
|
|
|
|
if (!isset($aQIDReplacements[$oldqid]))
|
|
{
|
|
$aQIDReplacements[$oldqid]=$newqid;
|
|
$results['questions']++;
|
|
}
|
|
else
|
|
{
|
|
switchMSSQLIdentityInsert('questions',false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Import subquestions -------------------------------------------------------
|
|
if(isset($xml->subquestions))
|
|
{
|
|
foreach ($xml->subquestions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
if (!in_array($insertdata['language'],$aLanguagesSupported) || $insertdata['gid']==0) continue;
|
|
if (!isset($insertdata['mandatory']) || trim($insertdata['mandatory'])=='')
|
|
{
|
|
$insertdata['mandatory']='N';
|
|
}
|
|
$insertdata['sid']=$iNewSID;
|
|
$insertdata['gid']=$aGIDReplacements[(int)$insertdata['gid']];;
|
|
$oldsqid=(int)$insertdata['qid']; unset($insertdata['qid']); // save the old qid
|
|
$insertdata['parent_qid']=$aQIDReplacements[(int)$insertdata['parent_qid']]; // remap the parent_qid
|
|
|
|
// now translate any links
|
|
if ($bTranslateInsertansTags)
|
|
{
|
|
$insertdata['question']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']);
|
|
if (isset($insertdata['help'])) $insertdata['help']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']);
|
|
}
|
|
if (isset($aQIDReplacements[$oldsqid])){
|
|
$insertdata['qid']=$aQIDReplacements[$oldsqid];
|
|
switchMSSQLIdentityInsert('questions',true);
|
|
}
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
|
|
|
|
if (!$bConvertInvalidQuestionCodes)
|
|
{
|
|
$sScenario='archiveimport';
|
|
}
|
|
else
|
|
{
|
|
$sScenario='import';
|
|
}
|
|
$question = new Question($sScenario);
|
|
$question->setAttributes($insertdata, false);
|
|
// Try to fix question title for valid question code enforcement
|
|
if(!$question->validate(array('title')))
|
|
{
|
|
$sOldTitle=$question->title;
|
|
$sNewTitle=preg_replace("/[^A-Za-z0-9]/", '', $sOldTitle);
|
|
if (is_numeric(substr($sNewTitle,0,1)))
|
|
{
|
|
$sNewTitle='sq' . $sNewTitle;
|
|
}
|
|
$question->title =$sNewTitle;
|
|
}
|
|
$attempts = 0;
|
|
// Try to fix question title for unique question code enforcement
|
|
while (!$question->validate(array('title')))
|
|
{
|
|
if (!isset($index))
|
|
{
|
|
$index = 0;
|
|
$rand = mt_rand(0, 1024);
|
|
}
|
|
else
|
|
{
|
|
$index++;
|
|
}
|
|
$sNewTitle='r' . $rand . 'sq' . $index;
|
|
$question->title = $sNewTitle;
|
|
$attempts++;
|
|
if ($attempts > 10)
|
|
{
|
|
safeDie($clang->gT("Error").": Failed to resolve question code problems after 10 attempts.<br />");
|
|
}
|
|
}
|
|
if (!$question->save())
|
|
{
|
|
// safeDie($clang->gT("Error while saving: "). print_r($question->errors, true));
|
|
//
|
|
// In PHP 5.2.10 a bug is triggered that resets the foreach loop when inserting a record
|
|
// Problem is that it is the default PHP version on Ubuntu 12.04 LTS (which is currently very common in use)
|
|
// For this reason we ignore insertion errors (because it is most likely a duplicate)
|
|
// and continue with the next one
|
|
continue;
|
|
}
|
|
// Set a warning if question title was updated
|
|
if(isset($sNewTitle))
|
|
{
|
|
$results['importwarnings'][] = sprintf($clang->gT("Title of subquestion %s was updated to %s."),$sOldTitle,$sNewTitle);// Maybe add the question title ?
|
|
$aQuestionCodeReplacements[$sOldTitle]=$sNewTitle;
|
|
unset($sNewTitle);
|
|
unset($sOldTitle);
|
|
}
|
|
$newsqid = $question->qid;
|
|
if (!isset($insertdata['qid']))
|
|
{
|
|
$aQIDReplacements[$oldsqid]=$newsqid; // add old and new qid to the mapping array
|
|
}
|
|
else
|
|
{
|
|
switchMSSQLIdentityInsert('questions',false);
|
|
}
|
|
$results['subquestions']++;
|
|
}
|
|
}
|
|
|
|
// Import answers ------------------------------------------------------------
|
|
if(isset($xml->answers))
|
|
{
|
|
|
|
foreach ($xml->answers->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
if (!in_array($insertdata['language'],$aLanguagesSupported) || !isset($aQIDReplacements[(int)$insertdata['qid']])) continue;
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the parent_qid
|
|
|
|
// now translate any links
|
|
if ($bTranslateInsertansTags)
|
|
{
|
|
$insertdata['answer']=translateLinks('survey', $iOldSID, $iNewSID, $insertdata['answer']);
|
|
}
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
|
|
if (Answer::model()->insertRecords($insertdata))
|
|
{
|
|
$results['answers']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Import questionattributes -------------------------------------------------
|
|
if(isset($xml->question_attributes))
|
|
{
|
|
$aAllAttributes=questionAttributes(true);
|
|
foreach ($xml->question_attributes->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
|
|
// take care of renaming of date min/max adv. attributes fields
|
|
if ($iDBVersion < 170)
|
|
{
|
|
if (isset($insertdata['attribute']))
|
|
{
|
|
if ($insertdata['attribute']=='dropdown_dates_year_max')
|
|
{
|
|
$insertdata['attribute']='date_max';
|
|
}
|
|
if ($insertdata['attribute']=='dropdown_dates_year_min')
|
|
{
|
|
$insertdata['attribute']='date_min';
|
|
}
|
|
}
|
|
}
|
|
unset($insertdata['qaid']);
|
|
if (!isset($aQIDReplacements[(int)$insertdata['qid']])) continue;
|
|
$insertdata['qid']=$aQIDReplacements[(integer)$insertdata['qid']]; // remap the qid
|
|
if ($iDBVersion<156 && isset($aAllAttributes[$insertdata['attribute']]['i18n']) && $aAllAttributes[$insertdata['attribute']]['i18n'])
|
|
{
|
|
foreach ($aLanguagesSupported as $sLanguage)
|
|
{
|
|
$insertdata['language']=$sLanguage;
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
$result=QuestionAttribute::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[7]<br />");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$result=QuestionAttribute::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[8]<br />");
|
|
}
|
|
$results['question_attributes']++;
|
|
}
|
|
}
|
|
|
|
// Import defaultvalues ------------------------------------------------------
|
|
if(isset($xml->defaultvalues))
|
|
{
|
|
|
|
|
|
$results['defaultvalues']=0;
|
|
foreach ($xml->defaultvalues->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the qid
|
|
if (isset($aQIDReplacements[(int)$insertdata['sqid']])) $insertdata['sqid']=$aQIDReplacements[(int)$insertdata['sqid']]; // remap the subquestion id
|
|
if ($insertdata)
|
|
XSSFilterArray($insertdata);
|
|
// now translate any links
|
|
$result=DefaultValue::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[9]<br />");
|
|
$results['defaultvalues']++;
|
|
}
|
|
}
|
|
$aOldNewFieldmap=reverseTranslateFieldNames($iOldSID,$iNewSID,$aGIDReplacements,$aQIDReplacements);
|
|
|
|
// Import conditions ---------------------------------------------------------
|
|
if(isset($xml->conditions))
|
|
{
|
|
|
|
|
|
$results['conditions']=0;
|
|
foreach ($xml->conditions->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
// replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this condition is orphan -> error, skip this record)
|
|
if (isset($aQIDReplacements[$insertdata['qid']]))
|
|
{
|
|
$insertdata['qid']=$aQIDReplacements[$insertdata['qid']]; // remap the qid
|
|
}
|
|
else continue; // a problem with this answer record -> don't consider
|
|
if ($insertdata['cqid'] != 0)
|
|
{
|
|
if (isset($aQIDReplacements[$insertdata['cqid']]))
|
|
{
|
|
$oldcqid = $insertdata['cqid']; //Save for cfield transformation
|
|
$insertdata['cqid']=$aQIDReplacements[$insertdata['cqid']]; // remap the qid
|
|
}
|
|
else continue; // a problem with this answer record -> don't consider
|
|
|
|
list($oldcsid, $oldcgid, $oldqidanscode) = explode("X",$insertdata["cfieldname"],3);
|
|
|
|
// replace the gid for the new one in the cfieldname(if there is no new gid in the $aGIDReplacements array it means that this condition is orphan -> error, skip this record)
|
|
if (!isset($aGIDReplacements[$oldcgid]))
|
|
continue;
|
|
}
|
|
|
|
unset($insertdata["cid"]);
|
|
|
|
// recreate the cfieldname with the new IDs
|
|
if ($insertdata['cqid'] != 0)
|
|
{
|
|
if (preg_match("/^\+/",$oldcsid))
|
|
{
|
|
$newcfieldname = '+'.$iNewSID . "X" . $aGIDReplacements[$oldcgid] . "X" . $insertdata["cqid"] .substr($oldqidanscode,strlen($oldcqid));
|
|
}
|
|
else
|
|
{
|
|
$newcfieldname = $iNewSID . "X" . $aGIDReplacements[$oldcgid] . "X" . $insertdata["cqid"] .substr($oldqidanscode,strlen($oldcqid));
|
|
}
|
|
}
|
|
else
|
|
{ // The cfieldname is a not a previous question cfield but a {XXXX} replacement field
|
|
$newcfieldname = $insertdata["cfieldname"];
|
|
}
|
|
$insertdata["cfieldname"] = $newcfieldname;
|
|
if (trim($insertdata["method"])=='')
|
|
{
|
|
$insertdata["method"]='==';
|
|
}
|
|
|
|
// Now process the value and replace @sgqa@ codes
|
|
if (preg_match("/^@(.*)@$/",$insertdata["value"],$cfieldnameInCondValue))
|
|
{
|
|
if (isset($aOldNewFieldmap[$cfieldnameInCondValue[1]]))
|
|
{
|
|
$newvalue = '@'.$aOldNewFieldmap[$cfieldnameInCondValue[1]].'@';
|
|
$insertdata["value"] = $newvalue;
|
|
}
|
|
|
|
}
|
|
|
|
// now translate any links
|
|
$result=Condition::model()->insertRecords($insertdata) or safeDie ($clang->gT("Error").": Failed to insert data[10]<br />");
|
|
$results['conditions']++;
|
|
}
|
|
}
|
|
// TMSW Condition->Relevance: Call LEM->ConvertConditionsToRelevance
|
|
|
|
// Import assessments --------------------------------------------------------
|
|
if(isset($xml->assessments))
|
|
{
|
|
|
|
|
|
foreach ($xml->assessments->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
if ($insertdata['gid']>0)
|
|
{
|
|
$insertdata['gid']=$aGIDReplacements[(int)$insertdata['gid']]; // remap the qid
|
|
}
|
|
|
|
$insertdata['sid']=$iNewSID; // remap the survey id
|
|
unset($insertdata['id']);
|
|
// now translate any links
|
|
$result=Assessment::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[11]<br />");
|
|
$results['assessments']++;
|
|
}
|
|
}
|
|
|
|
// Import quota --------------------------------------------------------------
|
|
if(isset($xml->quota))
|
|
{
|
|
|
|
|
|
foreach ($xml->quota->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['sid']=$iNewSID; // remap the survey id
|
|
$oldid=$insertdata['id'];
|
|
unset($insertdata['id']);
|
|
// now translate any links
|
|
$result=Quota::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[12]<br />");
|
|
$aQuotaReplacements[$oldid] = getLastInsertID('{{quota}}');
|
|
$results['quota']++;
|
|
}
|
|
}
|
|
|
|
// Import quota_members ------------------------------------------------------
|
|
if(isset($xml->quota_members))
|
|
{
|
|
|
|
foreach ($xml->quota_members->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['sid']=$iNewSID; // remap the survey id
|
|
$insertdata['qid']=$aQIDReplacements[(int)$insertdata['qid']]; // remap the qid
|
|
$insertdata['quota_id']=$aQuotaReplacements[(int)$insertdata['quota_id']]; // remap the qid
|
|
unset($insertdata['id']);
|
|
// now translate any links
|
|
$result=QuotaMember::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[13]<br />");
|
|
$results['quotamembers']++;
|
|
}
|
|
}
|
|
|
|
// Import quota_languagesettings----------------------------------------------
|
|
if(isset($xml->quota_languagesettings))
|
|
{
|
|
|
|
foreach ($xml->quota_languagesettings->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['quotals_quota_id']=$aQuotaReplacements[(int)$insertdata['quotals_quota_id']]; // remap the qid
|
|
unset($insertdata['quotals_id']);
|
|
$result=QuotaLanguageSetting::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data<br />");
|
|
$results['quotals']++;
|
|
}
|
|
}
|
|
|
|
// Import survey_url_parameters ----------------------------------------------
|
|
if(isset($xml->survey_url_parameters))
|
|
{
|
|
|
|
foreach ($xml->survey_url_parameters->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
$insertdata['sid']=$iNewSID; // remap the survey id
|
|
if (isset($insertdata['targetsqid']) && $insertdata['targetsqid']!='')
|
|
{
|
|
$insertdata['targetsqid'] =$aQIDReplacements[(int)$insertdata['targetsqid']]; // remap the qid
|
|
}
|
|
if (isset($insertdata['targetqid']) && $insertdata['targetqid']!='')
|
|
{
|
|
$insertdata['targetqid'] =$aQIDReplacements[(int)$insertdata['targetqid']]; // remap the qid
|
|
}
|
|
unset($insertdata['id']);
|
|
$result=SurveyURLParameter::model()->insertRecord($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[14]<br />");
|
|
$results['survey_url_parameters']++;
|
|
}
|
|
}
|
|
|
|
// Set survey permissions
|
|
Permission::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'],$iNewSID);
|
|
$aOldNewFieldmap=reverseTranslateFieldNames($iOldSID,$iNewSID,$aGIDReplacements,$aQIDReplacements);
|
|
$results['FieldReMap']=$aOldNewFieldmap;
|
|
LimeExpressionManager::SetSurveyId($iNewSID);
|
|
translateInsertansTags($iNewSID,$iOldSID,$aOldNewFieldmap);
|
|
replaceExpressionCodes($iNewSID,$aQuestionCodeReplacements);
|
|
if (count($aQuestionCodeReplacements)) {
|
|
array_unshift($results['importwarnings'] , "<span class='warningtitle'>".$clang->gT('Attention: Several question codes were updated. Please check these carefully as the update may not be perfect with customized expressions.').'</span)>');
|
|
}
|
|
LimeExpressionManager::RevertUpgradeConditionsToRelevance($iNewSID);
|
|
LimeExpressionManager::UpgradeConditionsToRelevance($iNewSID);
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* This function returns a new random sid if the existing one is taken,
|
|
* otherwise it returns the old one.
|
|
*
|
|
* @param mixed $iOldSID
|
|
*/
|
|
function GetNewSurveyID($iOldSID)
|
|
{
|
|
Yii::app()->loadHelper('database');
|
|
$query = "SELECT sid FROM {{surveys}} WHERE sid=$iOldSID";
|
|
|
|
$aRow = Yii::app()->db->createCommand($query)->queryRow();
|
|
|
|
//if (!is_null($isresult))
|
|
if($aRow!==false)
|
|
{
|
|
// Get new random ids until one is found that is not used
|
|
do
|
|
{
|
|
$iNewSID = randomChars(5,'123456789');
|
|
$query = "SELECT sid FROM {{surveys}} WHERE sid=$iNewSID";
|
|
$aRow = Yii::app()->db->createCommand($query)->queryRow();
|
|
}
|
|
while ($aRow!==false);
|
|
|
|
return $iNewSID;
|
|
}
|
|
else
|
|
{
|
|
return $iOldSID;
|
|
}
|
|
}
|
|
|
|
|
|
function XMLImportTokens($sFullFilePath,$iSurveyID,$sCreateMissingAttributeFields=true)
|
|
{
|
|
Yii::app()->loadHelper('database');
|
|
$clang = Yii::app()->lang;
|
|
$sXMLdata = file_get_contents($sFullFilePath);
|
|
$xml = simplexml_load_string($sXMLdata,'SimpleXMLElement',LIBXML_NONET);
|
|
$results['warnings']=array();
|
|
if ($xml->LimeSurveyDocType!='Tokens')
|
|
{
|
|
$results['error'] = $clang->gT("This is not a valid token data XML file.");
|
|
return $results;
|
|
}
|
|
|
|
if (!isset($xml->tokens->fields))
|
|
{
|
|
$results['tokens']=0;
|
|
return $results;
|
|
}
|
|
|
|
$results['tokens']=0;
|
|
$results['tokenfieldscreated']=0;
|
|
|
|
if ($sCreateMissingAttributeFields)
|
|
{
|
|
// Get a list with all fieldnames in the XML
|
|
$aXLMFieldNames=array();
|
|
foreach ($xml->tokens->fields->fieldname as $sFieldName )
|
|
{
|
|
$aXLMFieldNames[]=(string)$sFieldName;
|
|
}
|
|
// Get a list of all fieldnames in the token table
|
|
$aTokenFieldNames=Yii::app()->db->getSchema()->getTable("{{tokens_$iSurveyID}}",true);
|
|
$aTokenFieldNames=array_keys($aTokenFieldNames->columns);
|
|
$aFieldsToCreate=array_diff($aXLMFieldNames, $aTokenFieldNames);
|
|
Yii::app()->loadHelper('update/updatedb');
|
|
|
|
foreach ($aFieldsToCreate as $sField)
|
|
{
|
|
if (strpos($sField,'attribute')!==false)
|
|
{
|
|
addColumn('{{tokens_'.$iSurveyID.'}}',$sField, 'string');
|
|
}
|
|
}
|
|
}
|
|
|
|
switchMSSQLIdentityInsert('tokens_'.$iSurveyID,true);
|
|
foreach ($xml->tokens->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
$insertdata[(string)$key]=(string)$value;
|
|
}
|
|
|
|
$token = Token::create($iSurveyID);
|
|
$token->setAttributes($insertdata, false);
|
|
if (!$token->save())
|
|
{
|
|
$results['warnings'][]=$clang->gT("Skipped tokens entry:").' '. implode('. ',$token->errors['token']);
|
|
};
|
|
$results['tokens']++;
|
|
}
|
|
switchMSSQLIdentityInsert('tokens_'.$iSurveyID,false);
|
|
if (Yii::app()->db->getDriverName() == 'pgsql')
|
|
{
|
|
try {Yii::app()->db->createCommand("SELECT pg_catalog.setval(pg_get_serial_sequence('{{tokens_".$iSurveyID."}}', 'tid'), (SELECT MAX(tid) FROM {{tokens_".$iSurveyID."}}))")->execute();} catch(Exception $oException){};
|
|
}
|
|
return $results;
|
|
}
|
|
|
|
|
|
function XMLImportResponses($sFullFilePath,$iSurveyID,$aFieldReMap=array())
|
|
{
|
|
Yii::app()->loadHelper('database');
|
|
$clang = Yii::app()->lang;
|
|
|
|
switchMSSQLIdentityInsert('survey_'.$iSurveyID, true);
|
|
$results['responses']=0;
|
|
$oXMLReader = new XMLReader();
|
|
$oXMLReader->open($sFullFilePath);
|
|
$DestinationFields = Yii::app()->db->schema->getTable('{{survey_'.$iSurveyID.'}}')->getColumnNames();
|
|
while ($oXMLReader->read()) {
|
|
if ($oXMLReader->name === 'LimeSurveyDocType' && $oXMLReader->nodeType == XMLReader::ELEMENT)
|
|
{
|
|
$oXMLReader->read();
|
|
if ($oXMLReader->value!='Responses')
|
|
{
|
|
$results['error'] = $clang->gT("This is not a valid response data XML file.");
|
|
return $results;
|
|
}
|
|
}
|
|
if ($oXMLReader->name === 'rows' && $oXMLReader->nodeType == XMLReader::ELEMENT)
|
|
{
|
|
while ($oXMLReader->read()) {
|
|
if ($oXMLReader->name === 'row' && $oXMLReader->nodeType == XMLReader::ELEMENT)
|
|
{
|
|
$aInsertData=array();
|
|
while ($oXMLReader->read() && $oXMLReader->name != 'row') {
|
|
$sFieldname=$oXMLReader->name;
|
|
if ($sFieldname[0]=='_') $sFieldname=substr($sFieldname,1);
|
|
$sFieldname=str_replace('-','#',$sFieldname);
|
|
if (isset($aFieldReMap[$sFieldname]))
|
|
{
|
|
$sFieldname=$aFieldReMap[$sFieldname];
|
|
}
|
|
if (!$oXMLReader->isEmptyElement)
|
|
{
|
|
$oXMLReader->read();
|
|
if(in_array($sFieldname,$DestinationFields)) // some old response tables contain invalid column names due to old bugs
|
|
$aInsertData[$sFieldname]=$oXMLReader->value;
|
|
$oXMLReader->read();
|
|
}else
|
|
{
|
|
if(in_array($sFieldname,$DestinationFields))
|
|
$aInsertData[$sFieldname]='';
|
|
}
|
|
}
|
|
|
|
$result = SurveyDynamic::model($iSurveyID)->insertRecords($aInsertData) or safeDie($clang->gT("Error").": Failed to insert data[16]<br />");
|
|
$results['responses']++;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
switchMSSQLIdentityInsert('survey_'.$iSurveyID,false);
|
|
if (Yii::app()->db->getDriverName() == 'pgsql')
|
|
{
|
|
try {Yii::app()->db->createCommand("SELECT pg_catalog.setval(pg_get_serial_sequence('{{survey_".$iSurveyID."}}', 'id'), (SELECT MAX(id) FROM {{survey_".$iSurveyID."}}))")->execute();} catch(Exception $oException){};
|
|
}
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* This function import CSV file to responses table
|
|
*
|
|
* @param string $sFullFilePath
|
|
* @param integer $iSurveyId
|
|
* @param array $aOptions
|
|
* Return array $result ("errors","warnings","success")
|
|
*/
|
|
function CSVImportResponses($sFullFilePath,$iSurveyId,$aOptions=array())
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
// Default optional
|
|
if(!isset($aOptions['bDeleteFistLine'])){$aOptions['bDeleteFistLine']=true;} // By default delete first line (vvimport)
|
|
if(!isset($aOptions['sExistingId'])){$aOptions['sExistingId']="ignore";} // By default exclude existing id
|
|
if(!isset($aOptions['bNotFinalized'])){$aOptions['bNotFinalized']=false;} // By default don't change finalized part
|
|
if(!isset($aOptions['sCharset']) || !$aOptions['sCharset']){$aOptions['sCharset']="utf8";}
|
|
if(!isset($aOptions['sSeparator'])){$aOptions['sSeparator']="\t";}
|
|
if(!isset($aOptions['sQuoted'])){$aOptions['sQuoted']="\"";}
|
|
// Fix some part
|
|
if (!array_key_exists($aOptions['sCharset'], aEncodingsArray())) {
|
|
$aOptions['sCharset']="utf8";
|
|
}
|
|
|
|
// Prepare an array of sentence for result
|
|
$CSVImportResult=array();
|
|
// Read the file
|
|
$handle = fopen($sFullFilePath, "r"); // Need to be adapted for Mac ? in options ?
|
|
while (!feof($handle))
|
|
{
|
|
$buffer = fgets($handle); //To allow for very long lines . Another option is fgetcsv (0 to length), but need mb_convert_encoding
|
|
$aFileResponses[] = mb_convert_encoding($buffer, "UTF-8", $aOptions['sCharset']);
|
|
}
|
|
// Close the file
|
|
fclose($handle);
|
|
if($aOptions['bDeleteFistLine']){
|
|
array_shift($aFileResponses);
|
|
}
|
|
|
|
$aRealFieldNames = Yii::app()->db->getSchema()->getTable(SurveyDynamic::model($iSurveyId)->tableName())->getColumnNames();
|
|
//$aCsvHeader=array_map("trim",explode($aOptions['sSeparator'], trim(array_shift($aFileResponses))));
|
|
$aCsvHeader=str_getcsv(array_shift($aFileResponses),$aOptions['sSeparator'],$aOptions['sQuoted']);
|
|
$aLemFieldNames=LimeExpressionManager::getLEMqcode2sgqa($iSurveyId);
|
|
$aKeyForFieldNames=array();// An array assicated each fieldname with corresponding responses key
|
|
if(!$aCsvHeader){
|
|
$CSVImportResult['errors'][]=$clang->gT("File seems empty or has only one line");
|
|
return $CSVImportResult;
|
|
}
|
|
// Assign fieldname with $aFileResponses[] key
|
|
foreach($aRealFieldNames as $sFieldName){
|
|
if(in_array($sFieldName,$aCsvHeader)){ // First pass : simple associated
|
|
$aKeyForFieldNames[$sFieldName]=array_search($sFieldName,$aCsvHeader);
|
|
}elseif(in_array($sFieldName,$aLemFieldNames)){ // Second pass : LEM associated
|
|
$sLemFieldName=array_search($sFieldName,$aLemFieldNames);
|
|
if(in_array($sLemFieldName,$aCsvHeader)){
|
|
$aKeyForFieldNames[$sFieldName]=array_search($sLemFieldName,$aCsvHeader);
|
|
}elseif($aOptions['bForceImport']){
|
|
// as fallback just map questions in order of apperance
|
|
|
|
// find out where the answer data columns start in CSV
|
|
if( ! isset($csv_ans_start_index)){
|
|
foreach($aCsvHeader as $i=>$name){
|
|
if(preg_match('/^\d+X\d+X\d+/', $name)){
|
|
$csv_ans_start_index = $i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// find out where the answer data columns start in destination table
|
|
if( ! isset($table_ans_start_index)){
|
|
foreach($aRealFieldNames as $i=>$name){
|
|
if(preg_match('/^\d+X\d+X\d+/', $name)){
|
|
$table_ans_start_index = $i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// map answers in order
|
|
if(isset($table_ans_start_index,$csv_ans_start_index)){
|
|
$csv_index = (array_search($sFieldName,$aRealFieldNames)-$table_ans_start_index) + $csv_ans_start_index;
|
|
if($csv_index < sizeof($aCsvHeader)){
|
|
$aKeyForFieldNames[$sFieldName] = $csv_index;
|
|
}else{
|
|
$force_import_failed = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// check if forced error failed
|
|
if(isset($force_import_failed)){
|
|
$CSVImportResult['errors'][]=$clang->gT("Import failed: Forced import was requested but the input file doesn't contain enough columns to fill the survey.");
|
|
return $CSVImportResult;
|
|
}
|
|
|
|
// make sure at least one answer was imported before commiting
|
|
foreach($aKeyForFieldNames as $field=>$index){
|
|
if(preg_match('/^\d+X\d+X\d+/', $field)){
|
|
$import_ok = true;
|
|
break;
|
|
}
|
|
}
|
|
if( ! isset($import_ok)){
|
|
$CSVImportResult['errors'][]=$clang->gT("Import failed: No answers could be mapped.");
|
|
return $CSVImportResult;
|
|
}
|
|
|
|
// Now it's time to import
|
|
// Some var to return
|
|
$iNbResponseLine=0;
|
|
$iNbResponseExisting=0;
|
|
$aResponsesInserted=array();
|
|
$aResponsesUpdated=array();
|
|
$aResponsesError=array();
|
|
$aExistingsId=array();
|
|
|
|
$iMaxId=0; // If we set the id, keep the max
|
|
// Some specific header (with options)
|
|
$iIdKey=array_search('id', $aCsvHeader); // the id is allways needed and used a lot
|
|
if(is_int($iIdKey)){unset($aKeyForFieldNames['id']);}
|
|
$iSubmitdateKey=array_search('submitdate', $aCsvHeader); // submitdate can be forced to null
|
|
if(is_int($iSubmitdateKey)){unset($aKeyForFieldNames['submitdate']);}
|
|
$iIdReponsesKey=(is_int($iIdKey))?$iIdKey:0;// The key for reponses id: id column or first column if not exist
|
|
|
|
// Import each responses line here
|
|
while($sResponses=array_shift($aFileResponses)){
|
|
$iNbResponseLine++;
|
|
$bExistingsId=false;
|
|
$aResponses=str_getcsv($sResponses,$aOptions['sSeparator'],$aOptions['sQuoted']);
|
|
if($iIdKey!==false){
|
|
$oSurvey = SurveyDynamic::model($iSurveyId)->findByPk($aResponses[$iIdKey]);
|
|
if($oSurvey)
|
|
{
|
|
$bExistingsId=true;
|
|
$aExistingsId[]=$aResponses[$iIdKey];
|
|
// Do according to option
|
|
switch ($aOptions['sExistingId'])
|
|
{
|
|
case 'replace':
|
|
SurveyDynamic::model($iSurveyId)->deleteByPk($aResponses[$iIdKey]);
|
|
SurveyDynamic::sid($iSurveyId);
|
|
$oSurvey = new SurveyDynamic;
|
|
break;
|
|
case 'replaceanswers':
|
|
break;
|
|
case 'renumber':
|
|
SurveyDynamic::sid($iSurveyId);
|
|
$oSurvey = new SurveyDynamic;
|
|
break;
|
|
case 'skip':
|
|
case 'ignore':
|
|
default:
|
|
$oSurvey=false; // Remove existing survey : don't import again
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SurveyDynamic::sid($iSurveyId);
|
|
$oSurvey = new SurveyDynamic;
|
|
}
|
|
}else{
|
|
SurveyDynamic::sid($iSurveyId);
|
|
$oSurvey = new SurveyDynamic;
|
|
}
|
|
if($oSurvey){
|
|
// First rule for id and submitdate
|
|
if(is_int($iIdKey)) // Rule for id: only if id exists in vvimport file
|
|
{
|
|
if(!$bExistingsId) // If not exist : allways import it
|
|
{
|
|
$oSurvey->id=$aResponses[$iIdKey];
|
|
$iMaxId=($aResponses[$iIdKey]>$iMaxId)?$aResponses[$iIdKey]:$iMaxId;
|
|
}
|
|
elseif($aOptions['sExistingId']=='replace' || $aOptions['sExistingId']=='replaceanswers')// Set it depending with some options
|
|
{
|
|
$oSurvey->id=$aResponses[$iIdKey];
|
|
}
|
|
}
|
|
if($aOptions['bNotFinalized'])
|
|
{
|
|
$oSurvey->submitdate=new CDbExpression('NULL');
|
|
}
|
|
elseif(is_int($iSubmitdateKey))
|
|
{
|
|
if( $aResponses[$iSubmitdateKey]=='{question_not_shown}' || trim($aResponses[$iSubmitdateKey]=='')){
|
|
$oSurvey->submitdate = new CDbExpression('NULL');
|
|
}else{
|
|
// Maybe control valid date : see http://php.net/manual/en/function.checkdate.php#78362 for example
|
|
$oSurvey->submitdate=$aResponses[$iSubmitdateKey];
|
|
}
|
|
}
|
|
foreach($aKeyForFieldNames as $sFieldName=>$iFieldKey)
|
|
{
|
|
if( $aResponses[$iFieldKey]=='{question_not_shown}'){
|
|
$oSurvey->$sFieldName = new CDbExpression('NULL');
|
|
}else{
|
|
$sResponse=str_replace(array("{quote}","{tab}","{cr}","{newline}","{lbrace}"),array("\"","\t","\r","\n","{"),$aResponses[$iFieldKey]);
|
|
$oSurvey->$sFieldName = $sResponse;
|
|
}
|
|
}
|
|
// We use transaction to prevent DB error
|
|
$oTransaction = Yii::app()->db->beginTransaction();
|
|
try
|
|
{
|
|
if (isset($oSurvey->id) && !is_null($oSurvey->id))
|
|
{
|
|
switchMSSQLIdentityInsert('survey_'.$iSurveyId, true);
|
|
$bSwitched=true;
|
|
}
|
|
if($oSurvey->save())
|
|
{
|
|
$oTransaction->commit();
|
|
if($bExistingsId && $aOptions['sExistingId']!='renumber')
|
|
{
|
|
$aResponsesUpdated[]=$aResponses[$iIdReponsesKey];
|
|
}
|
|
else
|
|
{
|
|
$aResponsesInserted[]=$aResponses[$iIdReponsesKey];
|
|
}
|
|
}
|
|
else // Actually can not be, leave it if we have a $oSurvey->validate() in future release
|
|
{
|
|
$oTransaction->rollBack();
|
|
$aResponsesError[]=$aResponses[$iIdReponsesKey];
|
|
}
|
|
if (isset($bSwitched) && $bSwitched==true){
|
|
switchMSSQLIdentityInsert('survey_'.$iSurveyId, false);
|
|
$bSwitched=false;
|
|
}
|
|
}
|
|
catch(Exception $oException)
|
|
{
|
|
$oTransaction->rollBack();
|
|
$aResponsesError[]=$aResponses[$iIdReponsesKey];
|
|
// Show some error to user ?
|
|
// $CSVImportResult['errors'][]=$oException->getMessage(); // Show it in view
|
|
// tracevar($oException->getMessage());// Show it in console (if debug is set)
|
|
}
|
|
|
|
}
|
|
}
|
|
// Fix max next id (for pgsql)
|
|
// mysql dot need fix, but what for mssql ?
|
|
// Do a model function for this can be a good idea (see activate_helper/activateSurvey)
|
|
if (Yii::app()->db->driverName=='pgsql')
|
|
{
|
|
$sSequenceName= Yii::app()->db->getSchema()->getTable("{{survey_{$iSurveyId}}}")->sequenceName;
|
|
$iActualSerial=Yii::app()->db->createCommand("SELECT last_value FROM {$sSequenceName}")->queryScalar();
|
|
if($iActualSerial<$iMaxId)
|
|
{
|
|
$sQuery = "SELECT setval(pg_get_serial_sequence('{{survey_{$iSurveyId}}}', 'id'),{$iMaxId},false);";
|
|
$result = @Yii::app()->db->createCommand($sQuery)->execute();
|
|
}
|
|
}
|
|
|
|
// End of import
|
|
// Construction of returned information
|
|
if($iNbResponseLine){
|
|
$CSVImportResult['success'][]=sprintf($clang->gT("%s response lines in your file."),$iNbResponseLine);
|
|
}else{
|
|
$CSVImportResult['errors'][]=$clang->gT("No response lines in your file.");
|
|
}
|
|
if(count($aResponsesInserted)){
|
|
$CSVImportResult['success'][]=sprintf($clang->gT("%s responses were inserted."),count($aResponsesInserted));
|
|
// Maybe add implode aResponsesInserted array
|
|
}
|
|
if(count($aResponsesUpdated)){
|
|
$CSVImportResult['success'][]=sprintf($clang->gT("%s responses were updated."),count($aResponsesUpdated));
|
|
}
|
|
if(count($aResponsesError)){
|
|
$CSVImportResult['errors'][]=sprintf($clang->gT("%s responses cannot be inserted or updated."),count($aResponsesError));
|
|
}
|
|
if(count($aExistingsId) && ($aOptions['sExistingId']=='skip' || $aOptions['sExistingId']=='ignore'))
|
|
{
|
|
$CSVImportResult['warnings'][]=sprintf($clang->gT("%s responses already exist."),count($aExistingsId));
|
|
}
|
|
return $CSVImportResult;
|
|
}
|
|
|
|
|
|
function XMLImportTimings($sFullFilePath,$iSurveyID,$aFieldReMap=array())
|
|
{
|
|
|
|
Yii::app()->loadHelper('database');
|
|
$clang = Yii::app()->lang;
|
|
$sXMLdata = file_get_contents($sFullFilePath);
|
|
$xml = simplexml_load_string($sXMLdata,'SimpleXMLElement',LIBXML_NONET);
|
|
if ($xml->LimeSurveyDocType!='Timings')
|
|
{
|
|
$results['error'] = $clang->gT("This is not a valid timings data XML file.");
|
|
return $results;
|
|
}
|
|
|
|
$results['responses']=0;
|
|
|
|
$aLanguagesSupported=array();
|
|
foreach ($xml->languages->language as $language)
|
|
{
|
|
$aLanguagesSupported[]=(string)$language;
|
|
}
|
|
$results['languages']=count($aLanguagesSupported);
|
|
// Return if there are no timing records to import
|
|
if (!isset($xml->timings->rows))
|
|
{
|
|
return $results;
|
|
}
|
|
switchMSSQLIdentityInsert('survey_'.$iSurveyID.'_timings',true);
|
|
foreach ($xml->timings->rows->row as $row)
|
|
{
|
|
$insertdata=array();
|
|
|
|
foreach ($row as $key=>$value)
|
|
{
|
|
if ($key[0]=='_') $key=substr($key,1);
|
|
if (isset($aFieldReMap[substr($key,0,-4)]))
|
|
{
|
|
$key=$aFieldReMap[substr($key,0,-4)].'time';
|
|
}
|
|
$insertdata[$key]=(string)$value;
|
|
}
|
|
|
|
$result = SurveyTimingDynamic::model($iSurveyID)->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[17]<br />");
|
|
|
|
$results['responses']++;
|
|
}
|
|
switchMSSQLIdentityInsert('survey_'.$iSurveyID.'_timings',false);
|
|
|
|
return $results;
|
|
}
|
|
|
|
function XSSFilterArray(&$array)
|
|
{
|
|
if(Yii::app()->getConfig('filterxsshtml') && !Permission::model()->hasGlobalPermission('superadmin','read'))
|
|
{
|
|
$filter = new CHtmlPurifier();
|
|
$filter->options = array('URI.AllowedSchemes'=>array(
|
|
'http' => true,
|
|
'https' => true,
|
|
));
|
|
foreach($array as &$value)
|
|
{
|
|
$value = $filter->purify($value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Import survey from an TSV file template that does not require or allow assigning of GID or QID values.
|
|
* NOTE: This currently only supports import of one language
|
|
* @global type $connect
|
|
* @global type $dbprefix
|
|
* @global type $clang
|
|
* @global type $timeadjust
|
|
* @param type $sFullFilePath
|
|
* @return type
|
|
*
|
|
* @author TMSWhite
|
|
*/
|
|
function TSVImportSurvey($sFullFilePath)
|
|
{
|
|
$clang = Yii::app()->lang;
|
|
|
|
$insertdata=array();
|
|
$results=array();
|
|
$results['error']=false;
|
|
$baselang = 'en'; // TODO set proper default
|
|
|
|
$encoding='';
|
|
$handle = fopen($sFullFilePath, 'r');
|
|
$bom = fread($handle, 2);
|
|
rewind($handle);
|
|
$aAttributeList = questionAttributes();
|
|
|
|
// Excel tends to save CSV as UTF-16, which PHP does not properly detect
|
|
if($bom === chr(0xff).chr(0xfe) || $bom === chr(0xfe).chr(0xff)){
|
|
// UTF16 Byte Order Mark present
|
|
$encoding = 'UTF-16';
|
|
} else {
|
|
$file_sample = fread($handle, 1000) + 'e'; //read first 1000 bytes
|
|
// + e is a workaround for mb_string bug
|
|
rewind($handle);
|
|
|
|
$encoding = mb_detect_encoding($file_sample , 'UTF-8, UTF-7, ASCII, EUC-JP,SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP');
|
|
}
|
|
if ($encoding && $encoding != 'UTF-8'){
|
|
stream_filter_append($handle, 'convert.iconv.'.$encoding.'/UTF-8');
|
|
}
|
|
|
|
$file = stream_get_contents($handle);
|
|
fclose($handle);
|
|
|
|
// fix Excel non-breaking space
|
|
$file = str_replace("0xC20xA0",' ',$file);
|
|
$filelines = explode("\n",$file);
|
|
$row = array_shift($filelines);
|
|
$headers = explode("\t",$row);
|
|
$rowheaders = array();
|
|
foreach ($headers as $header)
|
|
{
|
|
$rowheaders[] = trim($header);
|
|
}
|
|
// remove BOM from the first header cell, if needed
|
|
$rowheaders[0] = preg_replace("/^\W+/","",$rowheaders[0]);
|
|
if (preg_match('/class$/',$rowheaders[0]))
|
|
{
|
|
$rowheaders[0] = 'class'; // second attempt to remove BOM
|
|
}
|
|
|
|
$adata = array();
|
|
foreach ($filelines as $rowline)
|
|
{
|
|
$rowarray = array();
|
|
$row = explode("\t",$rowline);
|
|
for ($i = 0; $i < count($rowheaders); ++$i)
|
|
{
|
|
$val = (isset($row[$i]) ? $row[$i] : '');
|
|
// if Excel was used, it surrounds strings with quotes and doubles internal double quotes. Fix that.
|
|
if (preg_match('/^".*"$/',$val))
|
|
{
|
|
$val = str_replace('""','"',substr($val,1,-1));
|
|
}
|
|
$rowarray[$rowheaders[$i]] = $val;
|
|
}
|
|
$adata[] = $rowarray;
|
|
}
|
|
|
|
$results['defaultvalues']=0;
|
|
$results['answers']=0;
|
|
$results['surveys']=0;
|
|
$results['languages']=0;
|
|
$results['questions']=0;
|
|
$results['subquestions']=0;
|
|
$results['question_attributes']=0;
|
|
$results['groups']=0;
|
|
$results['importwarnings']=array();
|
|
// these aren't used here, but are needed to avoid errors in post-import display
|
|
$results['assessments']=0;
|
|
$results['quota']=0;
|
|
$results['quotamembers']=0;
|
|
$results['quotals']=0;
|
|
|
|
// collect information about survey and its language settings
|
|
$surveyinfo = array();
|
|
$surveyls = array();
|
|
foreach ($adata as $row)
|
|
{
|
|
switch($row['class'])
|
|
{
|
|
case 'S':
|
|
if (isset($row['text']) && $row['name'] != 'datecreated')
|
|
{
|
|
$surveyinfo[$row['name']] = $row['text'];
|
|
}
|
|
break;
|
|
case 'SL':
|
|
if (!isset($surveyls[$row['language']]))
|
|
{
|
|
$surveyls[$row['language']] = array();
|
|
}
|
|
if (isset($row['text']))
|
|
{
|
|
$surveyls[$row['language']][$row['name']] = $row['text'];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
$iOldSID = 1;
|
|
if (isset($surveyinfo['sid']))
|
|
{
|
|
$iOldSID = (int) $surveyinfo['sid'];
|
|
}
|
|
|
|
// Create the survey entry
|
|
$surveyinfo['startdate']=NULL;
|
|
$surveyinfo['active']='N';
|
|
// unset($surveyinfo['datecreated']);
|
|
$iNewSID = Survey::model()->insertNewSurvey($surveyinfo) ; //or safeDie($clang->gT("Error").": Failed to insert survey<br />");
|
|
if (!$iNewSID)
|
|
{
|
|
$results['error'] = Survey::model()->getErrors();
|
|
$results['bFailed'] = true;
|
|
return $results;
|
|
}
|
|
$surveyinfo['sid']=$iNewSID;
|
|
$results['surveys']++;
|
|
$results['newsid']=$iNewSID;
|
|
|
|
$gid=0;
|
|
$gseq=0; // group_order
|
|
$qid=0;
|
|
$qseq=0; // question_order
|
|
$qtype='T';
|
|
$aseq=0; // answer sortorder
|
|
|
|
// set the language for the survey
|
|
$_title='Missing Title';
|
|
foreach ($surveyls as $_lang => $insertdata)
|
|
{
|
|
$insertdata['surveyls_survey_id'] = $iNewSID;
|
|
$insertdata['surveyls_language'] = $_lang;
|
|
if (isset($insertdata['surveyls_title']))
|
|
{
|
|
$_title = $insertdata['surveyls_title'];
|
|
}
|
|
else
|
|
{
|
|
$insertdata['surveyls_title'] = $_title;
|
|
}
|
|
|
|
|
|
$result = SurveyLanguageSetting::model()->insertNewSurvey($insertdata);//
|
|
if(!$result){
|
|
$results['error'][] = $clang->gT("Error")." : ".$clang->gT("Failed to insert survey language");
|
|
break;
|
|
}
|
|
$results['languages']++;
|
|
}
|
|
|
|
$ginfo=array();
|
|
$qinfo=array();
|
|
$sqinfo=array();
|
|
|
|
if (isset($surveyinfo['language']))
|
|
{
|
|
$baselang = $surveyinfo['language']; // the base language
|
|
}
|
|
|
|
$rownumber = 1;
|
|
$lastglang='';
|
|
foreach ($adata as $row)
|
|
{
|
|
$rownumber += 1;
|
|
switch($row['class'])
|
|
{
|
|
case 'G':
|
|
// insert group
|
|
$insertdata = array();
|
|
$insertdata['sid'] = $iNewSID;
|
|
$gname = ((!empty($row['name']) ? $row['name'] : 'G' . $gseq));
|
|
$glang = (!empty($row['language']) ? $row['language'] : $baselang);
|
|
// when a multi-lang tsv-file without information on the group id/number (old style) is imported,
|
|
// we make up this information by giving a number 0..[numberofgroups-1] per language.
|
|
// the number and order of groups per language should be the same, so we can also import these files
|
|
if ($lastglang!=$glang) //reset counter on language change
|
|
{
|
|
$iGroupcounter=0;
|
|
}
|
|
$lastglang=$glang;
|
|
//use group id/number from file. if missing, use an increasing number (s.a.)
|
|
$sGroupseq=(!empty($row['type/scale']) ? $row['type/scale'] : 'G'.$iGroupcounter++);
|
|
$insertdata['group_name'] = $gname;
|
|
$insertdata['grelevance'] = (isset($row['relevance']) ? $row['relevance'] : '');
|
|
$insertdata['description'] = (isset($row['text']) ? $row['text'] : '');
|
|
$insertdata['language'] = $glang;
|
|
|
|
// For multi language survey: same gid/sort order across all languages
|
|
if (isset($ginfo[$sGroupseq]))
|
|
{
|
|
$gid = $ginfo[$sGroupseq]['gid'];
|
|
$insertdata['gid'] = $gid;
|
|
$insertdata['group_order'] = $ginfo[$sGroupseq]['group_order'];
|
|
}
|
|
else
|
|
{
|
|
$insertdata['group_order'] = $gseq;
|
|
}
|
|
$newgid = QuestionGroup::model()->insertRecords($insertdata);
|
|
if(!$newgid){
|
|
$results['error'][] = $clang->gT("Error")." : ".$clang->gT("Failed to insert group").". ".$clang->gT("Text file row number ").$rownumber." (".$gname.")";
|
|
break;
|
|
}
|
|
if (!isset($ginfo[$sGroupseq]))
|
|
{
|
|
$results['groups']++;
|
|
$gid=$newgid;
|
|
$ginfo[$sGroupseq]['gid']=$gid;
|
|
$ginfo[$sGroupseq]['group_order']=$gseq++;
|
|
}
|
|
$qseq=0; // reset the question_order
|
|
break;
|
|
|
|
case 'Q':
|
|
// insert question
|
|
$insertdata = array();
|
|
$insertdata['sid'] = $iNewSID;
|
|
$qtype = (isset($row['type/scale']) ? $row['type/scale'] : 'T');
|
|
$qname = (isset($row['name']) ? $row['name'] : 'Q' . $qseq);
|
|
$insertdata['gid'] = $gid;
|
|
$insertdata['type'] = $qtype;
|
|
$insertdata['title'] = $qname;
|
|
$insertdata['question'] = (isset($row['text']) ? $row['text'] : '');
|
|
$insertdata['relevance'] = (isset($row['relevance']) ? $row['relevance'] : '');
|
|
$insertdata['preg'] = (isset($row['validation']) ? $row['validation'] : '');
|
|
$insertdata['help'] = (isset($row['help']) ? $row['help'] : '');
|
|
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
|
|
$insertdata['mandatory'] = (isset($row['mandatory']) ? $row['mandatory'] : '');
|
|
$lastother = $insertdata['other'] = (isset($row['other']) ? $row['other'] : 'N'); // Keep trace of other settings for sub question
|
|
$insertdata['same_default'] = (isset($row['same_default']) ? $row['same_default'] : 0);
|
|
$insertdata['parent_qid'] = 0;
|
|
|
|
// For multi numeric survey : same name, add the gid to have same name on different gid. Bad for EM.
|
|
$fullqname="G{$gid}_".$qname;
|
|
if (isset($qinfo[$fullqname]))
|
|
{
|
|
$qseq = $qinfo[$fullqname]['question_order'];
|
|
$qid = $qinfo[$fullqname]['qid'];
|
|
$insertdata['qid'] = $qid;
|
|
$insertdata['question_order'] = $qseq;
|
|
}
|
|
else
|
|
{
|
|
$insertdata['question_order'] = $qseq;
|
|
}
|
|
// Insert question and keep the qid for multi language survey
|
|
$result = Question::model()->insertRecords($insertdata);
|
|
if(!$result){
|
|
$results['error'][] = $clang->gT("Error")." : ".$clang->gT("Could not insert question").". ".$clang->gT("Text file row number ").$rownumber." (".$qname.")";
|
|
break;
|
|
}
|
|
$newqid = $result;
|
|
if (!isset($qinfo[$fullqname]))
|
|
{
|
|
$results['questions']++;
|
|
$qid=$newqid; // save this for later
|
|
$qinfo[$fullqname]['qid'] = $qid;
|
|
$qinfo[$fullqname]['question_order'] = $qseq++;
|
|
}
|
|
$aseq=0; //reset the answer sortorder
|
|
$sqseq = 0; //reset the sub question sortorder
|
|
// insert question attributes
|
|
foreach ($row as $key=>$val)
|
|
{
|
|
switch($key)
|
|
{
|
|
case 'class':
|
|
case 'type/scale':
|
|
case 'name':
|
|
case 'text':
|
|
case 'validation':
|
|
case 'relevance':
|
|
case 'help':
|
|
case 'language':
|
|
case 'mandatory':
|
|
case 'other':
|
|
case 'same_default':
|
|
case 'default':
|
|
break;
|
|
default:
|
|
if ($key != '' && $val != '')
|
|
{
|
|
$insertdata = array();
|
|
$insertdata['qid'] = $qid;
|
|
// check if attribute is a i18n attribute. If yes, set language, else set language to null in attribute table
|
|
if (isset($aAttributeList[$qtype][$key]['i18n']) && $aAttributeList[$qtype][$key]['i18n']==1)
|
|
{
|
|
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
|
|
}
|
|
else
|
|
{
|
|
$insertdata['language'] = NULL;
|
|
}
|
|
$insertdata['attribute'] = $key;
|
|
$insertdata['value'] = $val;
|
|
$result=QuestionAttribute::model()->insertRecords($insertdata);//
|
|
if(!$result){
|
|
$results['importwarnings'][] = $clang->gT("Warning")." : ".$clang->gT("Failed to insert question attribute").". ".$clang->gT("Text file row number ").$rownumber." ({$key})";
|
|
break;
|
|
}
|
|
$results['question_attributes']++;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// insert default value
|
|
if (isset($row['default']))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid'] = $qid;
|
|
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
|
|
$insertdata['defaultvalue'] = $row['default'];
|
|
$result = DefaultValue::model()->insertRecords($insertdata);
|
|
if(!$result){
|
|
$results['importwarnings'][] = $clang->gT("Warning")." : ".$clang->gT("Failed to insert default value").". ".$clang->gT("Text file row number ").$rownumber;
|
|
break;
|
|
}
|
|
$results['defaultvalues']++;
|
|
}
|
|
break;
|
|
case 'SQ':
|
|
$sqname = (isset($row['name']) ? $row['name'] : 'SQ' . $sqseq);
|
|
if ($qtype == 'O' || $qtype == '|')
|
|
{
|
|
; // these are fake rows to show naming of comment and filecount fields
|
|
}
|
|
elseif ($sqname == 'other' && $lastother=="Y") // If last question have other to Y : it's not a real SQ row
|
|
{
|
|
if($qtype=="!" || $qtype=="L")
|
|
{
|
|
// only used to set default value for 'other' in these cases
|
|
if (isset($row['default']))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid'] = $qid;
|
|
$insertdata['specialtype'] = 'other';
|
|
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
|
|
$insertdata['defaultvalue'] = $row['default'];
|
|
$result = DefaultValue::model()->insertRecords($insertdata);
|
|
if(!$result)
|
|
{
|
|
$results['importwarnings'][] = $clang->gT("Warning")." : ".$clang->gT("Failed to insert default value").". ".$clang->gT("Text file row number ").$rownumber;
|
|
break;
|
|
}
|
|
$results['defaultvalues']++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$insertdata = array();
|
|
$scale_id = (isset($row['type/scale']) ? $row['type/scale'] : 0);
|
|
$insertdata['sid'] = $iNewSID;
|
|
$insertdata['gid'] = $gid;
|
|
$insertdata['parent_qid'] = $qid;
|
|
$insertdata['type'] = $qtype;
|
|
$insertdata['title'] = $sqname;
|
|
$insertdata['question'] = (isset($row['text']) ? $row['text'] : '');
|
|
$insertdata['relevance'] = (isset($row['relevance']) ? $row['relevance'] : '');
|
|
$insertdata['preg'] = (isset($row['validation']) ? $row['validation'] : '');
|
|
$insertdata['help'] = (isset($row['help']) ? $row['help'] : '');
|
|
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
|
|
$insertdata['mandatory'] = (isset($row['mandatory']) ? $row['mandatory'] : '');
|
|
$insertdata['scale_id'] = $scale_id;
|
|
// For multi nueric language, qid is needed, why not gid. name is not unique.
|
|
$fullsqname = "G{$gid}Q{$qid}_{$scale_id}_{$sqname}";
|
|
if (isset($sqinfo[$fullsqname]))
|
|
{
|
|
$qseq = $sqinfo[$fullsqname]['question_order'];
|
|
$sqid = $sqinfo[$fullsqname]['sqid'];
|
|
$insertdata['question_order'] = $qseq;
|
|
$insertdata['qid'] = $sqid;
|
|
}
|
|
else
|
|
{
|
|
$insertdata['question_order'] = $qseq;
|
|
}
|
|
// Insert sub question and keep the sqid for multi language survey
|
|
$newsqid = Question::model()->insertRecords($insertdata);
|
|
if(!$newsqid){
|
|
$results['error'][] = $clang->gT("Error")." : ".$clang->gT("Could not insert subquestion").". ".$clang->gT("Text file row number ").$rownumber." (".$qname.")";
|
|
break;
|
|
}
|
|
if (!isset($sqinfo[$fullsqname]))
|
|
{
|
|
$sqinfo[$fullsqname]['question_order'] = $qseq++;
|
|
$sqid=$newsqid; // save this for later
|
|
$sqinfo[$fullsqname]['sqid'] = $sqid;
|
|
$results['subquestions']++;
|
|
}
|
|
|
|
// insert default value
|
|
if (isset($row['default']))
|
|
{
|
|
$insertdata=array();
|
|
$insertdata['qid'] = $qid;
|
|
$insertdata['sqid'] = $sqid;
|
|
$insertdata['scale_id'] = $scale_id;
|
|
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
|
|
$insertdata['defaultvalue'] = $row['default'];
|
|
$result = DefaultValue::model()->insertRecords($insertdata);
|
|
if(!$result){
|
|
$results['importwarnings'][] = $clang->gT("Warning")." : ".$clang->gT("Failed to insert default value").". ".$clang->gT("Text file row number ").$rownumber;
|
|
break;
|
|
}
|
|
$results['defaultvalues']++;
|
|
}
|
|
}
|
|
break;
|
|
case 'A':
|
|
$insertdata = array();
|
|
$insertdata['qid'] = $qid;
|
|
$insertdata['code'] = (isset($row['name']) ? $row['name'] : 'A' . $aseq);
|
|
$insertdata['answer'] = (isset($row['text']) ? $row['text'] : '');
|
|
$insertdata['scale_id'] = (isset($row['type/scale']) ? $row['type/scale'] : 0);
|
|
$insertdata['language']= (isset($row['language']) ? $row['language'] : $baselang);
|
|
$insertdata['assessment_value'] = (int) (isset($row['relevance']) ? $row['relevance'] : '');
|
|
$insertdata['sortorder'] = ++$aseq;
|
|
$result = Answer::model()->insertRecords($insertdata); // or safeDie("Error: Failed to insert answer<br />");
|
|
if(!$result){
|
|
$results['error'][] = $clang->gT("Error")." : ".$clang->gT("Could not insert answer").". ".$clang->gT("Text file row number ").$rownumber;
|
|
}
|
|
$results['answers']++;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
// Delete the survey if error found
|
|
if(is_array($results['error']))
|
|
{
|
|
$result = Survey::model()->deleteSurvey($iNewSID);
|
|
}
|
|
else
|
|
{
|
|
LimeExpressionManager::SetSurveyId($iNewSID);
|
|
LimeExpressionManager::RevertUpgradeConditionsToRelevance($iNewSID);
|
|
LimeExpressionManager::UpgradeConditionsToRelevance($iNewSID);
|
|
}
|
|
|
|
return $results;
|
|
}
|