/**
* 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');
    $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'] = 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(gT("This survey setting has not been imported: %s => %s"), $key, $value);
        }
        $iNewSID = $results['newsid'] = Survey::model()->insertNewSurvey($insertdata) or safeDie(gT("Error") . ": Failed to insert data [1]<br />");
        $results['surveys']++;
    }
    // Import survey languagesettings table ===================================================================================
    foreach ($xml->surveys_languagesettings->rows->row as $row) {
        $insertdata = array();
        foreach ($row as $key => $value) {
            $insertdata[(string) $key] = (string) $value;
        }
        if (!in_array($insertdata['surveyls_language'], $aLanguagesSupported)) {
            continue;
        }
        // Assign new survey ID
        $insertdata['surveyls_survey_id'] = $iNewSID;
        // Assign new survey name (if a copy)
        if ($sNewSurveyName != NULL) {
            $insertdata['surveyls_title'] = $sNewSurveyName;
        }
        if ($bTranslateInsertansTags) {
            $insertdata['surveyls_title'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_title']);
            if (isset($insertdata['surveyls_description'])) {
                $insertdata['surveyls_description'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_description']);
            }
            if (isset($insertdata['surveyls_welcometext'])) {
                $insertdata['surveyls_welcometext'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_welcometext']);
            }
            if (isset($insertdata['surveyls_urldescription'])) {
                $insertdata['surveyls_urldescription'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_urldescription']);
            }
            if (isset($insertdata['surveyls_email_invite'])) {
                $insertdata['surveyls_email_invite'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_invite']);
            }
            if (isset($insertdata['surveyls_email_remind'])) {
                $insertdata['surveyls_email_remind'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_remind']);
            }
            if (isset($insertdata['surveyls_email_register'])) {
                $insertdata['surveyls_email_register'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_register']);
            }
            if (isset($insertdata['surveyls_email_confirm'])) {
                $insertdata['surveyls_email_confirm'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_confirm']);
            }
        }
        if (isset($insertdata['surveyls_attributecaptions']) && substr($insertdata['surveyls_attributecaptions'], 0, 1) != '{') {
            unset($insertdata['surveyls_attributecaptions']);
        }
        $result = SurveyLanguageSetting::model()->insertNewSurvey($insertdata) or safeDie(gT("Error") . ": Failed to insert data [2]<br />");
    }
    // Import groups table ===================================================================================
    if (isset($xml->groups->rows->row)) {
        foreach ($xml->groups->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            if (!in_array($insertdata['language'], $aLanguagesSupported)) {
                continue;
            }
            $iOldSID = $insertdata['sid'];
            $insertdata['sid'] = $iNewSID;
            $oldgid = $insertdata['gid'];
            unset($insertdata['gid']);
            // save the old qid
            // now translate any links
            if ($bTranslateInsertansTags) {
                $insertdata['group_name'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['group_name']);
                $insertdata['description'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['description']);
            }
            // Insert the new group
            if (isset($aGIDReplacements[$oldgid])) {
                switchMSSQLIdentityInsert('groups', true);
                $insertdata['gid'] = $aGIDReplacements[$oldgid];
            }
            $newgid = QuestionGroup::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data [3]<br />");
            $results['groups']++;
            if (!isset($aGIDReplacements[$oldgid])) {
                $aGIDReplacements[$oldgid] = $newgid;
                // add old and new qid to the mapping array
            } else {
                switchMSSQLIdentityInsert('groups', false);
            }
        }
    }
    // Import questions table ===================================================================================
    // We have to run the question table data two times - first to find all main questions
    // then for subquestions (because we need to determine the new qids for the main questions first)
    if (isset($xml->questions)) {
        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(gT("Error") . ": Failed to resolve question code problems after 10 attempts.<br />");
                }
            }
            if (!$oQuestion->save()) {
                // safeDie(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(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(gT("Error") . ": Failed to resolve question code problems after 10 attempts.<br />");
                }
            }
            if (!$question->save()) {
                // safeDie(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(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 = \ls\helpers\questionHelper::getAttributesDefinitions();
        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[(int) $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(gT("Error") . ": Failed to insert data[7]<br />");
                }
            } else {
                $result = QuestionAttribute::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data[8]<br />");
            }
            $results['question_attributes']++;
        }
    }
    // Import defaultvalues ------------------------------------------------------
    if (isset($xml->defaultvalues)) {
        $results['defaultvalues'] = 0;
        foreach ($xml->defaultvalues->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            $insertdata['qid'] = $aQIDReplacements[(int) $insertdata['qid']];
            // remap the qid
            if (isset($aQIDReplacements[(int) $insertdata['sqid']])) {
                $insertdata['sqid'] = $aQIDReplacements[(int) $insertdata['sqid']];
            }
            // remap the subquestion id
            if ($insertdata) {
                XSSFilterArray($insertdata);
            }
            // now translate any links
            $result = DefaultValue::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data[9]<br />");
            $results['defaultvalues']++;
        }
    }
    $aOldNewFieldmap = reverseTranslateFieldNames($iOldSID, $iNewSID, $aGIDReplacements, $aQIDReplacements);
    // Import conditions ---------------------------------------------------------
    if (isset($xml->conditions)) {
        $results['conditions'] = 0;
        foreach ($xml->conditions->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            // replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this condition is orphan -> error, skip this record)
            if (isset($aQIDReplacements[$insertdata['qid']])) {
                $insertdata['qid'] = $aQIDReplacements[$insertdata['qid']];
                // remap the qid
            } else {
                continue;
            }
            // a problem with this answer record -> don't consider
            if ($insertdata['cqid'] != 0) {
                if (isset($aQIDReplacements[$insertdata['cqid']])) {
                    $oldcqid = $insertdata['cqid'];
                    //Save for cfield transformation
                    $insertdata['cqid'] = $aQIDReplacements[$insertdata['cqid']];
                    // remap the qid
                } else {
                    continue;
                }
                // a problem with this answer record -> don't consider
                list($oldcsid, $oldcgid, $oldqidanscode) = explode("X", $insertdata["cfieldname"], 3);
                // replace the gid for the new one in the cfieldname(if there is no new gid in the $aGIDReplacements array it means that this condition is orphan -> error, skip this record)
                if (!isset($aGIDReplacements[$oldcgid])) {
                    continue;
                }
            }
            unset($insertdata["cid"]);
            // recreate the cfieldname with the new IDs
            if ($insertdata['cqid'] != 0) {
                if (preg_match("/^\\+/", $oldcsid)) {
                    $newcfieldname = '+' . $iNewSID . "X" . $aGIDReplacements[$oldcgid] . "X" . $insertdata["cqid"] . substr($oldqidanscode, strlen($oldcqid));
                } else {
                    $newcfieldname = $iNewSID . "X" . $aGIDReplacements[$oldcgid] . "X" . $insertdata["cqid"] . substr($oldqidanscode, strlen($oldcqid));
                }
            } else {
                // The cfieldname is a not a previous question cfield but a {XXXX} replacement field
                $newcfieldname = $insertdata["cfieldname"];
            }
            $insertdata["cfieldname"] = $newcfieldname;
            if (trim($insertdata["method"]) == '') {
                $insertdata["method"] = '==';
            }
            // Now process the value and replace @sgqa@ codes
            if (preg_match("/^@(.*)@\$/", $insertdata["value"], $cfieldnameInCondValue)) {
                if (isset($aOldNewFieldmap[$cfieldnameInCondValue[1]])) {
                    $newvalue = '@' . $aOldNewFieldmap[$cfieldnameInCondValue[1]] . '@';
                    $insertdata["value"] = $newvalue;
                }
            }
            // now translate any links
            $result = Condition::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data[10]<br />");
            $results['conditions']++;
        }
    }
    // TMSW Condition->Relevance:  Call  LEM->ConvertConditionsToRelevance
    // Import assessments --------------------------------------------------------
    if (isset($xml->assessments)) {
        foreach ($xml->assessments->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            if ($insertdata['gid'] > 0) {
                $insertdata['gid'] = $aGIDReplacements[(int) $insertdata['gid']];
                // remap the qid
            }
            $insertdata['sid'] = $iNewSID;
            // remap the survey id
            unset($insertdata['id']);
            // now translate any links
            $result = Assessment::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data[11]<br />");
            $results['assessments']++;
        }
    }
    // Import quota --------------------------------------------------------------
    if (isset($xml->quota)) {
        foreach ($xml->quota->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            $insertdata['sid'] = $iNewSID;
            // remap the survey id
            $oldid = $insertdata['id'];
            unset($insertdata['id']);
            // now translate any links
            $result = Quota::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data[12]<br />");
            $aQuotaReplacements[$oldid] = getLastInsertID('{{quota}}');
            $results['quota']++;
        }
    }
    // Import quota_members ------------------------------------------------------
    if (isset($xml->quota_members)) {
        foreach ($xml->quota_members->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            $insertdata['sid'] = $iNewSID;
            // remap the survey id
            $insertdata['qid'] = $aQIDReplacements[(int) $insertdata['qid']];
            // remap the qid
            $insertdata['quota_id'] = $aQuotaReplacements[(int) $insertdata['quota_id']];
            // remap the qid
            unset($insertdata['id']);
            // now translate any links
            $result = QuotaMember::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data[13]<br />");
            $results['quotamembers']++;
        }
    }
    // Import quota_languagesettings----------------------------------------------
    if (isset($xml->quota_languagesettings)) {
        foreach ($xml->quota_languagesettings->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            $insertdata['quotals_quota_id'] = $aQuotaReplacements[(int) $insertdata['quotals_quota_id']];
            // remap the qid
            unset($insertdata['quotals_id']);
            $result = QuotaLanguageSetting::model()->insertRecords($insertdata) or safeDie(gT("Error") . ": Failed to insert data<br />");
            $results['quotals']++;
        }
    }
    // Import survey_url_parameters ----------------------------------------------
    if (isset($xml->survey_url_parameters)) {
        foreach ($xml->survey_url_parameters->rows->row as $row) {
            $insertdata = array();
            foreach ($row as $key => $value) {
                $insertdata[(string) $key] = (string) $value;
            }
            $insertdata['sid'] = $iNewSID;
            // remap the survey id
            if (isset($insertdata['targetsqid']) && $insertdata['targetsqid'] != '') {
                $insertdata['targetsqid'] = $aQIDReplacements[(int) $insertdata['targetsqid']];
                // remap the qid
            }
            if (isset($insertdata['targetqid']) && $insertdata['targetqid'] != '') {
                $insertdata['targetqid'] = $aQIDReplacements[(int) $insertdata['targetqid']];
                // remap the qid
            }
            unset($insertdata['id']);
            $result = SurveyURLParameter::model()->insertRecord($insertdata) or safeDie(gT("Error") . ": Failed to insert data[14]<br />");
            $results['survey_url_parameters']++;
        }
    }
    // Set survey rights
    Permission::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'], $iNewSID);
    $aOldNewFieldmap = reverseTranslateFieldNames($iOldSID, $iNewSID, $aGIDReplacements, $aQIDReplacements);
    $results['FieldReMap'] = $aOldNewFieldmap;
    LimeExpressionManager::SetSurveyId($iNewSID);
    translateInsertansTags($iNewSID, $iOldSID, $aOldNewFieldmap);
    replaceExpressionCodes($iNewSID, $aQuestionCodeReplacements);
    if (count($aQuestionCodeReplacements)) {
        array_unshift($results['importwarnings'], "<span class='warningtitle'>" . gT('Attention: Several question codes were updated. Please check these carefully as the update  may not be perfect with customized expressions.') . '</span)>');
    }
    LimeExpressionManager::RevertUpgradeConditionsToRelevance($iNewSID);
    LimeExpressionManager::UpgradeConditionsToRelevance($iNewSID);
    return $results;
}
 /**
  * TSV survey definition in format readable by TSVSurveyImport
  * one line each per group, question, sub-question, and answer
  * does not use SGQA naming at all.
  * @param type $sid
  * @return type
  */
 public static function &TSVSurveyExport($sid)
 {
     $aBaseFields = array('class', 'type/scale', 'name', 'relevance', 'text', 'help', 'language', 'validation', 'mandatory', 'other', 'default', 'same_default');
     // Advanced question attributes : @todo get used question attribute by question in survey ?
     $aQuestionAttributes = array_keys(\ls\helpers\questionHelper::getAttributesDefinitions());
     sort($aQuestionAttributes);
     $fields = array_merge($aBaseFields, $aQuestionAttributes);
     $rows = array();
     $primarylang = 'en';
     $otherlangs = '';
     $langs = array();
     // Export survey-level information
     $query = "select * from {{surveys}} where sid = " . $sid;
     $data = dbExecuteAssoc($query);
     foreach ($data->readAll() as $r) {
         foreach ($r as $key => $value) {
             if ($value != '') {
                 $row['class'] = 'S';
                 $row['name'] = $key;
                 $row['text'] = $value;
                 $rows[] = $row;
             }
             if ($key == 'language') {
                 $primarylang = $value;
             }
             if ($key == 'additional_languages') {
                 $otherlangs = $value;
             }
         }
     }
     $langs = explode(' ', $primarylang . ' ' . $otherlangs);
     $langs = array_unique($langs);
     // Export survey language settings
     $query = "select * from {{surveys_languagesettings}} where surveyls_survey_id = " . $sid;
     $data = dbExecuteAssoc($query);
     foreach ($data->readAll() as $r) {
         $_lang = $r['surveyls_language'];
         foreach ($r as $key => $value) {
             if ($value != '' && $key != 'surveyls_language' && $key != 'surveyls_survey_id') {
                 $row['class'] = 'SL';
                 $row['name'] = $key;
                 $row['text'] = $value;
                 $row['language'] = $_lang;
                 $rows[] = $row;
             }
         }
     }
     $surveyinfo = getSurveyInfo($sid);
     $assessments = false;
     if (isset($surveyinfo['assessments']) && $surveyinfo['assessments'] == 'Y') {
         $assessments = true;
     }
     foreach ($langs as $lang) {
         if (trim($lang) == '') {
             continue;
         }
         SetSurveyLanguage($sid, $lang);
         LimeExpressionManager::StartSurvey($sid, 'survey', array('sgqaNaming' => 'N', 'assessments' => $assessments), true);
         $moveResult = LimeExpressionManager::NavigateForwards();
         $LEM =& LimeExpressionManager::singleton();
         if (is_null($moveResult) || is_null($LEM->currentQset) || count($LEM->currentQset) == 0) {
             continue;
         }
         $_gseq = -1;
         foreach ($LEM->currentQset as $q) {
             $gseq = $q['info']['gseq'];
             $gid = $q['info']['gid'];
             $qid = $q['info']['qid'];
             //////
             // SHOW GROUP-LEVEL INFO
             //////
             if ($gseq != $_gseq) {
                 $_gseq = $gseq;
                 $ginfo = $LEM->gseq2info[$gseq];
                 // if relevance equation is using SGQA coding, convert to qcoding
                 $grelevance = $ginfo['grelevance'] == '' ? 1 : $ginfo['grelevance'];
                 $LEM->em->ProcessBooleanExpression($grelevance, $gseq, 0);
                 // $qseq
                 $grelevance = trim(strip_tags($LEM->em->GetPrettyPrintString()));
                 $gtext = trim($ginfo['description']) == '' ? '' : $ginfo['description'];
                 $row = array();
                 $row['class'] = 'G';
                 //create a group code to allow proper importing of multi-lang survey TSVs
                 $row['type/scale'] = 'G' . $gseq;
                 $row['name'] = $ginfo['group_name'];
                 $row['relevance'] = $grelevance;
                 $row['text'] = $gtext;
                 $row['language'] = $lang;
                 $row['random_group'] = $ginfo['randomization_group'];
                 $rows[] = $row;
             }
             //////
             // SHOW QUESTION-LEVEL INFO
             //////
             $row = array();
             $mandatory = $q['info']['mandatory'] == 'Y' ? 'Y' : '';
             $type = $q['info']['type'];
             $sgqas = explode('|', $q['sgqa']);
             if (count($sgqas) == 1 && !is_null($q['info']['default'])) {
                 $default = $q['info']['default'];
             } else {
                 $default = '';
             }
             $qtext = $q['info']['qtext'] != '' ? $q['info']['qtext'] : '';
             $help = $q['info']['help'] != '' ? $q['info']['help'] : '';
             //////
             // SHOW QUESTION ATTRIBUTES THAT ARE PROCESSED BY EM
             //////
             if (isset($LEM->qattr[$qid]) && count($LEM->qattr[$qid]) > 0) {
                 foreach ($LEM->qattr[$qid] as $key => $value) {
                     if (is_null($value) || trim($value) == '') {
                         continue;
                     }
                     switch ($key) {
                         default:
                         case 'exclude_all_others':
                         case 'exclude_all_others_auto':
                         case 'hidden':
                             if ($value == false || $value == '0') {
                                 $value = NULL;
                                 // so can skip this one - just using continue here doesn't work.
                             }
                             break;
                         case 'relevance':
                             $value = NULL;
                             // means an outdate database structure
                             break;
                     }
                     if (is_null($value) || trim($value) == '') {
                         continue;
                         // since continuing from within a switch statement doesn't work
                     }
                     $row[$key] = $value;
                 }
             }
             // if relevance equation is using SGQA coding, convert to qcoding
             $relevanceEqn = $q['info']['relevance'] == '' ? 1 : $q['info']['relevance'];
             $LEM->em->ProcessBooleanExpression($relevanceEqn, $gseq, $q['info']['qseq']);
             // $qseq
             $relevanceEqn = trim(preg_replace("#</(span|a)>#i", "", preg_replace("#<(span|a)[^>]+\\>#i", "", $LEM->em->GetPrettyPrintString())));
             // Relevance can not have HTML : only span and a are returned from GetPrettyPrintString
             $rootVarName = $q['info']['rootVarName'];
             $preg = '';
             if (isset($LEM->q2subqInfo[$q['info']['qid']]['preg'])) {
                 $preg = $LEM->q2subqInfo[$q['info']['qid']]['preg'];
                 if (is_null($preg)) {
                     $preg = '';
                 }
             }
             $row['class'] = 'Q';
             $row['type/scale'] = $type;
             $row['name'] = $rootVarName;
             $row['relevance'] = $relevanceEqn;
             $row['text'] = $qtext;
             $row['help'] = $help;
             $row['language'] = $lang;
             $row['validation'] = $preg;
             $row['mandatory'] = $mandatory;
             $row['other'] = $q['info']['other'];
             $row['default'] = $default;
             $row['same_default'] = 1;
             // TODO - need this: $q['info']['same_default'];
             $rows[] = $row;
             //////
             // SHOW ALL SUB-QUESTIONS
             //////
             $sawThis = array();
             // array of rowdivids already seen so only show them once
             foreach ($sgqas as $sgqa) {
                 if ($LEM->knownVars[$sgqa]['qcode'] == $rootVarName) {
                     continue;
                     // so don't show the main question as a sub-question too
                 }
                 $rowdivid = $sgqa;
                 $varName = $LEM->knownVars[$sgqa]['qcode'];
                 // if SQrelevance equation is using SGQA coding, convert to qcoding
                 $SQrelevance = $LEM->knownVars[$sgqa]['SQrelevance'] == '' ? 1 : $LEM->knownVars[$sgqa]['SQrelevance'];
                 $LEM->em->ProcessBooleanExpression($SQrelevance, $gseq, $q['info']['qseq']);
                 $SQrelevance = trim(preg_replace("#</(span|a)>#i", "", preg_replace("#<(span|a)[^>]+\\>#i", "", $LEM->em->GetPrettyPrintString())));
                 // Relevance can not have HTML : only span and a are returned from GetPrettyPrintString
                 switch ($q['info']['type']) {
                     case '1':
                         if (preg_match('/#1$/', $sgqa)) {
                             $rowdivid = NULL;
                             // so that doesn't show same message for second scale
                         } else {
                             $rowdivid = substr($sgqa, 0, -2);
                             // strip suffix
                             $varName = substr($LEM->knownVars[$sgqa]['qcode'], 0, -2);
                         }
                         break;
                     case 'P':
                         if (preg_match('/comment$/', $sgqa)) {
                             $rowdivid = NULL;
                         }
                         break;
                     case ':':
                     case ';':
                         $_rowdivid = $LEM->knownVars[$sgqa]['rowdivid'];
                         if (isset($sawThis[$qid . '~' . $_rowdivid])) {
                             $rowdivid = NULL;
                             // so don't show again
                         } else {
                             $sawThis[$qid . '~' . $_rowdivid] = true;
                             $rowdivid = $_rowdivid;
                             $sgqa_len = strlen($sid . 'X' . $gid . 'X' . $qid);
                             $varName = $rootVarName . '_' . substr($_rowdivid, $sgqa_len);
                         }
                         break;
                 }
                 if (is_null($rowdivid)) {
                     continue;
                 }
                 $sgqaInfo = $LEM->knownVars[$sgqa];
                 $subqText = $sgqaInfo['subqtext'];
                 if (isset($sgqaInfo['default'])) {
                     $default = $sgqaInfo['default'];
                 } else {
                     $default = '';
                 }
                 $row = array();
                 $row['class'] = 'SQ';
                 $row['type/scale'] = 0;
                 $row['name'] = substr($varName, strlen($rootVarName) + 1);
                 $row['relevance'] = $SQrelevance;
                 $row['text'] = $subqText;
                 $row['language'] = $lang;
                 $row['default'] = $default;
                 $rows[] = $row;
             }
             //////
             // SHOW ANSWER OPTIONS FOR ENUMERATED LISTS, AND FOR MULTIFLEXI
             //////
             if (isset($LEM->qans[$qid]) || isset($LEM->multiflexiAnswers[$qid])) {
                 $_scale = -1;
                 if (isset($LEM->multiflexiAnswers[$qid])) {
                     $ansList = $LEM->multiflexiAnswers[$qid];
                 } else {
                     $ansList = $LEM->qans[$qid];
                 }
                 foreach ($ansList as $ans => $value) {
                     $ansInfo = explode('~', $ans);
                     $valParts = explode('|', $value);
                     $valInfo[0] = array_shift($valParts);
                     $valInfo[1] = implode('|', $valParts);
                     if ($_scale != $ansInfo[0]) {
                         $_scale = $ansInfo[0];
                     }
                     $row = array();
                     if ($type == ':' || $type == ';') {
                         $row['class'] = 'SQ';
                     } else {
                         $row['class'] = 'A';
                     }
                     $row['type/scale'] = $_scale;
                     $row['name'] = $ansInfo[1];
                     $row['relevance'] = $assessments == true ? $valInfo[0] : '';
                     $row['text'] = $valInfo[1];
                     $row['language'] = $lang;
                     $rows[] = $row;
                 }
             }
         }
     }
     // Now generate the array out output data
     $out = array();
     $out[] = $fields;
     foreach ($rows as $row) {
         $tsv = array();
         foreach ($fields as $field) {
             $val = isset($row[$field]) ? $row[$field] : '';
             $tsv[] = $val;
         }
         $out[] = $tsv;
     }
     return $out;
 }