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 .= "
".$clang->gT("Error")."

\n"; $importsurvey .= $clang->gT("Import of this survey file failed")."
\n"; $importsurvey .= $clang->gT("File does not contain LimeSurvey data in the correct format.")."

\n"; //Couldn't find the SID - cannot continue $importsurvey .= "\n"; $importsurvey .= "\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 ("
".$clang->gT("Import of this survey file failed")."
{$surveyarray[0]}

\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
// 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("
".$clang->gT("Import of this survey file failed")."
"); } // 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
"); 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.")."
\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
\
\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.
"); } } 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]
"); } 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 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.='
'.$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
"); } // 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.
"); } } 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
"); } } else // insert answers { unset($answerrowdata['default_value']); if ($answerrowdata) XSSFilterArray($answerrowdata); $ares = Answer::model()->insertRecords($answerrowdata) or safeDie("Error: Failed to insert answer
"); $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'].'
'.$asrowdata['link'].''; 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
"); 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
"); $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
"); } } 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
"); } } //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
"); $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
"); } } 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]
"); $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]
"); } // 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]
"); $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.
"); } } 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.
"); } } 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]
"); } } else { $result=QuestionAttribute::model()->insertRecords($insertdata) or safeDie($clang->gT("Error").": Failed to insert data[8]
"); } $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]
"); $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]
"); $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]
"); $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]
"); $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]
"); $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
"); $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]
"); $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'] , "".$clang->gT('Attention: Several question codes were updated. Please check these carefully as the update may not be perfect with customized expressions.').''); } 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]
"); $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]
"); $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
"); 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
"); 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; }