View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
04739 | Bug reports | Import/Export | public | 2010-11-14 19:06 | 2010-12-07 14:14 |
Reporter | Assigned To | c_schmitz | |||
Priority | normal | Severity | partial_block | ||
Status | closed | Resolution | fixed | ||
Product Version | 1.90+ | ||||
Summary | 04739: Exported survey lss file does not import | ||||
Description | I exported the attached survey file from a running (production environment) lime instance. | ||||
Steps To Reproduce | 1- take attached lss file and try to import it. | ||||
Additional Information | I have no clue whether the problem comes from the export process which produces a faulty lss file or whether it comes from the import process that has problems handling the lss file. | ||||
Tags | No tags attached. | ||||
Attached Files | export_structure_xml.php (7,682 bytes)
<?php /* * LimeSurvey * Copyright (C) 2007 The LimeSurvey Project Team / Carsten Schmitz * All rights reserved. * License: GNU/GPL License v2 or later, see LICENSE.php * LimeSurvey is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. * See COPYRIGHT.php for copyright notices and details. * * $Id: export_structure_csv.php 8592 2010-04-14 12:23:25Z machaven $ */ // DUMP THE RELATED DATA FOR A SINGLE SURVEY INTO AN XML FILE FOR IMPORTING LATER ON OR ON ANOTHER SURVEY SETUP // DUMP ALL DATA FOR RELATED SID FROM THE FOLLOWING TABLES: // Answers // Assessments // Conditions // Default values // Groups // Questions // Question attributes // Quota // Quota Members // Surveys // Surveys language settings include_once("login_check.php"); require_once ("export_data_functions.php"); if (!isset($surveyid)) { $surveyid=returnglobal('sid'); } if (!$surveyid) { echo $htmlheader ."<br />\n" ."<table width='350' align='center' style='border: 1px solid #555555' cellpadding='1' cellspacing='0'>\n" ."\t<tr bgcolor='#555555'><td colspan='2' height='4'><font size='1' face='verdana' color='white'><strong>" .$clang->gT("Export Survey")."</strong></td></tr>\n" ."\t<tr><td align='center'>\n" ."<br /><strong><font color='red'>" .$clang->gT("Error")."</font></strong><br />\n" .$clang->gT("No SID has been provided. Cannot dump survey")."<br />\n" ."<br /><input type='submit' value='" .$clang->gT("Main Admin Screen")."' onclick=\"window.open('$scriptname', '_top')\">\n" ."\t</td></tr>\n" ."</table>\n" ."</body></html>\n"; exit; } function getXMLStructure($xmlwriter, $exclude=array()) { global $dbprefix, $surveyid, $connect; $sdump = ""; if ((!isset($exclude) && $exclude['answers'] !== true) || empty($exclude)) { //Answers table $aquery = "SELECT {$dbprefix}answers.* FROM {$dbprefix}answers, {$dbprefix}questions WHERE {$dbprefix}answers.language={$dbprefix}questions.language AND {$dbprefix}answers.qid={$dbprefix}questions.qid AND {$dbprefix}questions.sid=$surveyid"; BuildXMLFromQuery($xmlwriter,$aquery); } // Assessments $query = "SELECT {$dbprefix}assessments.* FROM {$dbprefix}assessments WHERE {$dbprefix}assessments.sid=$surveyid"; BuildXMLFromQuery($xmlwriter,$query); if ((!isset($exclude) && $exclude['conditions'] !== true) || empty($exclude)) { //Conditions table $cquery = "SELECT DISTINCT {$dbprefix}conditions.* FROM {$dbprefix}conditions, {$dbprefix}questions WHERE {$dbprefix}conditions.qid={$dbprefix}questions.qid AND {$dbprefix}questions.sid=$surveyid"; BuildXMLFromQuery($xmlwriter,$cquery); } //Default values $query = "SELECT {$dbprefix}defaultvalues.* FROM {$dbprefix}defaultvalues JOIN {$dbprefix}questions ON {$dbprefix}questions.qid = {$dbprefix}defaultvalues.qid AND {$dbprefix}questions.sid=$surveyid AND {$dbprefix}questions.language={$dbprefix}defaultvalues.language "; BuildXMLFromQuery($xmlwriter,$query); // Groups $gquery = "SELECT * FROM {$dbprefix}groups WHERE sid=$surveyid ORDER BY gid"; BuildXMLFromQuery($xmlwriter,$gquery); //Questions $qquery = "SELECT * FROM {$dbprefix}questions WHERE sid=$surveyid and parent_qid=0 ORDER BY qid"; BuildXMLFromQuery($xmlwriter,$qquery); //Subquestions $qquery = "SELECT * FROM {$dbprefix}questions WHERE sid=$surveyid and parent_qid>0 ORDER BY qid"; BuildXMLFromQuery($xmlwriter,$qquery,'subquestions'); //Question attributes $sBaseLanguage=GetBaseLanguageFromSurveyID($surveyid); if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType =='mssqlnative') { $query="SELECT qa.qid, qa.attribute, cast(qa.value as varchar(4000)) as value FROM {$dbprefix}question_attributes qa JOIN {$dbprefix}questions q ON q.qid = qa.qid AND q.sid={$surveyid} where q.language='{$sBaseLanguage}' group by qa.qid, qa.attribute, cast(qa.value as varchar(4000))"; } else { $query="SELECT qa.qid, qa.attribute, qa.value FROM {$dbprefix}question_attributes qa JOIN {$dbprefix}questions q ON q.qid = qa.qid AND q.sid={$surveyid} where q.language='{$sBaseLanguage}' group by qa.qid, qa.attribute, qa.value"; } BuildXMLFromQuery($xmlwriter,$query,'question_attributes'); if ((!isset($exclude) && $exclude['quotas'] !== true) || empty($exclude)) { //Quota $query = "SELECT {$dbprefix}quota.* FROM {$dbprefix}quota WHERE {$dbprefix}quota.sid=$surveyid"; BuildXMLFromQuery($xmlwriter,$query); //1Quota members $query = "SELECT {$dbprefix}quota_members.* FROM {$dbprefix}quota_members WHERE {$dbprefix}quota_members.sid=$surveyid"; BuildXMLFromQuery($xmlwriter,$query); //Quota languagesettings $query = "SELECT {$dbprefix}quota_languagesettings.* FROM {$dbprefix}quota_languagesettings, {$dbprefix}quota WHERE {$dbprefix}quota.id = {$dbprefix}quota_languagesettings.quotals_quota_id AND {$dbprefix}quota.sid=$surveyid"; BuildXMLFromQuery($xmlwriter,$query); } // Surveys $squery = "SELECT * FROM {$dbprefix}surveys WHERE sid=$surveyid"; //Exclude some fields from the export BuildXMLFromQuery($xmlwriter,$squery,'',array('owner_id','active','datecreated')); // Survey language settings $slsquery = "SELECT * FROM {$dbprefix}surveys_languagesettings WHERE surveyls_survey_id=$surveyid"; BuildXMLFromQuery($xmlwriter,$slsquery); } function getXMLData($exclude = array()) { global $dbversionnumber,$surveyid; $xml = getXMLWriter(); $xml->openMemory(); $xml->setIndent(true); $xml->startDocument('1.0', 'UTF-8'); $xml->startElement('document'); $xml->writeElement('LimeSurveyDocType','Survey'); $xml->writeElement('DBVersion',$dbversionnumber); $xml->startElement('languages'); $surveylanguages=GetAdditionalLanguagesFromSurveyID($surveyid); $surveylanguages[]=GetBaseLanguageFromSurveyID($surveyid); foreach ($surveylanguages as $surveylanguage) { $xml->writeElement('language',$surveylanguage); } $xml->endElement(); getXMLStructure($xml,$exclude); $xml->endElement(); // close columns $xml->endDocument(); return $xml->outputMemory(true); } if (!isset($copyfunction)) { $fn = "limesurvey_survey_$surveyid.lss"; header("Content-Type: text/html/force-download"); header("Content-Disposition: attachment; filename=$fn"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Pragma: cache"); // HTTP/1.0 echo getXMLData(); exit; } ?> dumpquestion.php (4,959 bytes)
<?php /* * LimeSurvey * Copyright (C) 2007 The LimeSurvey Project Team / Carsten Schmitz * All rights reserved. * License: GNU/GPL License v2 or later, see LICENSE.php * LimeSurvey is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. * See COPYRIGHT.php for copyright notices and details. * * $Id: dumpquestion.php 9499 2010-11-18 02:06:13Z c_schmitz $ */ // DUMP THE RELATED DATA FOR A SINGLE QUESTION INTO A SQL FILE FOR IMPORTING LATER ON OR // ON ANOTHER SURVEY SETUP DUMP ALL DATA WITH RELATED QID FROM THE FOLLOWING TABLES // - Questions // - Answers // - Question attributes // - Default values //Ensure script is not run directly, avoid path disclosure if (!isset($dbprefix) || isset($_REQUEST['dbprefix'])) {die("Cannot run this script directly");} include_once("login_check.php"); require_once("export_data_functions.php"); if(!bHasRight($surveyid,'export')) safe_die("You are not allowed to export questions."); $qid = returnglobal('qid'); if (!$qid) { safe_die("No QID has been provided. Cannot dump question."); } $fn = "limesurvey_question_$qid.lsq"; $xml = getXMLWriter(); if($action=='exportstructureLsrcCsvQuestion') { include_once($homedir.'/remotecontrol/lsrc.config.php'); //Select title as Filename and save $questionTitleSql = "SELECT title FROM {$dbprefix}questions WHERE qid=$qid AND sid=$surveyid AND gid=$gid "; $questionTitle = $connect->GetOne($questionTitleSql); $xml->openURI('remotecontrol/'.$queDir.substr($questionTitle,0,20).".lsq"); } else { header("Content-Type: text/html/force-download"); header("Content-Disposition: attachment; filename=$fn"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Pragma: cache"); // HTTP/1.0 $xml->openURI('php://output'); } $xml->setIndent(true); $xml->startDocument('1.0', 'UTF-8'); $xml->startElement('document'); $xml->writeElement('LimeSurveyDocType','Question'); $xml->writeElement('DBVersion',$dbversionnumber); $xml->startElement('languages'); $lquery = "SELECT language FROM {$dbprefix}questions WHERE qid=$qid or parent_qid=$qid group by language"; $lresult=db_execute_assoc($lquery); while ($row=$lresult->FetchRow()) { $xml->writeElement('language',$row['language']); } $xml->endElement(); getXMLStructure($xml,$qid); $xml->endElement(); // close columns $xml->endDocument(); exit; function getXMLStructure($xml,$qid) { global $dbprefix, $connect; // Questions table $qquery = "SELECT * FROM {$dbprefix}questions WHERE qid=$qid and parent_qid=0 order by language, scale_id, question_order"; BuildXMLFromQuery($xml,$qquery); // Questions table - Subquestions $qquery = "SELECT * FROM {$dbprefix}questions WHERE parent_qid=$qid order by language, scale_id, question_order"; BuildXMLFromQuery($xml,$qquery,'subquestions'); // Answers table $aquery = "SELECT * FROM {$dbprefix}answers WHERE qid = $qid order by language, scale_id, sortorder"; BuildXMLFromQuery($xml,$aquery); // Question attributes $surveyid=$connect->GetOne("select sid from {$dbprefix}questions where qid={$qid}"); $sBaseLanguage=GetBaseLanguageFromSurveyID($surveyid); if ($connect->databaseType == 'odbc_mssql' || $connect->databaseType == 'odbtp' || $connect->databaseType == 'mssql_n' || $connect->databaseType =='mssqlnative') { $query="SELECT qa.qid, qa.attribute, cast(qa.value as varchar(4000)) as value FROM {$dbprefix}question_attributes qa JOIN {$dbprefix}questions q ON q.qid = qa.qid AND q.sid={$surveyid} and q.qid={$qid} where q.language='{$sBaseLanguage}' group by qa.qid, qa.attribute, cast(qa.value as varchar(4000))"; } else { $query="SELECT qa.qid, qa.attribute, qa.value FROM {$dbprefix}question_attributes qa JOIN {$dbprefix}questions q ON q.qid = qa.qid AND q.sid={$surveyid} and q.qid={$qid} where q.language='{$sBaseLanguage}' group by qa.qid, qa.attribute, qa.value"; } BuildXMLFromQuery($xml,$query); // Default values $query = "SELECT * FROM {$dbprefix}defaultvalues WHERE qid=$qid order by language, scale_id"; BuildXMLFromQuery($xml,$query); } importgroup.php (53,747 bytes)
<?php /* * LimeSurvey * Copyright (C) 2007 The LimeSurvey Project Team / Carsten Schmitz * All rights reserved. * License: GNU/GPL License v2 or later, see LICENSE.php * LimeSurvey is free software. This version may have been modified pursuant * to the GNU General Public License, and as distributed it includes or * is derivative of works licensed under the GNU General Public License or * other free or open source software licenses. * See COPYRIGHT.php for copyright notices and details. * * $Id: importgroup.php 9503 2010-11-18 13:34:17Z c_schmitz $ */ //Ensure script is not run directly, avoid path disclosure include_once("login_check.php"); $importgroup = "<div class='header'>".$clang->gT("Import question group")."</div>\n"; $importgroup .= "<div class='messagebox'>\n"; $sFullFilepath = $tempdir . DIRECTORY_SEPARATOR . $_FILES['the_file']['name']; $aPathInfo = pathinfo($sFullFilepath); $sExtension = $aPathInfo['extension']; if (!@move_uploaded_file($_FILES['the_file']['tmp_name'], $sFullFilepath)) { $fatalerror = sprintf ($clang->gT("An error occurred uploading your file. This may be caused by incorrect permissions in your %s folder."),$tempdir); } // validate that we have a SID if (!returnglobal('sid')) { $fatalerror .= $clang->gT("No SID (Survey) has been provided. Cannot import question."); } else { $surveyid=returnglobal('sid'); } if (isset($fatalerror)) { $importgroup .= "<div class='warningheader'>".$clang->gT("Error")."</div><br />\n"; $importgroup .= $fatalerror."<br /><br />\n"; $importgroup .= "<input type='submit' value='".$clang->gT("Main Admin Screen")."' onclick=\"window.open('$scriptname', '_top')\" /><br /><br />\n"; $importgroup .= "</div>\n"; @unlink($sFullFilepath); return; } // IF WE GOT THIS FAR, THEN THE FILE HAS BEEN UPLOADED SUCCESFULLY $importgroup .= "<div class='successheader'>".$clang->gT("Success")."</div> <br />\n" .$clang->gT("File upload succeeded.")."<br /><br />\n" .$clang->gT("Reading file..")."<br /><br />\n"; if (strtolower($sExtension)=='csv') { $aImportResults=CSVImportGroup($sFullFilepath, $surveyid); } elseif (strtolower($sExtension)=='lsg') { $aImportResults=XMLImportGroup($sFullFilepath, $surveyid); } else die('Unknown file extension'); FixLanguageConsistency($surveyid); if (isset($aImportResults['fatalerror'])) { $importgroup .= "<div class='warningheader'>".$clang->gT("Error")."</div><br />\n"; $importgroup .= $aImportResults['fatalerror']."<br /><br />\n"; $importgroup .= "<input type='submit' value='".$clang->gT("Main Admin Screen")."' onclick=\"window.open('$scriptname', '_top')\" />\n"; $importgroup .= "</div>\n"; unlink($sFullFilepath); return; } $importgroup .= "<div class='successheader'>".$clang->gT("Success")."</div><br />\n" ."<strong><u>".$clang->gT("Question group import summary")."</u></strong><br />\n" ."<ul style=\"text-align:left;\">\n" ."\t<li>".$clang->gT("Groups").": ".$aImportResults['groups']."</li>\n" ."\t<li>".$clang->gT("Questions").": ".$aImportResults['questions']."</li>\n" ."\t<li>".$clang->gT("Subquestions").": ".$aImportResults['subquestions']."</li>\n" ."\t<li>".$clang->gT("Answers").": ".$aImportResults['answers']."</li>\n" ."\t<li>".$clang->gT("Conditions").": ".$aImportResults['conditions']."</li>\n"; if (strtolower($sExtension)=='csv') { $importgroup.="\t<li>".$clang->gT("Label sets").": ".$aImportResults['labelsets']." (".$aImportResults['labels'].")</li>\n"; } $importgroup.="\t<li>".$clang->gT("Question attributes:").$aImportResults['question_attributes']."</li>" ."</ul>\n"; $importgroup .= "<strong>".$clang->gT("Question group import is complete.")."</strong><br /> \n"; $importgroup .= "<input type='submit' value='".$clang->gT("Go to question group")."' onclick=\"window.open('$scriptname?sid=$surveyid&gid={$aImportResults['newgid']}', '_top')\" />\n"; $importgroup .= "</div><br />\n"; unlink($sFullFilepath); /** * This function imports an old-school question group file (*.csv,*.sql) * * @param mixed $sFullFilepath Full file patch to the import file * @param mixed $newsid Survey ID to which the question is attached */ function CSVImportGroup($sFullFilepath, $newsid) { global $dbprefix, $connect, $clang; $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=convertCSVRowToArray($questionarray[0],',','"'); unset($questionarray[0]); $countquestions = 0; } if (isset($answerarray)) { $answerfieldnames=convertCSVRowToArray($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 = GetBaseLanguageFromSurveyID($newsid); $aLanguagesSupported[]=$sBaseLanguage; // adds the base language to the list of supported languages $aLanguagesSupported=array_merge($aLanguagesSupported,GetAdditionalLanguagesFromSurveyID($newsid)); // Let's check that imported objects support at least the survey's baselang $langcode = GetBaseLanguageFromSurveyID($newsid); if (isset($grouparray)) { $groupfieldnames = convertCSVRowToArray($grouparray[0],',','"'); $langfieldnum = array_search("language", $groupfieldnames); $gidfieldnum = array_search("gid", $groupfieldnames); $groupssupportbaselang = bDoesImportarraySupportsLanguage($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 = bDoesImportarraySupportsLanguage($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 = bDoesImportarraySupportsLanguage($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 = convertCSVRowToArray($labelsetsarray[0],',','"'); $langfieldnum = array_search("languages", $labelsetfieldname); $lidfilednum = array_search("lid", $labelsetfieldname); $labelsetssupportbaselang = bDoesImportarraySupportsLanguage($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 = getqtypelist("" ,"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 =convertCSVRowToArray($labelsetsarray[0],',','"'); $fieldcontents=convertCSVRowToArray($lsa,',','"'); if ($count==0) {$count++; continue;} $labelsetrowdata=array_combine($fieldorders,$fieldcontents); // Save old labelid $oldlid=$labelsetrowdata['lid']; unset($labelsetrowdata['lid']); $newvalues=array_values($labelsetrowdata); $newvalues=array_map(array(&$connect, "qstr"),$newvalues); // quote everything accordingly $lsainsert = "INSERT INTO {$dbprefix}labelsets (".implode(',',array_keys($labelsetrowdata)).") VALUES (".implode(',',$newvalues).")"; //handle db prefix $lsiresult=$connect->Execute($lsainsert); $results['labelsets']++; // Get the new insert id for the labels inside this labelset $newlid=$connect->Insert_ID("{$dbprefix}labelsets",'lid'); if ($labelsarray) { $count=0; foreach ($labelsarray as $la) { $lfieldorders =convertCSVRowToArray($labelsarray[0],',','"'); $lfieldcontents=convertCSVRowToArray($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']=translink('label', $oldlid, $newlid, $labelrowdata['title']); $newvalues=array_values($labelrowdata); $newvalues=array_map(array(&$connect, "qstr"),$newvalues); // quote everything accordingly $lainsert = "INSERT INTO {$dbprefix}labels (".implode(',',array_keys($labelrowdata)).") VALUES (".implode(',',$newvalues).")"; //handle db prefix $liresult=$connect->Execute($lainsert); if ($liresult!==false) $results['labels']++; } } } //CHECK FOR DUPLICATE LABELSETS $thisset=""; $query2 = "SELECT code, title, sortorder, language, assessment_value FROM {$dbprefix}labels WHERE lid=".$newlid." ORDER BY language, sortorder, code"; $result2 = db_execute_num($query2) or safe_die("Died querying labelset $lid<br />$query2<br />".$connect->ErrorMsg()); while($row2=$result2->FetchRow()) { $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) || ($_SESSION['USER_RIGHT_MANAGE_LABEL'] != 1)) { //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 {$dbprefix}labels WHERE lid=$newlid"; $result=$connect->Execute($query) or safe_die("Couldn't delete labels<br />$query<br />".$connect->ErrorMsg()); $results['labels']=$results['labels']-$connect->Affected_Rows(); $query = "DELETE FROM {$dbprefix}labelsets WHERE lid=$newlid"; $result=$connect->Execute($query) or safe_die("Couldn't delete labelset<br />$query<br />".$connect->ErrorMsg()); $results['labelsets']=$results['labelsets']-$connect->Affected_Rows(); $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=convertCSVRowToArray($grouparray[0],',','"'); unset($grouparray[0]); $newgid = 0; $group_order = 0; // just to initialize this variable foreach ($grouparray as $ga) { $gacfieldcontents=convertCSVRowToArray($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 $oldsid=$grouprowdata['sid']; $grouprowdata['sid']=$newsid; // 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 ".db_table_name('groups')." where sid=$newsid"; $gres = db_execute_assoc($qmaxgo) or safe_die ($clang->gT("Error")." Failed to find out maximum group order value<br />\n$qmaxqo<br />\n".$connect->ErrorMsg()); $grow=$gres->FetchRow(); $group_order = $grow['maxgo']+1; } else $grouprowdata['gid'] = $newgid; $grouprowdata["group_order"]= $group_order; // Everything set - now insert it $grouprowdata=array_map('convertCsvreturn2return', $grouprowdata); // translate internal links $grouprowdata['group_name']=translink('survey', $oldsid, $newsid, $grouprowdata['group_name']); $grouprowdata['description']=translink('survey', $oldsid, $newsid, $grouprowdata['description']); db_switchIDInsert('groups',true); $tablename=$dbprefix.'groups'; $ginsert = $connect->GetinsertSQL($tablename,$grouprowdata); $gres = $connect->Execute($ginsert) or safe_die($clang->gT('Error').": Failed to insert group<br />\n$ginsert<br />\n".$connect->ErrorMsg()); db_switchIDInsert('groups',false); //GET NEW GID .... if is not done before and we count a group if a new gid is required if ($newgid == 0) { $newgid = $connect->Insert_ID("{$dbprefix}groups",'gid'); $countgroups++; } } // GROUPS is DONE // Import questions if (isset($questionarray) && $questionarray) { foreach ($questionarray as $qa) { $qacfieldcontents=convertCSVRowToArray($qa,',','"'); $questionrowdata=array_combine($questionfieldnames,$qacfieldcontents); $questionrowdata=array_map('convertCsvreturn2return', $questionrowdata); $questionrowdata["type"]=strtoupper($questionrowdata["type"]); // Skip not supported languages if (!in_array($questionrowdata['language'],$aLanguagesSupported)) continue; // replace the sid $questionrowdata["sid"] = $newsid; // 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('convertCsvreturn2return', $questionrowdata); // translate internal links $questionrowdata['title']=translink('survey', $oldsid, $newsid, $questionrowdata['title']); $questionrowdata['question']=translink('survey', $oldsid, $newsid, $questionrowdata['question']); $questionrowdata['help']=translink('survey', $oldsid, $newsid, $questionrowdata['help']); $newvalues=array_values($questionrowdata); $newvalues=array_map(array(&$connect, "qstr"),$newvalues); // quote everything accordingly if (isset($questionrowdata['qid'])) { db_switchIDInsert('questions',true); } $tablename=$dbprefix.'questions'; $qinsert = $connect->GetInsertSQL($tablename,$questionrowdata); $qres = $connect->Execute($qinsert) or safe_die ($clang->gT("Error").": Failed to insert question<br />\n$qinsert<br />\n".$connect->ErrorMsg()); $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]=$connect->Insert_ID("{$dbprefix}questions",'qid'); $saveqid=$aQIDReplacements[$oldqid]; } $qtypes = getqtypelist("" ,"array"); $aSQIDReplacements=array(); db_switchIDInsert('questions',false); // 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 ".db_table_name('labels')." where lid={$aLIDReplacements[$oldlid1]} and language='{$questionrowdata['language']}'"; $oldlabelsresult=db_execute_assoc($query); while($labelrow=$oldlabelsresult->FetchRow()) { if (in_array($labelrow['language'],$aLanguagesSupported)) { if ($qtypes[$questionrowdata['type']]['subquestions']<2) { $qinsert = "insert INTO ".db_table_name('answers')." (qid,code,answer,sortorder,language,assessment_value) VALUES ({$aQIDReplacements[$oldqid]},".db_quoteall($labelrow['code']).",".db_quoteall($labelrow['title']).",".db_quoteall($labelrow['sortorder']).",".db_quoteall($labelrow['language']).",".db_quoteall($labelrow['assessment_value']).")"; $qres = $connect->Execute($qinsert) or safe_die ($clang->gT("Error").": Failed to insert answer (lid1) <br />\n$qinsert<br />\n".$connect->ErrorMsg()); } else { if (isset($aSQIDReplacements[$labelrow['code'].'_'.$saveqid])){ $fieldname='qid,'; $data=$aSQIDReplacements[$labelrow['code'].'_'.$saveqid].','; } else { $fieldname='' ; $data=''; } $qinsert = "insert INTO ".db_table_name('questions')." ($fieldname parent_qid,title,question,question_order,language,scale_id,type, sid, gid) VALUES ($data{$aQIDReplacements[$oldqid]},".db_quoteall($labelrow['code']).",".db_quoteall($labelrow['title']).",".db_quoteall($labelrow['sortorder']).",".db_quoteall($labelrow['language']).",1,'{$questionrowdata['type']}',{$questionrowdata['sid']},{$questionrowdata['gid']})"; $qres = $connect->Execute($qinsert) or safe_die ($clang->gT("Error").": Failed to insert question <br />\n$qinsert<br />\n".$connect->ErrorMsg()); if ($fieldname=='') { $aSQIDReplacements[$labelrow['code'].'_'.$saveqid]=$connect->Insert_ID("{$dbprefix}questions","qid"); } } } } if (isset($oldlid2) && $qtypes[$questionrowdata['type']]['answerscales']>1) { $query="select * from ".db_table_name('labels')." where lid={$aLIDReplacements[$oldlid2]} and language='{$questionrowdata['language']}'"; $oldlabelsresult=db_execute_assoc($query); while($labelrow=$oldlabelsresult->FetchRow()) { $qinsert = "insert INTO ".db_table_name('answers')." (qid,code,answer,sortorder,language,assessment_value,scale_id) VALUES ({$aQIDReplacements[$oldqid]},".db_quoteall($labelrow['code']).",".db_quoteall($labelrow['title']).",".db_quoteall($labelrow['sortorder']).",".db_quoteall($labelrow['language']).",".db_quoteall($labelrow['assessment_value']).",1)"; $qres = $connect->Execute($qinsert) or safe_die ($clang->gT("Error").": Failed to insert answer (lid2)<br />\n$qinsert<br />\n".$connect->ErrorMsg()); } } } } } //Do answers $results['subquestions']=0; if (isset($answerarray) && $answerarray) { foreach ($answerarray as $aa) { $answerfieldcontents=convertCSVRowToArray($aa,',','"'); $answerrowdata=array_combine($answerfieldnames,$answerfieldcontents); if ($answerrowdata===false) { $importquestion.='<br />'.$clang->gT("Faulty line in import - fields and data don't match").":".implode(',',$answerfieldcontents); } // Skip not supported languages if (!in_array($answerrowdata['language'],$aLanguagesSupported)) continue; // replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this answer is orphan -> error, skip this record) if (isset($aQIDReplacements[$answerrowdata["qid"]])) $answerrowdata["qid"] = $aQIDReplacements[$answerrowdata["qid"]]; else continue; // a problem with this answer record -> don't consider if ($importversion<=132) { $answerrowdata["assessment_value"]=(int)$answerrowdata["code"]; } // Convert default values for single select questions $questiontemp=$connect->GetRow('select type,gid from '.db_table_name('questions').' where qid='.$answerrowdata["qid"]); $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']; $query=$connect->GetInsertSQL($dbprefix.'defaultvalues',$insertdata); $qres = $connect->Execute($query) or safe_die ("Error: Failed to insert defaultvalue <br />{$query}<br />\n".$connect->ErrorMsg()); } // translate internal links $answerrowdata['answer']=translink('survey', $oldsid, $newsid, $answerrowdata['answer']); // Everything set - now insert it $answerrowdata = array_map('convertCsvreturn2return', $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']=$newsid; $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']; $tablename=$dbprefix.'questions'; $query=$connect->GetInsertSQL($tablename,$questionrowdata); if (isset($questionrowdata['qid'])) db_switchIDInsert('questions',true); $qres = $connect->Execute($query) or safe_die ("Error: Failed to insert subquestion <br />{$query}<br />".$connect->ErrorMsg()); if (!isset($questionrowdata['qid'])) { $aSQIDReplacements[$answerrowdata['code'].$answerrowdata['qid']]=$connect->Insert_ID("{$dbprefix}questions","qid"); } else { db_switchIDInsert('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'; $tablename=$dbprefix.'defaultvalues'; $query=$connect->GetInsertSQL($tablename,$insertdata); $qres = $connect->Execute($query) or safe_die ("Error: Failed to insert defaultvalue <br />{$query}<br />\n".$connect->ErrorMsg()); } } else // insert answers { unset($answerrowdata['default_value']); $tablename=$dbprefix.'answers'; $query=$connect->GetInsertSQL($tablename,$answerrowdata); $ares = $connect->Execute($query) or safe_die ("Error: Failed to insert answer<br />{$query}<br />\n".$connect->ErrorMsg()); $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 {$dbprefix}groups where sid=$newsid group by gid ORDER BY gid"; //Get last question added (finds new qid) $gres = db_execute_assoc($gquery); while ($grow = $gres->FetchRow()) { fixsortorderQuestions($grow['gid'], $newsid); } } $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=convertCSVRowToArray($question_attributesarray[0],',','"'); unset($question_attributesarray[0]); foreach ($question_attributesarray as $qar) { $fieldcontents=convertCSVRowToArray($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"]); $tablename="{$dbprefix}question_attributes"; $qainsert=$connect->GetInsertSQL($tablename,$qarowdata); $result=$connect->Execute($qainsert); if ($result!==false) $results['question_attributes']++; } } // ATTRIBUTES is DONE // do CONDITIONS $results['conditions']=0; if (isset($conditionsarray) && $conditionsarray) { $fieldorders=convertCSVRowToArray($conditionsarray[0],',','"'); unset($conditionsarray[0]); foreach ($conditionsarray as $car) { $fieldcontents=convertCSVRowToArray($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 = '+'.$newsid . "X" . $newgid . "X" . $conditionrowdata["cqid"] .substr($oldqidanscode,strlen($oldqid)); } else { $newcfieldname = $newsid . "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); $newvalues=array_map(array(&$connect, "qstr"),$newvalues); // quote everything accordingly $conditioninsert = "insert INTO {$dbprefix}conditions (".implode(',',array_keys($conditionrowdata)).") VALUES (".implode(',',$newvalues).")"; $result=$connect->Execute($conditioninsert) or safe_die ("Couldn't insert condition<br />$conditioninsert<br />".$connect->ErrorMsg()); $results['conditions']++; } } $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 $newsid The new survey id - the group will always be added after the last group in the survey */ function XMLImportGroup($sFullFilepath, $newsid) { global $connect, $dbprefix, $clang; $aLanguagesSupported = array(); // this array will keep all the languages supported for the survey $sBaseLanguage = GetBaseLanguageFromSurveyID($newsid); $aLanguagesSupported[]=$sBaseLanguage; // adds the base language to the list of supported languages $aLanguagesSupported=array_merge($aLanguagesSupported,GetAdditionalLanguagesFromSurveyID($newsid)); $xml = @simplexml_load_file($sFullFilepath); if ($xml==false || $xml->LimeSurveyDocType!='Group') safe_die('This is not a valid LimeSurvey group structure XML file.'); $dbversion = (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; } // 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 =================================================================================== $tablename=$dbprefix.'groups'; $newgrouporder=$connect->GetOne("SELECT MAX(group_order) AS maxqo FROM ".db_table_name('groups')." WHERE sid=$newsid"); if (is_null($newgrouporder)) { $newgrouporder=0; } else { $newgrouporder++; } foreach ($xml->groups->rows->row as $row) { $insertdata=array(); foreach ($row as $key=>$value) { $insertdata[(string)$key]=(string)$value; } $oldsid=$insertdata['sid']; $insertdata['sid']=$newsid; $insertdata['group_order']=$newgrouporder; $oldgid=$insertdata['gid']; unset($insertdata['gid']); // save the old qid // now translate any links $insertdata['group_name']=translink('survey', $oldsid, $newsid, $insertdata['group_name']); $insertdata['description']=translink('survey', $oldsid, $newsid, $insertdata['description']); // Insert the new question if (isset($aGIDReplacements[$oldgid])) { $insertdata['gid']=$aGIDReplacements[$oldgid]; db_switchIDInsert('groups',true); } $query=$connect->GetInsertSQL($tablename,$insertdata); $result = $connect->Execute($query) or safe_die ($clang->gT("Error").": Failed to insert data<br />{$query}<br />\n".$connect->ErrorMsg()); $results['groups']++; if (!isset($aGIDReplacements[$oldgid])) { $newgid=$connect->Insert_ID($tablename,"gid"); // save this for later $aGIDReplacements[$oldgid]=$newgid; // add old and new qid to the mapping array } else { db_switchIDInsert('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) $tablename=$dbprefix.'questions'; $results['questions']=0; foreach ($xml->questions->rows->row as $row) { $insertdata=array(); foreach ($row as $key=>$value) { $insertdata[(string)$key]=(string)$value; } $oldsid=$insertdata['sid']; $insertdata['sid']=$newsid; 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']=translink('survey', $oldsid, $newsid, $insertdata['title']); $insertdata['question']=translink('survey', $oldsid, $newsid, $insertdata['question']); $insertdata['help']=translink('survey', $oldsid, $newsid, $insertdata['help']); // Insert the new question if (isset($aQIDReplacements[$oldqid])) { $insertdata['qid']=$aQIDReplacements[$oldqid]; db_switchIDInsert('questions',true); } $query=$connect->GetInsertSQL($tablename,$insertdata); $result = $connect->Execute($query) or safe_die ($clang->gT("Error").": Failed to insert data<br />{$query}<br />\n".$connect->ErrorMsg()); if (!isset($aQIDReplacements[$oldqid])) { $newqid=$connect->Insert_ID($tablename,"qid"); // save this for later $aQIDReplacements[$oldqid]=$newqid; // add old and new qid to the mapping array $results['questions']++; } else { db_switchIDInsert('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; } $insertdata['sid']=$newsid; 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 $insertdata['parent_qid']=$aQIDReplacements[(int)$insertdata['parent_qid']]; // remap the parent_qid // now translate any links $insertdata['title']=translink('survey', $oldsid, $newsid, $insertdata['title']); $insertdata['question']=translink('survey', $oldsid, $newsid, $insertdata['question']); $insertdata['help']=translink('survey', $oldsid, $newsid, $insertdata['help']); if (isset($aQIDReplacements[$oldsqid])){ $insertdata['qid']=$aQIDReplacements[$oldsqid]; db_switchIDInsert('questions',true); } $query=$connect->GetInsertSQL($tablename,$insertdata); $result = $connect->Execute($query) or safe_die ($clang->gT("Error").": Failed to insert data<br />{$query}<br />\n".$connect->ErrorMsg()); $newsqid=$connect->Insert_ID($tablename,"qid"); // save this for later if (!isset($insertdata['qid'])) { $aQIDReplacements[$oldsqid]=$newsqid; // add old and new qid to the mapping array } else { db_switchIDInsert('questions',false); } $results['subquestions']++; } } // Import answers -------------------------------------------------------------- if(isset($xml->answers)) { $tablename=$dbprefix.'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 $query=$connect->GetInsertSQL($tablename,$insertdata); $result=$connect->Execute($query) or safe_die ($clang->gT("Error").": Failed to insert data<br />{$query}<br />\n".$connect->ErrorMsg()); $results['answers']++; } } // Import questionattributes -------------------------------------------------------------- if(isset($xml->question_attributes)) { $tablename=$dbprefix.'question_attributes'; 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 // now translate any links $query=$connect->GetInsertSQL($tablename,$insertdata); $result=$connect->Execute($query) or safe_die ($clang->gT("Error").": Failed to insert data<br />{$query}<br />\n".$connect->ErrorMsg()); $results['question_attributes']++; } } // Import defaultvalues -------------------------------------------------------------- if(isset($xml->defaultvalues)) { $tablename=$dbprefix.'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']=$aQIDReplacements[(int)$insertdata['sqid']]; // remap the subqeustion id // now translate any links $query=$connect->GetInsertSQL($tablename,$insertdata); $result=$connect->Execute($query) or safe_die ($clang->gT("Error").": Failed to insert data<br />\$query<br />\n".$connect->ErrorMsg()); $results['defaultvalues']++; } } // Import conditions -------------------------------------------------------------- if(isset($xml->conditions)) { $tablename=$dbprefix.'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 = '+'.$newsid . "X" . $newgid . "X" . $insertdata["cqid"] .substr($oldqidanscode,strlen($oldqid)); } else { $newcfieldname = $newsid . "X" . $newgid . "X" . $insertdata["cqid"] .substr($oldqidanscode,strlen($oldqid)); } $insertdata["cfieldname"] = $newcfieldname; if (trim($insertdata["method"])=='') { $insertdata["method"]='=='; } // now translate any links $query=$connect->GetInsertSQL($tablename,$insertdata); $result=$connect->Execute($query) or safe_die ($clang->gT("Error").": Failed to insert data<br />\$query<br />\n".$connect->ErrorMsg()); $results['conditions']++; } } $results['newgid']=$newgid; $results['labelsets']=0; $results['labels']=0; return $results; } | ||||
Bug heat | 4 | ||||
Complete LimeSurvey version number (& build) | 9459 | ||||
I will donate to the project if issue is resolved | No | ||||
Browser | any | ||||
Database type & version | MSSQL SERVER 2005 (mssqlnative) | ||||
Server OS (if known) | Windows server 2003 | ||||
Webserver software & version (if known) | IIS6 | ||||
PHP Version | 5.3.3 | ||||
Just thought it would be useful to indicate the time allowed for a php script to run in my config. Below is an exceirpt of my php.ini limits + IIS timeout=600 sec ;;;;;;;;;;;;;;;;;;; ; Maximum execution time of each script, in seconds ; Maximum amount of time each script may spend parsing request data. It's a good ; Maximum input variable nesting level ; Maximum amount of memory a script may consume (128MB) |
|
The problem is the export, not the import. |
|
Thanks for the first patch. It however still does not work when re-importing. The message I get is "This is not a valid LimeSurvey survey structure XML file." 1- I ran your original patch and got a mssql error message in the lss file. I changed line 122 of the export_structure_xml.php to (I'm indeed using the mssqlnative driver.) 2- I retested with the change and got the attached lss file called lime_survey_95278_2.lss 3- Re-importing still gives a "This is not a valid LimeSurvey survey structure XML file." |
|
New file attached. Please test. |
|
Excellent, it now works, many thanks! I have attached the produced lss file for your reference. -> I've noticed that the same issue exists with LSG files (i.e. exporting a group also gives similar issues) : I have attached the lsg file of the "questionnaire" group extracted from the exact same survey. You'll see that the file is 2.5Mb while the survey file is 458kb. |
|
Thank you. I will have a look at that, too. It is basically the same issue so we can continue here. |
|
Added two files for exporting question groups and questions. Please test and let me know. |
|
GROUP LSG FILEI noticed I cannot really test the re-import of an exported lsg file with the patched files attached because I get the following error SQL messages when trying to import the exported group: Error: Failed to insert data Error: Failed to insert data I have nevertheless included the newly exported lsg file as an attachment. QUESTION LSQ FILEWhen re-importing the LSQ , I obtain the message "This is not a valid LimeSurvey question structure XML file." |
|
Thank you. Should be fine now. |
|
Released in latest 1.90+ version. |
|
Date Modified | Username | Field | Change |
---|---|---|---|
2010-11-14 19:06 |
|
New Issue | |
2010-11-14 19:06 |
|
File Added: limesurvey_survey_95278.lss | |
2010-11-14 19:34 |
|
Note Added: 13523 | |
2010-11-15 21:04 | c_schmitz | Assigned To | => c_schmitz |
2010-11-15 21:04 | c_schmitz | Status | new => assigned |
2010-11-15 21:16 | c_schmitz | Note Added: 13529 | |
2010-11-15 21:16 | c_schmitz | Status | assigned => feedback |
2010-11-15 21:17 | c_schmitz | File Added: export_structure_xml.php | |
2010-11-15 21:19 | c_schmitz | File Deleted: export_structure_xml.php | |
2010-11-15 21:19 | c_schmitz | File Added: export_structure_xml.php | |
2010-11-16 10:15 |
|
Note Added: 13536 | |
2010-11-16 10:15 |
|
Status | feedback => assigned |
2010-11-16 10:15 |
|
File Added: limesurvey_survey_95278_2.lss | |
2010-11-16 18:10 | c_schmitz | File Deleted: export_structure_xml.php | |
2010-11-16 18:10 | c_schmitz | File Added: export_structure_xml.php | |
2010-11-16 18:10 | c_schmitz | Note Added: 13537 | |
2010-11-16 18:15 | c_schmitz | Status | assigned => feedback |
2010-11-16 20:25 | c_schmitz | File Deleted: limesurvey_survey_95278.lss | |
2010-11-17 11:53 |
|
Note Added: 13547 | |
2010-11-17 11:53 |
|
Status | feedback => assigned |
2010-11-17 11:53 |
|
File Added: limesurvey_survey_95278_3.lss | |
2010-11-17 11:53 |
|
File Added: limesurvey_group_338.lsg | |
2010-11-18 02:26 | c_schmitz | Note Added: 13550 | |
2010-11-18 02:27 | c_schmitz | Note Edited: 13550 | |
2010-11-18 03:06 | c_schmitz | File Added: dumpgroup.php | |
2010-11-18 03:06 | c_schmitz | File Added: dumpquestion.php | |
2010-11-18 03:07 | c_schmitz | File Deleted: limesurvey_group_338.lsg | |
2010-11-18 03:07 | c_schmitz | File Deleted: limesurvey_survey_95278_2.lss | |
2010-11-18 03:07 | c_schmitz | File Deleted: limesurvey_survey_95278_3.lss | |
2010-11-18 03:07 | c_schmitz | Note Added: 13553 | |
2010-11-18 03:07 | c_schmitz | Status | assigned => feedback |
2010-11-18 12:29 |
|
Note Added: 13554 | |
2010-11-18 12:29 |
|
Status | feedback => assigned |
2010-11-18 12:29 |
|
File Added: limesurvey_question_7061.lsq | |
2010-11-18 12:29 |
|
File Added: limesurvey_group_338.lsg | |
2010-11-18 23:46 | c_schmitz | File Deleted: dumpgroup.php | |
2010-11-18 23:46 | c_schmitz | File Deleted: dumpquestion.php | |
2010-11-18 23:47 | c_schmitz | File Added: dumpquestion.php | |
2010-11-18 23:47 | c_schmitz | File Added: importgroup.php | |
2010-11-18 23:48 | c_schmitz | Note Added: 13557 | |
2010-11-18 23:48 | c_schmitz | Status | assigned => resolved |
2010-11-18 23:48 | c_schmitz | Resolution | open => fixed |
2010-12-07 14:14 | c_schmitz | Note Added: 13720 | |
2010-12-07 14:14 | c_schmitz | Status | resolved => closed |