/** * 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[(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; $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; }