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)
\n$qinsert
\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
\n$qinsert
\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)
\n$qinsert
\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.='
'.$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
$conditioninsert
");
$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
$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))
{
//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
$query
");
$query = "DELETE FROM {{labelsets}} WHERE lid=$newlid";
$result=Yii::app()->db->createCommand($query)->query() or safeDie("Couldn't delete labelset
$query
");
$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
\n$qinsert
\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
\n$qinsert
\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
\n$qinsert
\n");
}
}
}
}
//Do answers
if (isset($answerarray) && $answerarray)
{
foreach ($answerarray as $aa)
{
$answerfieldcontents=str_getcsv($aa,',','"');
$answerrowdata=array_combine($answerfieldnames,$answerfieldcontents);
if ($answerrowdata===false)
{
$importquestion.='
'.$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
\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
$query2
");
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."
"; 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
$query
");
$query = "DELETE FROM {{labelsets}} WHERE lid=$newlid";
$result = Yii::app()->db->createCommand($query)->execute() or safeDie("Couldn't delete labelset
$query
");
$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 .= "