<?php

use LimeSurvey\Models\Services\CopySurveyOptions;
use LimeSurvey\Models\Services\CopySurveyResources;
use LimeSurvey\Models\Services\FileUploadService;
use LimeSurvey\Models\Services\FilterImportedResources;
use LimeSurvey\Models\Services\GroupHelper;
use LimeSurvey\Models\Services\SurveyAccessModeService;
use LimeSurvey\Models\Services\SurveyDetailService;

/**
 * Class SurveyAdministrationController
 */
class SurveyAdministrationController extends LSBaseController
{
    /**
     * It's import to have the accessRules set (security issue).
     * Only logged in users should have access to actions. All other permissions
     * should be checked in the action itself.
     *
     * @return array
     */
    public function accessRules()
    {
        return [
            [
                'allow',
                'actions' => [],
                'users' => ['*'], //everybody
            ],
            [
                'allow',
                'actions' => [
                    'view',
                    'delete',
                    'index',
                    'insert',
                    'listsurveys',
                    'newSurvey',
                    'regenerateQuestionCode',
                    'renderItemsSelected',
                    'applythemeoptions',
                    'changeMultipleSurveyGroup',
                    'changeMultipleTheme',
                    'deleteMultiple',
                    'fakebrowser',
                    'getAjaxMenuArray',
                    'getAjaxQuestionGroupArray',
                    'getCurrentEditorValues',
                    'getDataSecTextSettings',
                    'getDateFormatOptions',
                    'updateAccessMode',
                    ''
                ],
                'users' => ['@'], //only login users
            ],
            ['deny'], //always deny all actions not mentioned above
        ];
    }

    /**
     * Set filters for all actions
     * @return string[]
     */
    public function filters()
    {
        return [
            'postOnly + copy'
        ];
    }

    /**
     * SurveyAdministrationController constructor.
     * @param $id
     * @param null $module
     * @throws CException
     */
    public function __construct($id, $module = null)
    {
        Yii::app()->request->updateNavigationStack();
        // Make sure viewHelper can be autoloaded
        Yii::import('application.helpers.viewHelper');
        parent::__construct($id, $module);
    }

    /**
     * This part comes from renderWrappedTemplate
     *
     * @param string $view
     * @return bool
     */
    protected function beforeRender($view)
    {
        if (!empty($this->aData['surveyid'])) {
            $this->aData['oSurvey'] = $this->aData['oSurvey'] ?? Survey::model()->findByPk($this->aData['surveyid']);

            // Needed to evaluate EM expressions in question summary
            // See bug #11845
            LimeExpressionManager::SetSurveyId($this->aData['surveyid']);
            LimeExpressionManager::StartProcessingPage(false, true);

            $this->layout = 'layout_questioneditor';
        } else {
            $this->layout = 'main';
        }

        // Used in question editor (pjax).
        App()->getClientScript()->registerPackage('ace');
        App()->getClientScript()->registerPackage('jquery-ace');

        return parent::beforeRender($view);
    }

    /**
     * Load complete view of survey properties and actions specified by $iSurveyID
     *
     * @return void
     *
     * @access public
     * @throws CException
     */
    public function actionView()
    {
        $iSurveyID = $this->getSurveyIdFromGetRequest();

        if (!Permission::model()->hasSurveyPermission((int)$iSurveyID, 'survey', 'read')) {
            Yii::app()->user->setFlash('error', gT("No permission or survey does not exist."));
            $this->redirect(Yii::app()->request->urlReferrer);
        }

        $beforeSurveyAdminView = new PluginEvent('beforeSurveyAdminView');
        $beforeSurveyAdminView->set('surveyId', $iSurveyID);
        App()->getPluginManager()->dispatchEvent($beforeSurveyAdminView);

        // We load the panel packages for quick actions
        $iSurveyID = sanitize_int($iSurveyID);

        //todo: first check if survey is new and DO NOT try to access model attributes without isset-check ...


        $survey = Survey::model()->findByPk($iSurveyID);  //yii standard is overwritten here ...
        $baselang = $survey->language;

        $aData = array('aAdditionalLanguages' => $survey->additionalLanguages);

        // Reinit LEMlang and LEMsid: ensure LEMlang are set to default lang, surveyid are set to this survey ID
        // Ensure Last GetLastPrettyPrintExpression get info from this sid and default lang
        LimeExpressionManager::SetEMLanguage($baselang);
        LimeExpressionManager::SetSurveyId($iSurveyID);
        LimeExpressionManager::StartProcessingPage(false, true);

        //breadcrumb
        if (isset($survey->currentLanguageSettings) && isset($survey->currentLanguageSettings->surveyls_title)) {
            $aData['title_bar']['title'] =
                $survey->currentLanguageSettings->surveyls_title . " (" . gT("ID") . ":" . $iSurveyID . ")";
        } else {
            $aData['title_bar']['title'] = 'Unknown_language_title' . " (" . gT("ID") . ":" . $iSurveyID . ")";
        }
        //buttons in topbar
        $topbarData = TopbarConfiguration::getSurveyTopbarData($iSurveyID);
        $aData['topbar']['middleButtons'] = $this->renderPartial(
            'partial/topbar/surveyTopbarLeft_view',
            $topbarData,
            true
        );
        $aData['topbar']['rightButtons'] = $this->renderPartial(
            'partial/topbar/surveyTopbarRight_view',
            $topbarData,
            true
        );
        $aData['surveyid'] = $iSurveyID;
        $aData['sid'] = $iSurveyID; //frontend need this to render topbar for the view

        // Last survey visited
        SettingsUser::setUserSetting('last_survey', $iSurveyID);

        $aData['sidemenu']["survey_menu"] = true;

        // We get the last question visited by user for this survey
        // 2025-02-19 seem not used , we are inside survey
        $aData['showLastQuestion'] = false;
        $lastquestionID = SettingsUser::getUserSetting('last_question', $iSurveyID, 'Survey');
        if ($lastquestionID) {
            $question = Question::model()->findByPk(intval($lastquestionID));
            if ($question) {
                $survey = Survey::model()->findByPk($question->sid);
                $baselang = $survey->language;
                $aData['last_question_name'] = $question['title'];
                if (!empty($question->questionl10ns[$baselang]['question'])) {
                    $aData['last_question_name'] .= ' : ' . $question->questionl10ns[$baselang]['question'];
                }
                $aData['last_question_link'] = $this->createUrl(
                    "questionAdministration/view",
                    [
                        'surveyid' => $question->sid,
                        'gid' => $question->gid,
                        'qid' => $question->qid
                    ]
                );
            }
        }
        $aData['templateapiversion'] = Template::model()->getTemplateConfiguration(null, $iSurveyID)->getApiVersion();

        $user = User::model()->findByPk(App()->session['loginID']);
        $aData['owner'] = $user->attributes;

      //  if ((empty($aData['display']['menu_bars']['surveysummary']) || !is_string($aData['display']['menu_bars']['surveysummary'])) && !empty($aData['gid'])) {
        //    $aData['display']['menu_bars']['surveysummary'] = 'viewgroup';
       // }

        $surveyUrls = [];
        foreach ($survey->allLanguages as $language) {
            $surveyUrls[$language] = $survey->getSurveyUrl($language);
        }
        $aData['surveyUrls'] = $surveyUrls;

        $this->surveysummary($aData);

        // Display 'Overview' in Green Bar
     //   $aData['subaction'] = gT('Overview');
        $surveyActivationFeedback = Yii::app()->request->getParam('surveyActivationFeedback', null);
        $aData['surveyActivationFeedback'] = $surveyActivationFeedback;

        $this->aData = $aData;
        $this->render('sidebody');
    }

    /**
     * List Surveys.
     *
     * @return void
     */
    public function actionListsurveys()
    {
        Yii::app()->loadHelper('surveytranslator');
        $aData = array();
        $aData['issuperadmin'] = false;

        if (Permission::model()->hasGlobalPermission('superadmin', 'read')) {
            $aData['issuperadmin'] = true;
        }
        $aData['model'] = new Survey('search');
        $aData['groupModel'] = new SurveysGroups('search');
        $aData['topbar']['title'] = gT('Survey list');
        $aData['topbar']['backLink'] = App()->createUrl('dashboard/view');

        $aData['topbar']['middleButtons'] = $this->renderPartial('partial/topbarBtns/leftSideButtons', [], true);

        $this->aData = $aData;
        $this->render('listSurveys_view', $aData);
    }

    /**
     * Delete multiple survey
     *
     * @return void
     * @throws CException
     */
    public function actionDeleteMultiple()
    {
        $aSurveys = json_decode(Yii::app()->request->getPost('sItems', ''));
        $aResults = array();
        foreach ($aSurveys as $iSurveyID) {
            $iSurveyID = sanitize_int($iSurveyID);
            $oSurvey = Survey::model()->findByPk($iSurveyID);
            $aResults[$iSurveyID]['title'] = $oSurvey->correct_relation_defaultlanguage->surveyls_title;
            if (Permission::model()->hasSurveyPermission($iSurveyID, 'survey', 'delete')) {
                $aResults[$iSurveyID]['result'] = Survey::model()->deleteSurvey($iSurveyID);
            } else {
                $aResults[$iSurveyID]['result'] = false;
                $aResults[$iSurveyID]['error'] = gT("User does not have valid permissions");
            }
        }
        $this->renderPartial(
            'ext.admin.survey.ListSurveysWidget.views.massive_actions._action_results',
            array(
                'aResults' => $aResults,
                'successLabel' => gT('Deleted')
            )
        );
    }

    /**
     * Render selected items for massive action
     *
     * @return void
     */
    public function actionRenderItemsSelected()
    {
        $aSurveys = json_decode(Yii::app()->request->getPost('$oCheckedItems', ''));
        $aResults = [];
        $tableLabels = array(gT('Survey ID'), gT('Survey title'), gT('Status'));
        foreach ($aSurveys as $iSurveyID) {
            if (!is_numeric($iSurveyID)) {
                continue;
            }
            $oSurvey = Survey::model()->findByPk($iSurveyID);
            $aResults[$iSurveyID]['title'] = $oSurvey->correct_relation_defaultlanguage->surveyls_title;
            $aResults[$iSurveyID]['result'] = 'selected';
        }

        $this->renderPartial(
            'ext.admin.grid.MassiveActionsWidget.views._selected_items',
            array(
                'aResults' => $aResults,
                'successLabel' => gT('Selected'),
                'tableLabels' => $tableLabels
            )
        );
    }

    /**
     * Regeerates the question code
     * Automatically renumbers the "question codes" so that they follow
     * a methodical numbering method.
     *
     * @return void
     *
     */
    public function actionRegenerateQuestionCodes()
    {
        $iSurveyID = $this->getSurveyIdFromGetRequest();
        $sSubAction = Yii::app()->request->getParam('subaction');

        if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
            Yii::app()->setFlashMessage(gT("You do not have permission to access this page."), 'error');
            $this->redirect(array('surveyAdministration/view', 'surveyid' => $iSurveyID));
        }
        $oSurvey = Survey::model()->findByPk($iSurveyID);
        if ($oSurvey->isActive) {
            Yii::app()->setFlashMessage(gT("You can't update question code for an active survey."), 'error');
            $this->redirect(array('surveyAdministration/view', 'surveyid' => $iSurveyID));
        }

        //check subaction
        if (!($sSubAction === 'straight' || $sSubAction === 'bygroup')) {
            Yii::app()->setFlashMessage(gT("Invalid parameters."), 'error');
            $this->redirect(array('surveyAdministration/view', 'surveyid' => $iSurveyID));
        }

        //Automatically renumbers the "question codes" so that they follow
        //a methodical numbering method
        $iQuestionNumber = 1;
        $iGroupNumber = 0;
        $iGroupSequence = 0;
        $oQuestions = Question::model()
            ->with(['group' => ['alias' => 'g'], 'questionl10ns'])
            ->findAll(
                array(
                    'select' => 't.qid,t.gid',
                    'condition' => "t.sid=:sid and questionl10ns.language=:language and parent_qid=0",
                    'order' => 'g.group_order, question_order',
                    'params' => array(':sid' => $iSurveyID, ':language' => $oSurvey->language)
                )
            );

        foreach ($oQuestions as $oQuestion) {
            if ($sSubAction == 'bygroup' && $iGroupNumber != $oQuestion->gid) {
                //If we're doing this by group, restart the numbering when the group number changes
                $iQuestionNumber = 1;
                $iGroupNumber = $oQuestion->gid;
                $iGroupSequence++;
            }
            $sNewTitle = (($sSubAction == 'bygroup') ? ('G' . $iGroupSequence) : '') . "Q" .
                str_pad($iQuestionNumber, 5, "0", STR_PAD_LEFT);
            Question::model()->updateAll(array('title' => $sNewTitle), 'qid=:qid', array(':qid' => $oQuestion->qid));
            $iQuestionNumber++;
            $iGroupNumber = $oQuestion->gid;
        }
        Yii::app()->setFlashMessage(gT("Question codes were successfully regenerated."));
        LimeExpressionManager::SetDirtyFlag(); // so refreshes syntax highlighting
        $this->redirect(array('surveyAdministration/view/surveyid/' . $iSurveyID));
    }

    /**
     * This function prepares the classic view for a new survey
     *
     * @return void
     */
    public function actionNewSurvey()
    {
        if (!Permission::model()->hasGlobalPermission('surveys', 'create')) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->request->urlReferrer);
        }
        $survey = new Survey();
        // set 'inherit' values to survey attributes
        $survey->setToInherit();

        App()->getClientScript()->registerPackage('jquery-json');
        Yii::app()->loadHelper('surveytranslator');
        Yii::app()->loadHelper('admin.htmleditor');

        $aData = $this->generalTabNewSurvey();
        $aData = array_merge($aData, $this->getGeneralTemplateData(0));
        $aData['esrow'] =  $this->fetchSurveyInfo('newsurvey');

        $aData['oSurvey'] = $survey;
        $aData['bShowAllOptions'] = true;
        $aData['bShowInherited'] = true;
        $oSurveyOptions = $survey;
        $oSurveyOptions->bShowRealOptionValues = false;
        $oSurveyOptions->setOptions();
        $aData['oSurveyOptions'] = $oSurveyOptions->oOptionLabels;

        $aData['optionsOnOff'] = array(
            'Y' => gT('On', 'unescaped'),
            'N' => gT('Off', 'unescaped'),
        );

        $aData['optionsAdmin'] = array(
            'default' => gT('Default', 'unescaped'),
            'owner' => gT('Current user', 'unescaped'),
            'custom' => gT('Custom', 'unescaped'),
        );

        $testLanguages = getLanguageDataRestricted(true, 'short');

        $aData['edittextdata']['listLanguagesCode'] = $testLanguages;
        $aData['edittextdata']['aSurveyGroupList'] = SurveysGroups::getSurveyGroupsList();

        $arrayed_data = array();
        $arrayed_data['oSurvey'] = $survey;
        $arrayed_data['data'] = $aData;
        $arrayed_data['title_bar']['title'] = gT('New survey');

        // topbar
        $aData['topbar']['title'] = gT('Create survey');
        $aData['topbar']['rightButtons'] = $this->renderPartial(
            'partial/topbarBtns_create_survey/rightSideButtons',
            [],
            true
        );

        $this->aData = $aData;

        //this is not the layout
        $this->render('newSurvey_view', [
            'arrayed_data' => $arrayed_data
        ]);
    }

    /**
     * Saves the new survey after the creation screen is submitted
     *
     * @return string
     * @throws CException
     */
    public function actionInsert()
    {
        if (Permission::model()->hasGlobalPermission('surveys', 'create')) {
            $user = Yii::app()->user;

            // CHECK IF USER OWNS PREVIOUS SURVEYS BEGIN
            if ($user !== null) {
                $userid = (int) $user->getId();
                $ownsPreviousSurveys  = Survey::model()->findByAttributes(array('owner_id' => $userid));
                if ($ownsPreviousSurveys === null) {
                    $ownsPreviousSurveys = false;
                } else {
                    $ownsPreviousSurveys = true;
                }
            }
            // CHECK IF USER OWNS PREVIOUS SURVEYS END

            // Check if survey title was set
            $surveyTitle = Yii::app()->request->getPost('surveyls_title');
            $surveyTitle = trim((string) $surveyTitle);
            if ($surveyTitle == '') {
                $alertError = gT("Survey could not be created because it did not have a title");

                return Yii::app()->getController()->renderPartial(
                    '/admin/super/_renderJson',
                    array(
                        'data' => array(
                            'alertData' => $alertError,
                            'missingField' => 'surveyls_title'
                        )
                    ),
                    false,
                    false
                );
            }

            Yii::app()->loadHelper("surveytranslator");

            $simpleSurveyValues = new \LimeSurvey\Datavalueobjects\SimpleSurveyValues();
            $baseLanguage = App()->request->getPost('language');
            if ($baseLanguage === null) {
                $baseLanguage = 'en'; //shoulb be const somewhere ... or get chosen language from user
            }
            $simpleSurveyValues->baseLanguage = $baseLanguage;
            $simpleSurveyValues->surveyGroupId = (int) App()->request->getPost('gsid', '1');
            $simpleSurveyValues->title = $surveyTitle;

            $administrator = Yii::app()->request->getPost('administrator');
            if ($administrator == 'custom') {
                $simpleSurveyValues->admin = Yii::app()->request->getPost('admin');
                $simpleSurveyValues->adminEmail = Yii::app()->request->getPost('adminemail');
            }
            $overrideAdministrator = ($administrator != 'owner');

            $surveyCreator = new \LimeSurvey\Models\Services\CreateSurvey(new Survey(), new SurveyLanguageSetting());
            $newSurvey = $surveyCreator->createSimple(
                $simpleSurveyValues,
                (int)Yii::app()->user->getId(),
                Permission::model(),
                $overrideAdministrator
            );
            if (!$newSurvey) {
                Yii::app()->setFlashMessage(gT("Survey could not be created."), 'error');
                $this->redirect(Yii::app()->request->urlReferrer);
            }

            $iNewSurveyid = $newSurvey->sid;
            $this->aData['surveyid'] = $newSurvey->sid; //import to render correct layout in before_render

            // This will force the generation of the entry for survey group
            TemplateConfiguration::checkAndcreateSurveyConfig($iNewSurveyid);

            $createSample = SettingsUser::getUserSettingValue('createsample');
            if ($createSample === null || $createSample === 'default') {
                $createSample = Yii::app()->getConfig('createsample');
            }

            // Figure out destination
            if ($createSample) {
                $iNewGroupID = $this->createSampleGroup($iNewSurveyid);
                $iNewQuestionID = $this->createSampleQuestion($iNewSurveyid, $iNewGroupID);

                Yii::app()->setFlashMessage(gT("Your new survey was created. We also created a first question group and an example question for you."), 'info');
                $redirecturl = $this->getSurveyAndSidemenueDirectionURL(
                    $iNewSurveyid,
                    $iNewGroupID,
                    $iNewQuestionID,
                    'structure'
                );
            } elseif (!$ownsPreviousSurveys) {
                // SET create question and create question group as default view.
                $redirecturl = $this->createUrl(
                    'questionGroupsAdministration/add/',
                    ['surveyid' => $iNewSurveyid]
                );
            } else {
                $redirecturl = $this->createUrl(
                    'surveyAdministration/view/',
                    ['iSurveyID' => $iNewSurveyid]
                );
                Yii::app()->setFlashMessage(gT("Your new survey was created."), 'info');
            }

            return Yii::app()->getController()->renderPartial(
                '/admin/super/_renderJson',
                array(
                    'data' => array(
                        'redirecturl' => $redirecturl,
                    )
                ),
                false,
                false
            );
        }
        $this->redirect(Yii::app()->request->urlReferrer);
    }

    /**
     * New create survey process with default values.
     * Includes to open new question editor (in cloud) when editor is activated by user.
     *
     * @return void
     */
    public function actionCreateSurvey()
    {
        if (Permission::model()->hasGlobalPermission('surveys', 'create')) {
            $userId = App()->user->id;
            $currentUser = User::model()->findByPk($userId);
            $currentUserLanguage = $currentUser->lang;
            //we need the language short
            if ($currentUserLanguage === 'auto') {
                $currentUserLanguage = Yii::app()->getConfig('defaultlang');
            }

            $simpleSurveyValues = new \LimeSurvey\Datavalueobjects\SimpleSurveyValues();
            $simpleSurveyValues->title = gt('Untitled survey');
            $simpleSurveyValues->surveyGroupId = 1;
            $simpleSurveyValues->baseLanguage = $currentUserLanguage;
            $surveyCreator = new \LimeSurvey\Models\Services\CreateSurvey(new Survey(), new SurveyLanguageSetting());
            $newSurvey = $surveyCreator->createSimple(
                $simpleSurveyValues,
                (int)Yii::app()->user->getId(),
                Permission::model()
            );
            if ($newSurvey) {
                //create examlpe group and example question
                $iNewGroupID = $this->createSampleGroup($newSurvey->sid);
                $iNewQuestionID = $this->createSampleQuestion($newSurvey->sid, $iNewGroupID);

                App()->setFlashMessage(gT("Your new survey was created. We also created a first question group and an example question for you."), 'info');
                $redirectUrl = $this->getSurveyAndSidemenueDirectionURL(
                    $newSurvey->sid,
                    $iNewGroupID,
                    $iNewQuestionID,
                    'structure'
                );
                $this->redirect($redirectUrl);
            } else {
                App()->setFlashMessage(gT("Survey could not be created."), 'error');
                $this->redirect(Yii::app()->request->urlReferrer);
            }
        } else {
            App()->setFlashMessage(gT('Access denied'), 'error');
            $this->redirect(Yii::app()->request->urlReferrer);
        }
    }

    /**
     * todo: what is this? why do we need it?
     *(it'S just an js-script alert window rendert here ...)
     *
     * @return void
     * @throws CException
     */
    public function actionFakebrowser()
    {
        $this->renderPartial('/admin/survey/newSurveyBrowserMessage', array());
    }

    /**
     * Function responsible to import survey resources from a '.zip' file.
     *
     * @todo is this function used? the function editlocalsetting does not exists  (also not in old controller surveyadmin)
     *
     * @access public
     * @return void
     */
    public function actionImportsurveyresources()
    {
        $iSurveyID = sanitize_int(Yii::app()->request->getPost('surveyid'));
        if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->request->urlReferrer);
        }

        if (!empty($iSurveyID)) {
            if (Yii::app()->getConfig('demoMode')) {
                Yii::app()->user->setFlash('error', gT("Demo mode only: Uploading files is disabled in this system."));
                $this->redirect(array('surveyAdministration/rendersidemenulink/', 'surveyid' => $iSurveyID, 'subaction' => 'generalsettings'));
            }

            // Create temporary directory
            // If dangerous content is unzipped
            // then no one will know the path
            Yii::import('application.helpers.common_helper', true);
            $extractdir = createRandomTempDir();
            $zipfilename = $_FILES['the_file']['tmp_name'];
            $basedestdir = Yii::app()->getConfig('uploaddir') . "/surveys";
            $destdir = $basedestdir . "/$iSurveyID/";

            if (!is_writeable($basedestdir)) {
                Yii::app()->user->setFlash('error', sprintf(
                    gT("Incorrect permissions in your %s folder."),
                    $basedestdir
                ));
                $this->redirect(array('surveyAdministration/rendersidemenulink/', 'surveyid' => $iSurveyID, 'subaction' => 'generalsettings'));
            }


            if (!is_dir($destdir)) {
                mkdir($destdir);
            }

            $aImportedFilesInfo = array();
            $aErrorFilesInfo = array();

            if (is_file($zipfilename)) {
                $zip = new LimeSurvey\Zip();
                if ($zip->open($zipfilename) !== true || $zip->extractTo($extractdir) !== true) {
                    Yii::app()->user->setFlash(
                        'error',
                        gT("This file is not a valid ZIP file archive. Import failed. ") . $zip->getStatusString()
                    );
                    $this->redirect(array('surveyAdministration/rendersidemenulink/', 'surveyid' => $iSurveyID, 'subaction' => 'generalsettings'));
                }
                $zip->close();

                // now read tempdir and copy authorized files only
                $folders = array('flash', 'files', 'images');

                $filteredImportedResources = new FilterImportedResources();

                foreach ($folders as $folder) {
                    list($_aImportedFilesInfo, $_aErrorFilesInfo) = $filteredImportedResources->filterImportedResources(
                        $extractdir . "/" . $folder,
                        $destdir . $folder
                    );
                    $aImportedFilesInfo = array_merge($aImportedFilesInfo, $_aImportedFilesInfo);
                    $aErrorFilesInfo = array_merge($aErrorFilesInfo, $_aErrorFilesInfo);
                }

                // Deletes the temp directory
                rmdirr($extractdir);

                // Delete the temporary file
                unlink($zipfilename);

                if (empty($aErrorFilesInfo) && empty($aImportedFilesInfo)) {
                    Yii::app()->user->setFlash(
                        'error',
                        gT("This ZIP archive contains no valid Resources files. Import failed.")
                    );
                    $this->redirect(array('surveyAdministration/rendersidemenulink/', 'surveyid' => $iSurveyID, 'subaction' => 'resources'));
                }
            } else {
                Yii::app()->setFlashMessage(
                    gT("An error occurred uploading your file. This may be caused by incorrect permissions for the application /tmp folder."),
                    'error'
                );
                $this->redirect(array('surveyAdministration/rendersidemenulink/', 'surveyid' => $iSurveyID, 'subaction' => 'resources'));
            }
            $aData = array(
                'aErrorFilesInfo' => $aErrorFilesInfo,
                'aImportedFilesInfo' => $aImportedFilesInfo,
                'surveyid' => $iSurveyID
            );
            $aData['display']['menu_bars']['surveysummary'] = true;
            $survey = Survey::model()->findByPk($iSurveyID);
            $aData['title_bar']['title'] = $survey->currentLanguageSettings->surveyls_title . " (" . gT("ID") . ":" . $iSurveyID . ")";

            $this->aData = $aData;
            $this->render('importSurveyResources_view', $this->aData);
        }
    }

    /**
     * Function to call current Editor Values by Ajax
     *
     * @param integer $sid Given Survey ID
     *
     * is still used in sidemenu Text elemnts (see vue.js ajaxcall)
     *
     * @return JSON
     * @throws CException
     */
    public function actionGetCurrentEditorValues($sid)
    {
        //Permission check
        if (!Permission::model()->hasSurveyPermission($sid, 'surveycontent', 'read')) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                array(
                    'data' => [
                        'success' => false,
                        'message' => gT("No permission"),
                        'debug' => null
                    ]
                ),
                false,
                false
            );
        }

        $iSurveyId = (int)$sid;
        $oSurvey = Survey::model()->findByPk($iSurveyId);

        $updatePermission = $oSurvey == null
            ? Permission::model()->hasGlobalPermission('surveys', 'create')
            : Permission::model()->hasSurveyPermission($iSurveyId, 'surveylocale', 'update');

        $aLanguages = [];
        $aReturner = [
            "surveyTitle" => [],
            "welcome" => [],
            "description" => [],
            "endText" => [],
            "endUrl" => [],
            "endUrlDescription" => [],
            "dateFormat" => [],
            "decimalDivider" => [],
            "permissions" => [
                "update" => $updatePermission,
                "editorpreset" => Yii::app()->session['htmleditormode'],
            ]
        ];

        if ($oSurvey == null) {
            $defaultLanguage = App()->getConfig('defaultlang');
            $aLanguageDetails = getLanguageDetails($defaultLanguage);
            $aLanguages = [$defaultLanguage => getLanguageCodefromLanguage($defaultLanguage)];
            $aReturner["surveyTitle"][$defaultLanguage] = "";
            $aReturner["welcome"][$defaultLanguage] = "";
            $aReturner["description"][$defaultLanguage] = "";
            $aReturner["endText"][$defaultLanguage] = "";
            $aReturner["endUrl"][$defaultLanguage] = "";
            $aReturner["endUrlDescription"][$defaultLanguage] = "";
            $aReturner["dateFormat"][$defaultLanguage] = $aLanguageDetails['dateformat'];
            $aReturner["decimalDivider"][$defaultLanguage] = $aLanguageDetails['radixpoint'];

            return Yii::app()->getController()->renderPartial(
                '/admin/super/_renderJson',
                [
                    'data' => [
                        "textdata" => $aReturner,
                        "languages" => $aLanguages
                    ]
                ],
                false,
                false
            );
        }

        foreach ($oSurvey->allLanguages as $sLanguage) {
            $aLanguages[$sLanguage] = getLanguageNameFromCode($sLanguage, false);
            $aReturner["surveyTitle"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_title;
            $aReturner["welcome"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_welcometext;
            $aReturner["description"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_description;
            $aReturner["endText"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_endtext;
            $aReturner["endUrl"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_url;
            $aReturner["endUrlDescription"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_urldescription;
            $aReturner["dateFormat"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_dateformat;
            $aReturner["decimalDivider"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_numberformat;
        }

        return Yii::app()->getController()->renderPartial(
            '/admin/super/_renderJson',
            [
                'data' => [
                    "textdata" => $aReturner,
                    "languages" => $aLanguages
                ]
            ],
            false,
            false
        );
    }

    /**
     * Massive action in ListSurveysWidget ...
     * Ajax request
     *
     * @return void
     * @throws CException
     */
    public function actionChangeMultipleTheme()
    {
        $sSurveys = $_POST['sItems'] ?? '';
        $aSIDs = json_decode($sSurveys);
        $aResults = array();

        $sTemplate = App()->request->getPost('theme');

        foreach ($aSIDs as $iSurveyID) {
            $aResults = $this->changeTemplate($iSurveyID, $sTemplate, $aResults, true);
        }

        $this->renderPartial(
            'ext.admin.survey.ListSurveysWidget.views.massive_actions._action_results',
            array('aResults' => $aResults, 'successLabel' => $sTemplate)
        );
    }

    /**
     * Change survey group for multiple survey at once.
     * Called from survey list massive actions
     *
     * @return void
     * @throws CException
     */
    public function actionChangeMultipleSurveyGroup()
    {
        $sSurveys = $_POST['sItems'] ?? '';
        $aSIDs = json_decode($sSurveys);
        $aResults = array();

        $iSurveyGroupId = sanitize_int(App()->request->getPost('surveygroupid'));

        foreach ($aSIDs as $iSurveyID) {
            $oSurvey = Survey::model()->findByPk((int)$iSurveyID);
            $aResults[$iSurveyID]['title'] = $oSurvey->correct_relation_defaultlanguage->surveyls_title;
            /* Permission must be checked with current SurveyGroup, SurveyGroup give Surveys Permission, see mantis issue #19169 */
            if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) {
                $aResults[$iSurveyID]['result'] = false;
                $aResults[$iSurveyID]['error'] = gT("User does not have valid permissions");
                continue;
            }
            $oSurvey->gsid = $iSurveyGroupId;
            if ($oSurvey->save()) {
                $aResults[$iSurveyID]['result'] = true;
            } else {
                $aResults[$iSurveyID]['result'] = false;
                $aResults[$iSurveyID]['error'] = gT("Survey update failed");
            }
        }

        Yii::app()->getController()->renderPartial(
            'ext.admin.survey.ListSurveysWidget.views.massive_actions._action_results',
            array('aResults' => $aResults, 'successLabel' => gT("Success"))
        );
    }

    /**
     * Toggles Quick action
     *
     * @return string | null
     * @throws CException
     */
    public function actionToggleQuickAction()
    {
        $quickactionstate = (int)SettingsUser::getUserSettingValue('quickaction_state');

        switch ($quickactionstate) {
            case null:
            case 0:
                $save = SettingsUser::setUserSetting('quickaction_state', 1);
                break;
            case 1:
                $save = SettingsUser::setUserSetting('quickaction_state', 0);
                break;
            default:
                $save = null;
        }
        return Yii::app()->getController()->renderPartial(
            '/admin/super/_renderJson',
            array(
                'data' => [
                    'success' => $save,
                    'newState' => SettingsUser::getUserSettingValue('quickaction_state')
                ],
            ),
            false,
            false
        );
    }

    /**
     * AjaxRequest get questionGroup with containing questions
     *
     * @todo this could go to the questiongroupAdministrationController ?
     *
     * @param int $surveyid Given Survey ID
     *
     * @return string|string[]
     * @throws CException
     */
    public function actionGetAjaxQuestionGroupArray($surveyid)
    {
        $iSurveyID = sanitize_int($surveyid);

        if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'read')) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->createUrl('/admin'));
        }

        $survey = Survey::model()->findByPk($iSurveyID);
        $baselang = $survey->language;
        $lastquestionID = SettingsUser::getUserSetting('last_question', $iSurveyID, 'Survey');
        $lastquestiongroupID = SettingsUser::getUserSetting('last_group', $iSurveyID, 'Survey');
        $aGroups = QuestionGroup::model()->findAllByAttributes(
            array('sid' => $iSurveyID),
            array('order' => 'group_order ASC')
        );
        $aGroupViewable = array();

        $aData = ['topBar' => ['name' => 'questionTopbar_view'], "sid" => $iSurveyID];

        $topbarConfig = TopbarConfiguration::createFromViewData($aData);
        $configData  = $topbarConfig->getData();


        if (count($aGroups)) {
            foreach ($aGroups as $group) {
                $curGroup = $group->attributes;
                $curGroup['group_name'] = viewHelper::flatEllipsizeText($group->questiongroupl10ns[$baselang]->group_name, true, 150);
                $curGroup['groupDropdown'] = [];
                $condarray = getGroupDepsForConditions($surveyid, "all", $group->gid, "by-targgid");

                $curGroup['link'] = $this->createUrl(
                    "questionGroupsAdministration/view",
                    ['surveyid' => $surveyid, 'gid' => $group->gid]
                );
                $group->aQuestions = Question::model()->findAllByAttributes(
                    array(
                        "sid" => $iSurveyID,
                        "gid" => $group['gid'],
                        'parent_qid' => 0
                    ),
                    array('order' => 'question_order ASC')
                );

                if ($configData['hasSurveyContentReadPermission']) {
                    $curGroup['groupDropdown']['language'] =
                    [
                        'id' => '',
                        'label' => gT("Check logic"),
                        'icon' => 'ri-checkbox-fill',
                        'url' => Yii::App()->createUrl("admin/expressions/sa/survey_logic_file/sid/{$iSurveyID}/gid/$group->gid")
                    ];
                }
                if ($configData['hasSurveyContentExportPermission']) {
                    $curGroup['groupDropdown']['export'] =
                    [
                        'id' => '',
                        'label' => gT("Export"),
                        'icon' => 'ri-download-fill',
                        'url' => Yii::App()->createUrl("admin/export/sa/group/surveyid/$iSurveyID/gid/$group->gid")
                    ];
                }

                if ($configData['hasSurveyContentDeletePermission']) {
                    if ($configData['oSurvey']->active !== 'Y') {
                        if (is_null($condarray)) {
                            $curGroup['groupDropdown']['delete'] =
                            [
                                'id' => '',
                                'label' => gT("Delete group"),
                                'icon' => 'ri-delete-bin-fill text-danger',
                                'dataTitle' => gT('Delete group'),
                                'dataBtnText' => gT('Delete'),
                                'dataOnclick' => '(function() { ' .  convertGETtoPOST(
                                    Yii::app()->createUrl(
                                        "questionGroupsAdministration/delete/",
                                        [  "asJson" => true,
                                        "surveyid" => $iSurveyID,
                                        "gid" => $group->gid,
                                        "landOnSideMenuTab" => "structure",
                                        ]
                                    )
                                ) . '})',
                                'dataMessage' => gT("Deleting this group will also delete any questions and answers it contains. Are you sure you want to continue?", 'unescaped')
                            ];
                        } else {
                            $curGroup['groupDropdown']['delete'] =
                            [
                                'id' => '',
                                'label' => gT("Delete group"),
                                'icon' => 'ri-delete-bin-fill text-danger',
                                'dataTitle' => gT('Delete group'),
                                'disabled' => true,
                                'title' => gT("Impossible to delete this group because there is at least one question having a condition on its content", 'unescaped')
                            ];
                        }
                    } else {
                        $curGroup['groupDropdown']['delete'] =
                        [
                            'id' => '',
                            'label' => gT("Delete group"),
                            'icon' => 'ri-delete-bin-fill text-danger',
                            'dataTitle' => gT('Delete group'),
                            'disabled' => true,
                            'title' => gT("It is not possible to add/delete groups if the survey is active.", 'unescaped')
                        ];
                    }
                }



                $curGroup['questions'] = array();
                foreach ($group->aQuestions as $question) {
                    if (is_object($question)) {
                        $curQuestion = $question->attributes;
                        $curQuestion['link'] = $this->createUrl(
                            "questionAdministration/view",
                            ['surveyid' => $surveyid, 'gid' => $group->gid, 'qid' => $question->qid]
                        );
                        $curQuestion['hidden'] = isset($question->questionattributes['hidden']) &&
                            !empty($question->questionattributes['hidden']->value);
                        $questionText = isset($question->questionl10ns[$baselang])
                            ? $question->questionl10ns[$baselang]->question
                            : '';
                        // We have to limit the question text length here, otherwise the whole question is loaded into the navigation tree
                        $curQuestion['question_flat'] = viewHelper::flatEllipsizeText($questionText, true, 150);
                        $hasdefaultvalues = (QuestionTheme::findQuestionMetaData($question->type)['settings'])->hasdefaultvalues;
                        $curQuestion['questionDropdown'] = [];
                        if ($configData['hasSurveyContentUpdatePermission']) {
                            $curQuestion['questionDropdown']['conditionDesigner'] =
                                [
                                    'id' => 'conditions_button',
                                    'label' => gT("Condition designer"),
                                    'icon' => 'ri-git-branch-fill icon',
                                    'url' => Yii::App()->createUrl("admin/conditions/sa/index/subaction/editconditionsform/surveyid/$iSurveyID/gid/$question->gid/qid/$question->qid")
                                ];
                        }
                        $curQuestion['questionDropdown']['editDefault'] =
                            [
                                'id' => 'default_value_button',
                                'label' => gT("Edit default answers"),
                                'icon' => 'ri-grid-line ',
                                'url' => Yii::App()->createUrl("questionAdministration/editdefaultvalues/surveyid/$iSurveyID/gid/$question->gid/qid/$question->qid"),
                                'active' => $configData['hasSurveyContentUpdatePermission'] && $hasdefaultvalues > 0 ? 1 : 0
                            ];

                        if ($configData['hasSurveyContentExportPermission']) {
                            $curQuestion['questionDropdown']['export'] =
                                [
                                    'id' => '',
                                    'label' => gT("Export"),
                                    'icon' => 'ri-download-fill',
                                    'url' => Yii::App()->createUrl("admin/export/sa/question/surveyid/$iSurveyID/gid/$question->gid/qid/$question->qid")
                                ];
                        }

                        if ($configData['hasSurveyContentCreatePermission'] && ($configData['oSurvey']->active != 'Y')) {
                            $curQuestion['questionDropdown']['copy'] =
                                [
                                    'id' => 'copy_button',
                                    'label' => gT("Copy"),
                                    'icon' => 'ri-file-copy-line icon',
                                    'url' => Yii::App()->createUrl("questionAdministration/copyQuestion/surveyId/$iSurveyID/questionGroupId/$question->gid/questionId/$question->qid")
                                ];
                        }

                        if ($configData['hasSurveyContentReadPermission']) {
                            if (count($configData['surveyLanguages']) > 1) {
                                $curQuestion['questionDropdown']['language'] = [];
                                foreach ($configData['surveyLanguages'] as $languageCode => $languageName) {
                                    array_push(
                                        $curQuestion['questionDropdown']['language'],
                                        [
                                            'id' => '',
                                            'label' => gT($languageName),
                                            'icon' => 'ri-checkbox-fill',
                                            'url' => Yii::App()->createUrl("admin/expressions/sa/survey_logic_file/sid/{$iSurveyID}/gid/$question->gid/qid/$question->qid/lang/" . $languageCode)
                                        ]
                                    );
                                }
                            } else {
                                $curQuestion['questionDropdown']['language'] =
                                    [
                                        'id' => '',
                                        'label' => gT("Check logic"),
                                        'icon' => 'ri-checkbox-fill',
                                        'url' => Yii::App()->createUrl("admin/expressions/sa/survey_logic_file/sid/{$iSurveyID}/gid/$question->gid/qid/$question->qid")
                                    ];
                            }
                        }

                        if ($configData['oSurvey']->active !== 'Y') {
                            $curQuestion['questionDropdown']['delete'] =
                                [
                                    'id' => '',
                                    'label' => gT("Delete question"),
                                    'icon' => 'ri-delete-bin-fill text-danger',
                                    'dataTitle' => gT('Delete this question'),
                                    'dataBtnText' => gT('Delete'),
                                    'dataOnclick' => '(function() { ' .  convertGETtoPOST(Yii::app()->createUrl("questionAdministration/delete/", ["qid" => $question->qid, "redirectTo" => "groupoverview"])) . '})',
                                    'dataMessage' => gT("Deleting this question will also delete any answer options and subquestions it includes. Are you sure you want to continue?", 'unescaped')
                                ];
                        } else {
                            $curQuestion['questionDropdown']['delete'] =
                            [
                                'id' => '',
                                'label' => gT("Delete question"),
                                'icon' => 'ri-delete-bin-fill text-danger',
                                'dataTitle' => gT('Delete this question'),
                                'disabled' => true,
                                'title' => gT("You can not delete a question if the survey is active.", 'unescaped'),
                            ];
                        }

                        $curGroup['questions'][] = $curQuestion;
                    }
                }
                $aGroupViewable[] = $curGroup;
            }
        }


        return $this->renderPartial(
            '/admin/super/_renderJson',
            array(
                'data' => array(
                    'groups' => $aGroupViewable,
                    'settings' => array(
                        'lastquestion' => $lastquestionID,
                        'lastquestiongroup' => $lastquestiongroupID,
                    ),
                )
            ),
            false,
            false
        );
    }

    /**
     * Ajaxified get MenuItems with containing questions
     *
     * @todo this could go into surveymenucontroller
     *
     * @param int $surveyid Given Survey ID
     * @param string $position Given Position
     *
     * @return string|string[]
     * @throws CException
     */
    public function actionGetAjaxMenuArray($surveyid, $position = '')
    {
        $iSurveyID = sanitize_int($surveyid);

        //todo permission check ?!?

        $survey = Survey::model()->findByPk($iSurveyID);
        $menus = $survey->getSurveyMenus($position);
        return $this->renderPartial(
            '/admin/super/_renderJson',
            array(
                'data' => [
                    'menues' => $menus,
                    'settings' => array(
                        'extrasettings' => false,
                        'parseHTML' => false,
                    )
                ]
            ),
            false,
            false
        );
    }

    /**
     * Method to call current date information by ajax
     *
     * @return JSON | string
     * @throws CException
     */
    public function actionGetDateFormatOptions()
    {
        $aRawDateFormats = getDateFormatData();

        //todo: does this action needs a permission check? what permission should be checked?

        return $this->renderPartial(
            '/admin/super/_renderJson',
            [
                'data' => array_map(
                    function ($aDateFormats) {
                        return $aDateFormats['dateformat'];
                    },
                    $aRawDateFormats
                )
            ],
            false,
            false
        );
    }

    /**
     * Method to store data edited in the text editor component
     *
     * integer $sid Survey ID
     *
     * @return JSON | string
     * @throws CException
     */
    public function actionSaveTextData($sid)
    {
        $iSurveyId = (int)$sid;
        $changes = Yii::app()->request->getPost('changes');
        $aSuccess = [];

        if (!Permission::model()->hasSurveyPermission($iSurveyId, 'surveycontent', 'update')) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                array(
                    'data' => [
                        'success' => false,
                        'message' => gT("No permission"),
                        'debug' => null
                    ]
                ),
                false,
                false
            );
        }

        foreach ($changes as $sLanguage => $contentChange) {
            //todo: better not to use sql-statement like this in a foreach (performance!!!)
            $oSurveyLanguageSetting = SurveyLanguageSetting::model()->findByPk(
                ["surveyls_survey_id" => $iSurveyId, "surveyls_language" => $sLanguage]
            );
            if ($oSurveyLanguageSetting == null) {
                $oSurveyLanguageSetting = new SurveyLanguageSetting();
                $oSurveyLanguageSetting->surveyls_survey_id = $iSurveyId;
                $oSurveyLanguageSetting->surveyls_language = $sLanguage;
            }
            $oSurveyLanguageSetting->surveyls_title = $contentChange['surveyTitle'];
            $oSurveyLanguageSetting->surveyls_welcometext = $contentChange['welcome'];
            $oSurveyLanguageSetting->surveyls_description = $contentChange['description'];
            $oSurveyLanguageSetting->surveyls_endtext = $contentChange['endText'];
            $oSurveyLanguageSetting->surveyls_url = $contentChange['endUrl'];
            $oSurveyLanguageSetting->surveyls_urldescription = $contentChange['endUrlDescription'];
            $oSurveyLanguageSetting->surveyls_dateformat = $contentChange['dateFormat'];
            $oSurveyLanguageSetting->surveyls_numberformat = $contentChange['decimalDivider'];
            $aSuccess[$sLanguage] = $oSurveyLanguageSetting->save();
            unset($oSurveyLanguageSetting);
        }

        $success = array_reduce(
            $aSuccess,
            function ($carry, $subsuccess) {
                return $carry = $carry && $subsuccess;
            },
            true
        );

        return $this->renderPartial(
            '/admin/super/_renderJson',
            [
                'data' => [
                    "success" => $success,
                    "message" => ($success ? gT("Survey texts were saved successfully.") : gT("Error saving survey texts"))
                ]
            ],
            false,
            false
        );
    }

    /**
     * Collect the data necessary for the data security settings and return a JSON document
     *
     * @param integer|null $sid Survey ID
     *
     * @return JSON | string
     *
     * @throws CException
     */
    public function actionGetDataSecTextSettings($sid = null)
    {
        $iSurveyId = (int)$sid;

        //permission check ...
        if (!Permission::model()->hasSurveyPermission($iSurveyId, 'surveycontent', 'read')) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                array(
                    'data' => [
                        'success' => false,
                        'message' => gT("No permission"),
                        'debug' => null
                    ]
                ),
                false,
                false
            );
        }


        $oSurvey = Survey::model()->findByPk($iSurveyId);

        $aLanguages = [];
        $aReturner = [
            "dataseclabel" => [],
            "datasecmessage" => [],
            "datasecerror" => [],
        ];

        if ($oSurvey == null) {
            $defaultLanguage = App()->getConfig('defaultlang');
            $aLanguages = [$defaultLanguage => getLanguageCodefromLanguage($defaultLanguage)];
            $aReturner["datasecmessage"][$defaultLanguage] = "";
            $aReturner["datasecerror"][$defaultLanguage] = "";
            $aReturner["dataseclabel"][$defaultLanguage] = "";

            return $this->renderPartial(
                '/admin/super/_renderJson',
                [
                    'data' => [
                        "showsurveypolicynotice" => 0,
                        "textdata" => $aReturner,
                        "languages" => $aLanguages,
                        "permissions" => [
                            "update" => Permission::model()->hasGlobalPermission('surveys', 'create'),
                            "editorpreset" => Yii::app()->session['htmleditormode'],
                        ]
                    ]
                ],
                false,
                false
            );
        }

        foreach ($oSurvey->allLanguages as $sLanguage) {
            $aLanguages[$sLanguage] = getLanguageNameFromCode($sLanguage, false);
            $aReturner["datasecmessage"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_policy_notice;
            $aReturner["datasecerror"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_policy_error;
            $aReturner["dataseclabel"][$sLanguage] = $oSurvey->languagesettings[$sLanguage]->surveyls_policy_notice_label;
        }

        return $this->renderPartial(
            '/admin/super/_renderJson',
            [
                'data' => [
                    "showsurveypolicynotice" => $oSurvey->showsurveypolicynotice,
                    "textdata" => $aReturner,
                    "languages" => $aLanguages,
                    "permissions" => [
                        "update" => Permission::model()->hasSurveyPermission($iSurveyId, 'surveysecurity', 'update'),
                        "editorpreset" => Yii::app()->session['htmleditormode'],
                    ]
                ]
            ],
            false,
            false
        );
    }

    /**
     * Method to store data edited in the data security text editor component
     *
     * @param integer $sid Survey ID
     *
     * @return JSON | string
     *
     * @throws CException
     */
    public function actionSaveDataSecTextData($sid)
    {
        $iSurveyId = (int)$sid;
        if (!Permission::model()->hasSurveyPermission($iSurveyId, 'surveycontent', 'update')) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                array(
                    'data' => [
                        'success' => false,
                        'message' => gT("No permission"),
                        'debug' => null
                    ]
                ),
                false,
                false
            );
        }

        $oSurvey = Survey::model()->findByPk($iSurveyId);
        $changes = Yii::app()->request->getPost('changes', []);
        $aSuccess = [];

        $oSurvey->showsurveypolicynotice = $changes['showsurveypolicynotice'] ?? 0;
        $aSuccess[] = $oSurvey->save();
        foreach ($oSurvey->allLanguages as $sLanguage) {
            $oSurveyLanguageSetting = SurveyLanguageSetting::model()->findByPk([
                "surveyls_survey_id" => $iSurveyId,
                "surveyls_language" => $sLanguage
            ]);
            if ($oSurveyLanguageSetting == null) {
                $oSurveyLanguageSetting = new SurveyLanguageSetting();
                $oSurveyLanguageSetting->surveyls_title = "";
                $oSurveyLanguageSetting->surveyls_survey_id = $iSurveyId;
                $oSurveyLanguageSetting->surveyls_language = $sLanguage;
            }

            $oSurveyLanguageSetting->surveyls_policy_notice = $changes['datasecmessage'][$sLanguage] ?? '';
            $oSurveyLanguageSetting->surveyls_policy_error = $changes['datasecerror'][$sLanguage] ?? '';
            $oSurveyLanguageSetting->surveyls_policy_notice_label = $changes['dataseclabel'][$sLanguage] ?? '';
            $aSuccess[$sLanguage] = $oSurveyLanguageSetting->save();
            unset($oSurveyLanguageSetting);
        }

        $success = array_reduce(
            $aSuccess,
            function ($carry, $subsuccess) {
                return $carry = $carry && $subsuccess;
            },
            true
        );

        return $this->renderPartial(
            '/admin/super/_renderJson',
            [
                'data' => [
                    "success" => $success,
                    "message" => ($success ? gT("Successfully saved privacy policy text") : gT("Error saving privacy policy text"))
                ]
            ],
            false,
            false
        );
    }

    /**
     * Apply current theme options for imported survey theme
     *
     * @param integer $iSurveyID The survey ID of imported survey
     *
     * @return void
     */
    public function actionApplythemeoptions(int $surveyid = 0)
    {
        $iSurveyID = $surveyid;
        if ((int)$iSurveyID > 0 && Yii::app()->request->isPostRequest) {
            $oSurvey = Survey::model()->findByPk($iSurveyID);
            $sTemplateName = $oSurvey->template;
            $aThemeOptions = json_decode(App()->request->getPost('themeoptions', ''));

            if (!empty($aThemeOptions)) {
                $oSurveyConfig = TemplateConfiguration::getInstance($sTemplateName, null, $iSurveyID);
                if ($oSurveyConfig->options === 'inherit') {
                    $oSurveyConfig->setOptionKeysToInherit();
                }

                foreach ($aThemeOptions as $key => $value) {
                    $oSurveyConfig->setOption($key, $value);
                }
                $oSurveyConfig->save();
            }
        }
        $this->redirect(array('surveyAdministration/view/surveyid/' . $iSurveyID));
    }

    /**
     * Upload an image in directory
     *
     * @return json |string
     *
     * @throws CException
     */
    public function actionUploadimagefile()
    {
        $debug = [$_FILES];
        // Check file size and render JSON on error.
        // This is done before checking the survey permissions because, if the max POST size was exceeded,
        // there is no Survey ID to check for permissions, so the error could be misleading.
        $uploadValidator = new LimeSurvey\Models\Services\UploadValidator();
        $uploadValidator->renderJsonOnError('file', $debug);

        $iSurveyID = (int)Yii::app()->request->getPost('surveyid');
        $success = false;
        $debug = [];
        if (
            Permission::model()->hasSurveyPermission(
                $iSurveyID,
                'surveycontent',
                'update'
            )
        ) {
            $checkImage = LSYii_ImageValidator::validateImage($_FILES["file"]);
            if ($checkImage['check'] !== false) {
                $diContainer = \LimeSurvey\DI::getContainer();
                $fileUploadService = $diContainer->get(
                    FileUploadService::class
                );
                $destDir = $fileUploadService->getSurveyUploadDirectory(
                    $iSurveyID
                );
                if (is_writeable($destDir)) {
                    $returnedData = $fileUploadService->saveFileInDirectory(
                        $_FILES['file'],
                        $destDir
                    );
                    $message = $returnedData['uploadResultMessage'];
                    $debug = $returnedData['debug'];
                    $success = $returnedData['success'];
                } else {
                    $message = sprintf(
                        gT("Incorrect permissions in your %s folder."),
                        $destDir
                    );
                }
            } else {
                $message = $checkImage['uploadresult'];
                $debug = $checkImage['debug'];
            }
        } else {
            $message = gT(
                "You don't have sufficient permissions to upload images in this survey"
            );
        }

        return $this->renderPartial(
            '/admin/super/_renderJson',
            array(
                'data' => [
                    'success' => $success,
                    'message' => $message,
                    'debug' => $debug
                ]
            ),
        );
    }

    /**
     * Returns JSON Data for Token Top Bar.
     *
     * @param int $sid Given Survey ID
     * @param bool $onlyclose Close
     *
     * @return string
     * @todo: this should go into tokens controller ...
     *
     */
    public function actionGetTokenTopBar(int $sid)
    {
        $oSurvey = Survey::model()->findByPk($sid);

        return $this->renderPartial(
            'token_bar',
            array(
                'oSurvey' => $oSurvey,
                'sid' => $sid,
                'onlyclose' => !$oSurvey->hasTokensTable
            ),
            false,
            false
        );
    }

    /**
     * Function responsible to deactivate a survey.
     *
     * @return void
     * @access public
     * @throws CException
     */
    public function actionDeactivate()
    {
        $iSurveyID = $this->getSurveyIdFromGetRequest();
        if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveyactivation', 'update')) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->request->urlReferrer);
        }
        $diContainer = \LimeSurvey\DI::getContainer();
        $surveyDeactivate = $diContainer->get(
            LimeSurvey\Models\Services\SurveyDeactivate::class
        );

        $aData = array();

        $datestamp = time();
        $date = date('YmdHis', $datestamp); //'His' adds 24hours+minutes to name to allow multiple deactiviations in a day
        $survey = Survey::model()->findByPk($iSurveyID);
        $aData['aSurveysettings'] = getSurveyInfo($iSurveyID);
        $aData['surveyid'] = $iSurveyID;
        $aData['sid'] = $iSurveyID;
        $aData['title_bar']['title'] = $survey->currentLanguageSettings->surveyls_title . " (" . gT("ID") . ":" . $iSurveyID . ")";
        $aData['topBar']['hide'] = true;
        $ok = Yii::app()->request->getPost('ok');

        if ($ok == '') {
            $aData['date'] = $date;
            $aData['dbprefix'] = Yii::app()->db->tablePrefix;
            $aData['sNewSurveyTableName'] = Yii::app()->db->tablePrefix . "old_survey_{$iSurveyID}_{$date}";
            $aData['step1'] = true;
        } else {
            try {
                $result = $surveyDeactivate->deactivate($iSurveyID, ['ok' => $ok]);
            } catch (Exception $e) {
                App()->user->setFlash('error', $e->getMessage());
            }

            if (!empty($result["beforeDeactivate"]["message"])) {
                Yii::app()->user->setFlash('error', $result["beforeDeactivate"]["message"]);
            }
            if ($result["beforeDeactivate"]["message"] === false) {
                // @todo: What if two plugins change this?
                $aData = [];
                $aData['nostep'] = true;
                $this->aData = $aData;
            } else {
                if (!$result["surveyTableExists"]) {
                    $_SESSION['flashmessage'] = gT("Error: Response table does not exist. Survey cannot be deactivated.");
                    $this->redirect($this->createUrl("surveyAdministration/view/surveyid/{$iSurveyID}"));
                }

                $aData = $result['aData'];

                $aData['sidemenu']['state'] = false;
            }
        }

        $this->aData = $aData;
        $this->render('deactivateSurvey_view', $aData);
    }

    /**
     * fixes the numbering of questions
     * This can happen if question 1 have subquestion code 1 and
     * have question 11 in same survey and group (then same SGQA).
     *
     * @todo: maybe this one could not happen anymore ?
     *
     * @return array|false|string|string[]|null
     * @throws CException
     */
    public function actionFixNumbering()
    {
        //get params surveyid and questionid
        $surveyId = sanitize_int(Yii::app()->request->getParam('iSurveyID', 0));
        $questionId = sanitize_int(Yii::app()->request->getParam('questionId', 0));

        $success = false;
        if (($surveyId > 0) && ($questionId > 0)) {
            App()->loadHelper('admin.activate');
            fixNumbering($questionId, $surveyId);
            $success = true;
        }

        return $this->renderPartial(
            '/admin/super/_renderJson',
            [
                'data' => [
                    'success' => $success,
                    //'html' => $html,  todo: should we give any feedback here?
                ]
            ],
        );
    }

    /**
     * This action renders the view for survey activation where
     * the user can preselect some options like "ipanonymize" etc.
     * It is also possible to switch between the "open access mode" and
     * the "close-access-mode" before the survey is activated.
     * The action also checks if it is even possible to activate the survey
     * (see checkGroup() and checkQuestions() for more information).
     *
     * @return void
     */
    public function actionActivateSurvey()
    {
        $surveyId = (int) Yii::app()->request->getPost('surveyId');
        if (!Permission::model()->hasSurveyPermission($surveyId, 'surveyactivation', 'update')) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->request->urlReferrer);
        }
        $oSurvey = Survey::model()->findByPk($surveyId);
        $aSurveysettings = getSurveyInfo($surveyId);

        Yii::app()->loadHelper("admin.activate");
        $failedgroupcheck = checkGroup($surveyId);
        $failedcheck = checkQuestions($surveyId, $surveyId);
        $error = "";
        if (!$oSurvey->countTotalQuestions) {
            $error = gT("There are no questions in this survey.");
        }
        $checkFailed = (isset($failedcheck) && $failedcheck) || (isset($failedgroupcheck) && $failedgroupcheck) || !empty($error);
        $footerButton = $this->renderPartial(
            '/surveyAdministration/surveyActivation/_activateFooterBtns',
            [],
            true
        );
        if ($checkFailed) {
            //survey can not be activated
            $html = $this->renderPartial(
                '/surveyAdministration/surveyActivation/_activateSurveyCheckFailed',
                [
                'failedcheck' => $failedcheck,
                'failedgroupcheck' => $failedgroupcheck,
                'error' => $error,
                'surveyid' => $oSurvey->sid
                ],
                true
            );
            $footerButton = $this->renderPartial(
                '/surveyAdministration/surveyActivation/_failedFooterBtn',
                [],
                true
            );
        } else {
            //check if survey is in "open-access-mode"
            $survey = Survey::model()->findByPk($surveyId);
            $surveyActivator = new SurveyActivator($survey);
            $html = $this->renderPartial(
                '/surveyAdministration/surveyActivation/_activateSurveyOptions',
                [
                'oSurvey' => $oSurvey,
                'aSurveysettings' => $aSurveysettings,
                    'closeAccessMode' => $surveyActivator->isCloseAccessMode(),
                ],
                true
            );
        }

        return $this->renderPartial(
            '/admin/super/_renderJson',
            [
                'data' => [
                    'success' => true,
                    'html' => $html,
                    'checkFailed' => $checkFailed,
                    'footerButton' => $footerButton
                ]
            ],
        );
    }

    /**
     * This action activates the survey with selected options.
     *
     * @return void
     */
    public function actionActivate()
    {
        $surveyId = (int) App()->request->getPost('surveyId');
        if (!Permission::model()->hasSurveyPermission($surveyId, 'surveyactivation', 'update')) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->request->urlReferrer);
        }

        // Avoid reactivating a survey that is already active
        // Doing so might override the survey settings, causing an "Error: didn't save" issue
        if (Survey::model()->findByPk($surveyId)->getIsActive()) {
            App()->user->setFlash('error', gT("The survey is already active."));
            $this->redirect(App()->request->urlReferrer);
        }

        $diContainer = \LimeSurvey\DI::getContainer();
        $surveyActivate = $diContainer->get(
            LimeSurvey\Models\Services\SurveyActivate::class
        );

        try {
            $result = $surveyActivate->activate($surveyId);
        } catch (Exception $e) {
            App()->user->setFlash('error', $e->getMessage());
        }



        ######### OLD #########
        if (
            (isset($result['error']) && $result['error'] == 'plugin')
            || (isset($result['blockFeedback']) && $result['blockFeedback'])
        ) {
            // Got false from plugin, redirect to survey front-page
            $this->redirect(['surveyAdministration/view', 'surveyid' => $surveyId]);
        } elseif (isset($result['pluginFeedback'])) {
            // Special feedback from plugin should be given to user
            //todo: what should be done here ...
            $this->render('surveyActivation/_activation_feedback', $result);
        } elseif (isset($result['error'])) {
            $data['result'] = $result;
            //$this->aData = $aData;
            //todo: what should be done here ...
            $this->render('surveyActivation/_activation_error', $data);
        } else {
            $warning = (isset($result['warning'])) ? true : false;
            $allowregister = $result['isAllowRegister']; //todo: where to ask for this one here

            $openAccessMode = Yii::app()->request->getPost('openAccessMode', null);
            if ($openAccessMode !== null) {
                $modes = [
                    'Y' => 'O',
                    'N' => 'C'
                ];
                $mode = ($modes[$openAccessMode] ?? 'O');
                $surveyAccessModeService = new SurveyAccessModeService(
                    Permission::model(),
                    Survey::model(),
                    Yii::app(),
                );
                $surveyAccessModeService->changeAccessMode($surveyId, $mode);
                switch ($openAccessMode) {
                    case 'Y': //show a modal or give feedback on another page
                        $this->redirect([
                            '/surveyAdministration/view/',
                            'surveyid'                 => $surveyId,
                            'surveyActivationFeedback' => 'surveyActivationFeedback'
                        ]);
                        break;
                    case 'N': //check if token table exists or 'allowRegister' set to true
                        $this->redirect([
                            '/admin/tokens/sa/index/',
                            'surveyid'                 => $surveyId,
                            'surveyActivationFeedback' => 'surveyActivationFeedback'
                        ]);
                        break;
                    default: //this should never happen exception ...
                }
            }

            $activationData = [
                'iSurveyID'     => $surveyId,
                'survey'        => $result['oSurvey'],
                'warning'       => $warning,
                'allowregister' => $allowregister,
            ];
            $this->aData = $result;
            $this->render('surveyActivation/_activation_feedback', $activationData);
        }
    }

    /**
     * Function responsible to delete a survey.
     *
     * @return string
     * @access public
     */
    public function actionDelete()
    {
        //todo: delete should always be a post-request
        $iSurveyID = $this->getSurveyIdFromGetRequest();
        if (!Permission::model()->hasSurveyPermission($iSurveyID, 'survey', 'delete')) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->request->urlReferrer);
        }
        $aData = [];
        $iSurveyID = sanitize_int($iSurveyID);
        $aData['surveyid'] = $iSurveyID;
        $aData['sid'] = $aData['surveyid'];
        $survey = Survey::model()->findByPk($iSurveyID);

        $aData['sidemenu']['state'] = false;
        $aData['title_bar']['title'] = $survey->currentLanguageSettings->surveyls_title . " (" . gT("ID") . ":" . $iSurveyID . ")";
        $aData['sidemenu']['state'] = false;
        $aData['survey'] = $survey;

        if (Yii::app()->request->getPost("delete") == 'yes') {
            $aData['issuperadmin'] = Permission::model()->hasGlobalPermission('superadmin', 'read');
            Survey::model()->deleteSurvey($iSurveyID);
            Yii::app()->session['flashmessage'] = gT("Survey deleted.");
            $this->redirect(array("dashboard/view"));
        }

        $this->aData = $aData;
        $this->render('deleteSurvey_view', $aData);
    }

    /**
     * Remove files not deleted properly.
     * Purge is only available for surveys that were already deleted but for some reason
     * left files behind.
     *
     * @param int $purge_sid Given ID
     *
     * @return void
     */
    public function actionPurge($purge_sid)
    {
        $purge_sid = (int) $purge_sid;
        if (Permission::model()->hasGlobalPermission('superadmin', 'delete')) {
            $survey = Survey::model()->findByPk($purge_sid);
            if (empty($survey)) {
                $result = rmdirr(Yii::app()->getConfig('uploaddir') . '/surveys/' . $purge_sid);
                if ($result) {
                    Yii::app()->user->setFlash('success', gT('Survey files deleted.'));
                } else {
                    Yii::app()->user->setFlash('error', gT('Error: Could not delete survey files.'));
                }
            } else {
                // Should not be possible.
                Yii::app()->user->setFlash(
                    'error',
                    gT('Error: Cannot purge files for a survey that is not deleted. Please delete the survey normally in the survey view.')
                );
            }
        } else {
            Yii::app()->user->setFlash('error', gT('Access denied'));
        }

        $this->redirect($this->createUrl('admin/globalsettings'));
    }


    /**
     * New system of rendering content
     * Based on yii submenu rendering
     *
     * @param int $surveyid Given Survey ID
     * @param string $subaction Given subaction (subaction decides which view to render)
     *
     * @return void
     *
     * @throws Exception
     *
     * The below 'uses' are mentioned
     * @uses self::generalTabEditSurvey()
     * @uses self::pluginTabSurvey()
     * @uses self::tabPresentationNavigation()
     * @uses self::tabPublicationAccess()
     * @uses self::tabNotificationDataManagement()
     * @uses self::tabTokens()
     * @uses self::tabPanelIntegration()
     * @uses self::tabResourceManagement()
     *
     */
    public function actionRendersidemenulink($surveyid, $subaction)
    {
        $iSurveyID = (int) $surveyid;
        $menuaction = (string) $subaction;
        $survey = Survey::model()->findByPk($iSurveyID);
        $aData['oSurvey'] = $survey;
        // set values from database to survey attributes

        if (empty($survey)) {
            throw new Exception('Found no survey with id ' . $iSurveyID);
        }

        $survey->setOptionsFromDatabase();

        //Get all languages
        $grplangs = $survey->additionalLanguages;
        $baselang = $survey->language;
        array_unshift($grplangs, $baselang);

        //@TODO add language checks here
        $menuEntry = SurveymenuEntries::model()->find('name=:name', array(':name' => $menuaction));

        if (!(Permission::model()->hasSurveyPermission($iSurveyID, $menuEntry->permission, $menuEntry->permission_grade))) {
            Yii::app()->setFlashMessage(gT("You do not have permission to access this page."), 'error');
            $this->redirect(array('surveyAdministration/view', 'surveyid' => $iSurveyID));
        }

        $templateData = is_array($menuEntry->data) ? $menuEntry->data : [];

        if (!empty($menuEntry->getdatamethod)) {
            $templateData = array_merge($templateData, call_user_func_array(
                array($this, $menuEntry->getdatamethod), //info: getdatamethod is the name of a function here in this controller!!!
                array('survey' => $survey)
            ));
        }

        $templateData = array_merge($this->getGeneralTemplateData($iSurveyID), $templateData);

        // For Text Elemnts Tab.
        if ($menuaction === 'surveytexts') {
            $temp = [];
            $languages = $survey->allLanguages;
            foreach ($languages as $i => $language) {
                $temp = $this->getGeneralTemplateData($iSurveyID);

                App()->loadHelper('database');
                App()->loadHelper('surveytranslator');
                App()->loadHelper('admin.htmleditor');

                $surveyLanguageSetting = SurveyLanguageSetting::model()->findByPk(
                    array(
                        'surveyls_survey_id' => $iSurveyID,
                        'surveyls_language' => $language
                    )
                )->getAttributes();
                $aTabTitles[$language] = getLanguageNameFromCode($surveyLanguageSetting['surveyls_language'], false);

                if ($surveyLanguageSetting['surveyls_language'] == $survey->language) {
                    $aTabTitles[$language] .= ' (' . gT("Base language") . ')';
                }

                $temp['aSurveyLanguageSettings'] = $surveyLanguageSetting;
                $temp['action'] = "surveygeneralsettings";
                $temp['i'] = $i;
                $temp['dateformatdetails'] = getDateFormatData(App()->session['dateformat']);
                $temp['oSurvey'] = $survey;
                Yii::app()->session['FileManagerContext'] = "edit:survey:{$iSurveyID}";
                $aTabContents[$language] = $this->renderPartial('/admin/survey/editLocalSettings_view', $temp, true);
            }

            $aData['aTabContents'] = $aTabContents;
            $aData['aTabTitles']   = $aTabTitles;
            $aData['moreInfo'] = $temp;
        }

        App()->getClientScript()->registerPackage('jquery-json');

        // override survey settings if global settings exist
        $templateData['showqnumcode']   = getGlobalSetting('showqnumcode') !== 'choose' ? getGlobalSetting('showqnumcode') : $survey->showqnumcode;
        $templateData['shownoanswer']   = getGlobalSetting('shownoanswer') !== 'choose' ? getGlobalSetting('shownoanswer') : $survey->shownoanswer;
        $templateData['showgroupinfo']  = getGlobalSetting('showgroupinfo') !== '2' ? getGlobalSetting('showgroupinfo') : $survey->showgroupinfo;
        $templateData['showxquestions'] = getGlobalSetting('showxquestions') !== 'choose' ? getGlobalSetting('showxquestions') : $survey->showxquestions;

        //Start collecting aData
        $aData['surveyid'] = $iSurveyID;
        $aData['sid'] = $iSurveyID;
        $aData['menuaction'] = $menuaction;
        $aData['template'] = $menuEntry->template;
        $aData['templateData'] = $templateData;
        $aData['surveyls_language'] = $baselang;
        $aData['action'] = $menuEntry->action;
        $aData['entryData'] = $menuEntry->attributes;
        $aData['dateformatdetails'] = getDateFormatData(Yii::app()->session['dateformat']);
        $aData['subaction'] = $menuEntry->title;
        $aData['display']['menu_bars']['surveysummary'] = $menuEntry->title;
        $aData['title_bar']['title'] = $survey->currentLanguageSettings->surveyls_title . " (" . gT("ID") . ":" . $iSurveyID . ")";


        if ($subaction === 'resources' || $subaction === 'panelintegration') {
            $aData['topBar']['showSaveButton'] = false;
        } else {
            // Since the save action for survey texts checks two permissions and survey menu entries only support one permission,
            // we need to check the permissions here and decide whether to show the save button or not for that screen.
            /** @todo: Generalize for other subactions */
            if (
                $subaction === 'surveytexts'
                && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveylocale', 'update')
                && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')
            ) {
                $aData['topBar']['showSaveButton'] = false;
            } else {
                $aData['topBar']['showSaveButton'] = true;
            }
        }
        $topbarData = TopbarConfiguration::getSurveyTopbarData($iSurveyID);
        $topbarData = array_merge($topbarData, $aData['topBar']);
        $aData['topbar']['middleButtons'] = $this->renderPartial(
            'partial/topbar/surveyTopbarLeft_view',
            $topbarData,
            true
        );
        $aData['topbar']['rightButtons'] = $this->renderPartial(
            'partial/topbar/surveyTopbarRight_view',
            $topbarData,
            true
        );

        $aData['topBar']['closeUrl'] = $this->createUrl("surveyAdministration/view/", ['surveyid' => $iSurveyID]); // Close button

        $aData['optionsOnOff'] = array(
            'Y' => gT('On', 'unescaped'),
            'N' => gT('Off', 'unescaped'),
        );

        $this->aData = $aData;
        $this->render($menuEntry->template, $aData);
    }

    /**
     * Load ordering of question group screen.
     * questiongroup::organize()
     * @TODO Reordering should be handled by existing function in new QuestionGroupService class
     *
     * @param int $iSurveyID Given Survey ID
     *
     * @return void
     */
    public function actionOrganize()
    {
        $request = Yii::app()->request;

        $iSurveyID = $this->getSurveyIdFromGetRequest();

        $iSurveyID = sanitize_int($iSurveyID);
        $thereIsPostData = $request->getPost('orgdata') !== null;
        $userHasPermissionToUpdate = Permission::model()->hasSurveyPermission(
            $iSurveyID,
            'surveycontent',
            'update'
        );

        if (!$userHasPermissionToUpdate) {
            Yii::app()->user->setFlash('error', gT("Access denied"));
            $this->redirect(Yii::app()->request->urlReferrer);
        }

        if ($thereIsPostData) {
            // Save the new ordering.
            $orgdata = $this->getOrgdata();

            $groupHelper = new LimeSurvey\Models\Services\GroupHelper();
            $result = $groupHelper->reorderGroup($iSurveyID, $orgdata);

            if ($result['type'] === 'success') {
                App()->setFlashMessage(gT("The new question group/question order was successfully saved."));
            } elseif ($result['type'] === 'error') {
                foreach ($result['question-titles'] as $questionTitle) {
                    App()->setFlashMessage(sprintf(gT("Unable to reorder question %s."), $questionTitle), 'warning');
                }
            }

            $closeAfterSave = $request->getPost('close-after-save') === 'true';
            if ($closeAfterSave) {
                 // save reordering redirect to listquestion page as this part is moved there
                 $this->redirect($this->createUrl('questionAdministration/listQuestions', ['surveyid' => $iSurveyID , 'activeTab' => 'reorder']));
            }
        }
        $aData = $this->showReorderForm($iSurveyID);

        $aData['topBar']['showSaveButton'] = true;
        $topbarData = TopbarConfiguration::getSurveyTopbarData($iSurveyID);
        $topbarData = array_merge($topbarData, $aData['topBar']);
        $aData['topbar']['middleButtons'] = $this->renderPartial(
            'partial/topbar/surveyTopbarLeft_view',
            $topbarData,
            true
        );
        $aData['topbar']['rightButtons'] = $this->renderPartial(
            'partial/topbar/surveyTopbarRight_view',
            $topbarData,
            true
        );

        // Display 'Reorder question/question groups' in Green Bar
        $aData['subaction'] = gT('Reorder questions/question groups');

        $this->aData = $aData;
        $this->render('/admin/survey/organizeGroupsAndQuestions_view', $aData);
    }

    /**
     * @param int $surveyid Given Survey ID.
     *
     * @return void
     * @todo   Add TypeDoc.
     */
    public function actionGetUrlParamsJSON($surveyid)
    {
        $iSurveyID = (int) $surveyid;
        $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
        $aSurveyParameters = SurveyURLParameter::model()->findAll('sid=:sid', [':sid' => $iSurveyID]);
        $aData = array(
            'rows' => []
        );
        foreach ($aSurveyParameters as $oSurveyParameter) {
            $row = $oSurveyParameter->attributes;

            if ($oSurveyParameter->targetqid != '') {
                $row['questionTitle'] = $oSurveyParameter->question->title . ": " . ellipsize(flattenText($oSurveyParameter->question->questionl10ns[$sBaseLanguage]->question, false, true), 43, .70);
            }

            if ($oSurveyParameter->targetsqid != '') {
                $row['questionTitle'] .= (' - ' . ellipsize(flattenText($oSurveyParameter->subquestion->questionl10ns[$sBaseLanguage]->question, false, true), 30, .75));
            }

            $row['qid'] = $oSurveyParameter->targetqid;
            $row['sqid'] = $oSurveyParameter->targetsqid;
            $aData['rows'][] = $row;
        }

        $aData['page'] = 1;
        $aData['records'] = count($aSurveyParameters);
        $aData['total'] = 1;

        echo ls_json_encode($aData);
    }

    /**
     * Function responsible to copy a survey.
     *
     * @access public
     * @return void
     * @throws CException
     * @throws Exception
     */
    public function actionCopy()
    {
        //everybody who has permission to create surveys
        if (!Permission::model()->hasGlobalPermission('surveys', 'create')) {
            App()->user->setFlash('error', gT("Access denied"));
            $this->redirect(App()->request->urlReferrer);
        }
        $surveyId = sanitize_int(App()->request->getPost('surveyIdToCopy'));
        $survey = Survey::model()->findByPk($surveyId);
        if (!$survey) {
            App()->user->setFlash('error', gT("Survey does not exist."));
            $this->redirect(App()->request->urlReferrer);
        }
        if (!Permission::model()->hasSurveyPermission($surveyId, 'surveycontent', 'export')) {
            App()->user->setFlash('error', gT("Access denied"));
            $this->redirect(App()->request->urlReferrer);
        }

        //the new survey id
        $rawNewSid = App()->request->getPost('copysurveyid');
        $newSurveyId = ($rawNewSid === '' || $rawNewSid === null)
            ? null
            : sanitize_int($rawNewSid, 1, 999999);

        //the source survey id
        $sourceSurveyId = sanitize_int(App()->request->getPost('surveyIdToCopy'));

        $sourceSurvey = Survey::model()->findByPk($sourceSurveyId);

        $options = $this->getPostParamsForCopySurvey(App()->request);
        $copySurveyService = new \LimeSurvey\Models\Services\CopySurvey(
            $sourceSurvey,
            $options,
            $newSurveyId,
        );

        $copyResults = $copySurveyService->copy();

        $copiedSurvey = $copyResults->getCopiedSurvey();
        if ($copiedSurvey !== null) {
            $groupList = QuestionGroup::model()->findAllByAttributes(['sid' => $copiedSurvey->sid]);
            $this->resetExpressionManager($copiedSurvey, $groupList);
        }

        $aData = [];
        $aData['copyResults'] = $copyResults;

        if ($copiedSurvey !== null) {
            $aData['sLink'] = $this->createUrl('surveyAdministration/view/', ['iSurveyID' => $copiedSurvey->sid]);
            $aData['sLinkApplyThemeOptions'] = 'surveyAdministration/applythemeoptions/surveyid/' . $copiedSurvey->sid;
            $questionGroupList = QuestionGroup::model()->findAllByAttributes(['sid' => $copiedSurvey->sid]);

            // Make the link point to the first group/question if available
            if (!empty($questionGroupList)) {
                $oFirstGroup = $questionGroupList[0];
                $oFirstQuestion = Question::model()->primary()->findByAttributes(
                    ['gid' => $oFirstGroup->gid],
                    ['order' => 'question_order ASC']
                );

                $aData['sLink'] = $this->getSurveyAndSidemenueDirectionURL(
                    $copiedSurvey->sid,
                    $oFirstGroup->gid,
                    !empty($oFirstQuestion) ? $oFirstQuestion->qid : null,
                    'structure'
                );
            }
        }

        if ($copiedSurvey !== null) {
            $copiedSurvey->setOptions();
            if ($copiedSurvey->hasNewEditor) {
                $aData['sLink'] = App()->createUrl("editorLink/index", ["route" => "survey/" . $copiedSurvey->sid]);
            }
        }
        $this->aData = $aData;

        $this->render('copySurveyResult_view', $this->aData);
    }

    /**
     * Initialises the necessary options.
     *
     * @param $request
     * @return CopySurveyOptions
     */
    private function getPostParamsForCopySurvey($request): CopySurveyOptions
    {
        $optionsDataContainer = new CopySurveyOptions();

        //Survey resource files and adapt links
        $option = $request->getPost('copyResourcesAndLinks');
        $optionsDataContainer->setResourcesAndLinks(isset($option) && $option == "1");

        $option = $request->getPost('copySurveyQuotas');
        $optionsDataContainer->setQuotas(isset($option) && $option == "1");

        $option = $request->getPost('copySurveyPermissions');
        $optionsDataContainer->setPermissions(isset($option) && $option == "1");

        $option = $request->getPost('copyAnswerOptions');
        $optionsDataContainer->setAnswerOptions(isset($option) && $option == "1");

        $option = $request->getPost('copySurveyConditions');
        $optionsDataContainer->setConditions(isset($option) && $option == "1");

        $option = $request->getPost('copyStartEndDate');
        $optionsDataContainer->setStartAndEndDate(isset($option) && $option == "1");

        $option = $request->getPost('resetResponseStartId');
        $optionsDataContainer->setResetResponseStartId(isset($option) && $option == "1");

        return $optionsDataContainer;
    }

    /**
     * @param int $surveyIdToCopy
     * @return void
     * @throws Exception
     */
    public function actionCopySimple($surveyIdToCopy)
    {
        //everybody who has permission to create surveys
        if (!Permission::model()->hasGlobalPermission('surveys', 'create')) {
            App()->user->setFlash('error', gT("Access denied"));
            $this->redirect(App()->request->urlReferrer);
        }

        $surveyId = sanitize_int($surveyIdToCopy);
        $survey = Survey::model()->findByPk($surveyId);
        if (!$survey) {
            App()->user->setFlash('error', gT("Survey does not exist."));
            $this->redirect(App()->request->urlReferrer);
        }

        if (!Permission::model()->hasSurveyPermission($surveyId, 'surveycontent', 'export')) {
            App()->user->setFlash('error', gT("Access denied"));
            $this->redirect(App()->request->urlReferrer);
        }
        $optionsDataContainer = new CopySurveyOptions();
        //start and enddate should be copied in the simple copy process
        $optionsDataContainer->setStartAndEndDate(true);
        $copySurveyService = new \LimeSurvey\Models\Services\CopySurvey(
            $survey,
            $optionsDataContainer,
        );

        $copyResults = $copySurveyService->copy();

        $copiedSurvey = $copyResults->getCopiedSurvey();
        if ($copiedSurvey !== null) {
            $groupList = QuestionGroup::model()->findAllByAttributes(['sid' => $copiedSurvey->sid]);
            $this->resetExpressionManager($copiedSurvey, $groupList);
        }

        if (empty($copyResults->getErrors())) {
            App()->user->setFlash('success', gT("Survey copied successfully."));
        } else {
            App()->user->setFlash('error', gT("Error while copying the survey."));
        }

        $redirectUrl = App()->request->urlReferrer;
        if ($copiedSurvey !== null) {
            $redirectUrl = App()->createUrl("surveyAdministration/view/", ["iSurveyID" => $copiedSurvey->sid]);
            $copiedSurvey->setOptions();
            if ($copiedSurvey->hasNewEditor) {
                $redirectUrl = App()->createUrl("editorLink/index", ["route" => "survey/" . $copiedSurvey->sid]);
            }
        }

        $this->redirect($redirectUrl);
    }

    /**
     * Import an uploaded survey file, create the survey if valid, and render the import summary view.
     *
     * Validates upload permissions and file type/size, moves the uploaded file to a temporary location,
     * calls importSurveyFile(...) (passing the "translinksfields" flag and optional "surveysgroup" request parameter),
     * translates import results into view data (including links to the new survey and theme-apply action),
     * resets the expression manager for the newly created survey (if any), cleans up the temporary file,
     * and renders the importSurvey_view with import results or error information.
     */
    public function actionImport()
    {
        //everybody who has permission to create surveys
        if (!Permission::model()->hasGlobalPermission('surveys', 'create')) {
            App()->user->setFlash('error', gT("Access denied"));
            $this->redirect(App()->request->urlReferrer);
        }

        $aData = [];
        $sExtension = "";

        $aData['sHeader'] = gT("Import survey data");
        $aData['sSummaryHeader'] = gT("Survey structure import summary");
        $aData['textCompleted'] = gT("Import of survey is completed.");
        $aPathInfo = pathinfo((string) $_FILES['the_file']['name']);

        if (isset($aPathInfo['extension'])) {
            $sExtension = $aPathInfo['extension'];
        }

        $aData['bFailed'] = false;

        $sFullFilepath = App()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(30) . '.' . $sExtension;
        if ($_FILES['the_file']['error'] == 1 || $_FILES['the_file']['error'] == 2) {
            $aData['sErrorMessage'] = sprintf(gT("Sorry, this file is too large. Only files up to %01.2f MB are allowed."), getMaximumFileUploadSize() / 1024 / 1024) . '<br>';
            $aData['bFailed'] = true;
        } elseif (!in_array(strtolower($sExtension), array('lss', 'txt', 'tsv', 'lsa'))) {
            $aData['sErrorMessage'] = sprintf(gT("Import failed. You specified an invalid file type '%s'."), CHtml::encode($sExtension));
            $aData['bFailed'] = true;
        } elseif ($aData['bFailed'] || !@move_uploaded_file($_FILES['the_file']['tmp_name'], $sFullFilepath)) {
            $aData['sErrorMessage'] = gT("An error occurred uploading your file. This may be caused by incorrect permissions for the application /tmp folder.");
            $aData['bFailed'] = true;
        }

        App()->loadHelper('admin.import');

        if (!$aData['bFailed']) {
            $targetSurveysGroup = App()->request->getPost('surveysgroup');
            if (!in_array($targetSurveysGroup, ['default', 'from_survey'], true)) {
                $targetSurveysGroup = 'default';
            }
            $aImportResults = importSurveyFile($sFullFilepath, (App()->request->getPost('translinksfields') == '1'), null, null, null, $targetSurveysGroup);
            if (is_null($aImportResults)) {
                $aImportResults = array(
                    'error' => gT("Unknown error while reading the file, no survey created.")
                );
            }
        } else {
            $aData['bFailed'] = true;
        }

        // If the import failed, set the status and error message in order to keep consistency with other errors
        if (!empty($aImportResults['error'])) {
            $aData['sErrorMessage'] = $aImportResults['error'];
            $aData['bFailed'] = true;
        }

        if (isset($sFullFilepath) && file_exists($sFullFilepath)) {
            unlink($sFullFilepath);
        }

        if (!$aData['bFailed'] && isset($aImportResults)) {
            $aData['aImportResults'] = $aImportResults;
            if (isset($aImportResults['newsid'])) {
                // Set link pointing to survey administration overview. This link will be updated if the survey has groups
                $aData['sLink'] = $this->createUrl('surveyAdministration/view/', ['iSurveyID' => $aImportResults['newsid']]);
                $aData['sLinkApplyThemeOptions'] = 'surveyAdministration/applythemeoptions/surveyid/' . $aImportResults['newsid'];
            }
        }

        if (!empty($aImportResults['newsid'])) {
            $oSurvey = Survey::model()->findByPk($aImportResults['newsid']);
            $aGrouplist = QuestionGroup::model()->findAllByAttributes(['sid' => $aImportResults['newsid']]);

            $this->resetExpressionManager($oSurvey, $aGrouplist);

            // Make the link point to the first group/question if available
            if (!empty($aGrouplist)) {
                $oFirstGroup = $aGrouplist[0];
                $oFirstQuestion = Question::model()->primary()->findByAttributes(
                    ['gid' => $oFirstGroup->gid],
                    ['order' => 'question_order ASC']
                );

                $aData['sLink'] = $this->getSurveyAndSidemenueDirectionURL(
                    $aImportResults['newsid'],
                    $oFirstGroup->gid,
                    !empty($oFirstQuestion) ? $oFirstQuestion->qid : null,
                    'structure'
                );
            }
        }

        if (isset($aImportResults['newsid'])) {
            if (!isset($oSurvey)) {
                $oSurvey = Survey::model()->findByPk($aImportResults['newsid']);
            }
            if ($oSurvey->hasNewEditor) {
                $aData['sLink'] = App()->createUrl("editorLink/index", ["route" => "survey/" . $aImportResults['newsid']]);
            }
        }
        $this->aData = $aData;
        $this->render('importSurvey_view', $this->aData);
    }


    /**
     * Called via ajax request from survey summary quick action "Show questions group by group".
     *
     * @param int    $iSurveyID Given Survey ID
     * @param string $format    Given Format
     *
     * @return void
     */
    public function actionChangeFormat(int $iSurveyID, $format)
    {
        if (Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
            if (in_array($format, array('S', 'G', 'A'))) {
                $survey = Survey::model()->findByPk($iSurveyID);
                $survey->format = $format;
                $survey->save();
                echo $survey->format;
            }
        }
    }


    /**
     * Expires the survey.
     *
     * @return void
     */
    public function actionExpire()
    {
        $iSurveyID = $this->getSurveyIdFromGetRequest();
        if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) {
            Yii::app()->setFlashMessage(gT("You do not have permission to access this page."), 'error');
            $this->redirect(array('surveyAdministration/view', 'surveyid' => $iSurveyID));
        }
        Yii::app()->session['flashmessage'] = gT("The survey was successfully expired by setting an expiration date in the survey settings.");
        Survey::model()->expire($iSurveyID);
        $this->redirect(array('surveyAdministration/view/surveyid/' . $iSurveyID));
    }

    /**
     *  Ajaxrequest returning 'session['dateformat']'
     *  and some other parameters to the frontend
     *
     * @return void
     *
     * @todo this function should be moved to another controller (?)
     */
    public function actionDatetimesettings()
    {
        if (Permission::model()->hasGlobalPermission('surveys', 'read')) {
            $data = array(
                'dateformatsettings' => getDateFormatData(Yii::app()->session['dateformat']),
                'showClear' => true,
                'allowInputToggle' => true,
            );
            echo json_encode($data);
        }
    }

    /**
     * Action to set expiry date to multiple surveys.
     *  (ajax request)
     *
     * @return void
     * @throws CException
     */
    public function actionExpireMultipleSurveys()
    {
        $sSurveys = $_POST['sItems'] ?? '';
        $aSIDs = json_decode($sSurveys);
        $aResults = array();
        $expires = App()->request->getPost('expires');
        $formatdata = getDateFormatData(Yii::app()->session['dateformat']);
        Yii::import('application.libraries.Date_Time_Converter', true);
        if (trim((string) $expires) == "") {
            $expires = null;
        } else {
            $datetimeobj = new Date_Time_Converter($expires, $formatdata['phpdate'] . ' H:i');
            $expires = $datetimeobj->convert("Y-m-d H:i:s");
        }

        foreach ($aSIDs as $sid) {
            if ((int)$sid > 0) {
                $survey = Survey::model()->findByPk($sid);
                $survey->expires = $expires;
                $aResults[$survey->primaryKey]['title'] = ellipsize(
                    $survey->correct_relation_defaultlanguage->surveyls_title,
                    30
                );
                if (!Permission::model()->hasSurveyPermission($sid, 'surveysettings', 'update')) {
                    $aResults[$survey->primaryKey]['result'] = false;
                    $aResults[$survey->primaryKey]['error'] = gT("User does not have valid permissions");
                } else {
                    if ($survey->save()) {
                        $aResults[$survey->primaryKey]['result'] = true;
                    } else {
                        $aResults[$survey->primaryKey]['result'] = false;
                        $aResults[$survey->primaryKey]['error'] = gT("Survey update failed");
                    }
                }
            }
        }
        $this->renderPartial(
            'ext.admin.survey.ListSurveysWidget.views.massive_actions._action_results',
            array('aResults' => $aResults, 'successLabel' => gT('OK'))
        );
    }

    /** ************************************************************************************************************ */
    /**                      The following functions could be moved to model or service classes                      */
    /** **********************************************************************************************************++ */

    /**
     * Reset expression manager values
     *
     * @param Survey $oSurvey
     * @param array $aGrouplist
     * @return void
     */
    private function resetExpressionManager($oSurvey, $aGrouplist)
    {
        LimeExpressionManager::SetDirtyFlag();
        LimeExpressionManager::singleton();
        // Why this @ !
        LimeExpressionManager::SetSurveyId($oSurvey->sid);
        LimeExpressionManager::RevertUpgradeConditionsToRelevance($oSurvey->sid);
        LimeExpressionManager::UpgradeConditionsToRelevance($oSurvey->sid);
        @LimeExpressionManager::StartSurvey($oSurvey->sid, 'survey', $oSurvey->attributes, true);
        LimeExpressionManager::StartProcessingPage(true, true);
        foreach ($aGrouplist as $aGroup) {
            LimeExpressionManager::StartProcessingGroup(
                $aGroup['gid'],
                $oSurvey->anonymized != 'Y',
                $oSurvey->sid
            );
            LimeExpressionManager::FinishProcessingGroup();
        }
        LimeExpressionManager::FinishProcessingPage();
    }

    /**
     * Try to get the get-parameter from request.
     * At the moment there are three namings for a survey ID:
     * 'sid'
     * 'surveyid'
     * 'iSurveyID'
     *
     * Returns the id as integer or null if not exists any of them.
     *
     * @return int | null
     *
     * @todo While refactoring (at some point) this function should be removed and only one unique identifier should be used
     */
    private function getSurveyIdFromGetRequest()
    {
        $surveyId = Yii::app()->request->getParam('sid');
        if ($surveyId === null) {
            $surveyId = Yii::app()->request->getParam('surveyid');
        }
        if ($surveyId === null) {
            $surveyId = Yii::app()->request->getParam('iSurveyID');
        }

        return (int) $surveyId;
    }

    /**
     * Returns data for Tab Resourves.
     * survey::_tabResourceManagement()
     * Load "Resources" tab.
     *
     * @todo is this new implementation???
     *
     * @param Survey $survey Given Survey
     *
     * @return array
     */
    protected function tabResourceManagement($survey)
    {
        global $sCKEditorURL;

        // TAB Uploaded Resources Management
        $ZIPimportAction = " onclick='if (window.LS.validatefilename(this.form,\"" . gT('Please select a file to import!', 'js') . "\")) { this.form.submit();}'";
        if (!class_exists('ZipArchive')) {
            $ZIPimportAction = " onclick='alert(\"" . gT("The ZIP library is not activated in your PHP configuration thus importing ZIP files is currently disabled.", "js") . "\");'";
        }

        $disabledIfNoResources = '';
        if (hasResources($survey->sid, 'survey') === false) {
            $disabledIfNoResources = " disabled='disabled'";
        }
        $aData = [];
        $aData['ZIPimportAction'] = $ZIPimportAction;
        $aData['disabledIfNoResources'] = $disabledIfNoResources;
        $aData['sCKEditorURL'] = $sCKEditorURL;
        $aData['noform'] = true;

        //KCFINDER SETTINGS
        Yii::app()->session['FileManagerContext'] = "edit:survey:{$survey->sid}";
        Yii::app()->loadHelper('admin.htmleditor');
        initKcfinder();

        return $aData;
    }

    /**
     * Show the form for Organize question groups/questions
     *
     * @param int $iSurveyID Given Survey ID
     *
     * @return array
     * @todo Change function name to _showOrganizeGroupsAndQuestions?
     * @todo Does actually not show anything, but gets data. So getReorderFormData()?
     */
    private function showReorderForm($iSurveyID)
    {
        $survey = Survey::model()->findByPk($iSurveyID);
        $aData = [];
        $aData['title_bar']['title'] = $survey->currentLanguageSettings->surveyls_title . " (" . gT("ID") . ":" . $iSurveyID . ")";
        $aData['sid'] = $iSurveyID; //frontend need this to render topbar for the view

        // Prepare data for the view
        $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
        LimeExpressionManager::StartSurvey($iSurveyID, 'survey');
        LimeExpressionManager::StartProcessingPage(true, Yii::app()->baseUrl);

        $groups = $survey->groups;
        $groupData = [];
        $initializedReplacementFields = false;

        $aData['organizebar']['savebuttonright'] = true;
        $aData['organizebar']['closebuttonright']['url'] = $this->createUrl("surveyAdministration/view/", array('surveyid' => $iSurveyID));
        $aData['organizebar']['saveandclosebuttonright']['url'] = true;
        $aData['surveybar']['buttons']['view'] = true;
        $aData['surveybar']['savebutton']['form'] = 'frmOrganize';
        $aData['topBar']['showSaveButton'] = true;

        foreach ($groups as $iGID => $oGroup) {
            $groupData[$iGID]['gid'] = $oGroup->gid;
            $groupData[$iGID]['group_text'] = $oGroup->gid . ' ' . $oGroup->questiongroupl10ns[$sBaseLanguage]->group_name;
            LimeExpressionManager::StartProcessingGroup($oGroup->gid, false, $iSurveyID);
            if (!$initializedReplacementFields) {
                templatereplace("{SITENAME}"); // Hack to ensure the EM sets values of LimeReplacementFields
                $initializedReplacementFields = true;
            }

            $qs = array();

            foreach ($oGroup->questions as $question) {
                $relevance = $question->relevance == '' ? 1 : $question->relevance;
                $questionText = sprintf(
                    '[{%s}] %s % s',
                    $relevance,
                    $question->title,
                    $question->questionl10ns[$sBaseLanguage]->question
                );
                LimeExpressionManager::ProcessString($questionText, $question->qid);
                $questionData['question'] = viewHelper::stripTagsEM(LimeExpressionManager::GetLastPrettyPrintExpression());
                $questionData['gid'] = $oGroup->gid;
                $questionData['qid'] = $question->qid;
                $questionData['title'] = $question->title;
                $qs[] = $questionData;
            }
            $groupData[$iGID]['questions'] = $qs;
            LimeExpressionManager::FinishProcessingGroup();
        }
        LimeExpressionManager::FinishProcessingPage();

        $aData['aGroupsAndQuestions'] = $groupData;
        $aData['surveyid'] = $iSurveyID;
        $aData['surveyActivated'] = $survey->getIsActive();
        return $aData;
    }

    /**
     * Get the new question organization from the post data.
     * This function replaces parse_str, since parse_str
     * is bound by max_input_vars.
     *
     * @return array
     */
    private function getOrgdata()
    {
        $request = Yii::app()->request;
        $orgdata = $request->getPost('orgdata', '');
        $ex = explode('&', $orgdata);
        $vars = array();
        foreach ($ex as $str) {
            list($list, $target) = explode('=', $str);
            $list = str_replace('list[', '', $list);
            $list = str_replace(']', '', $list);
            $vars[$list] = $target;
        }

        return $vars;
    }

    /**
     * Returns Data for Plugin tab.
     * survey::_pluginTabSurvey()
     * Load "Simple Plugin" page in specific survey.
     *
     * @param Survey $survey Given Survey
     *
     * @return array
     *
     * This method is called via call_user_func in self::rendersidemenulink()
     * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
     */
    protected function pluginTabSurvey($survey)
    {
        $aData = array();
        $beforeSurveySettings = new PluginEvent('beforeSurveySettings');
        $beforeSurveySettings->set('survey', $survey->sid);
        App()->getPluginManager()->dispatchEvent($beforeSurveySettings);
        $aData['pluginSettings'] = $beforeSurveySettings->get('surveysettings');
        return $aData;
    }

    /**
     * Update the theme of a survey
     *
     * @param int $iSurveyID Survey ID
     * @param string $template The survey theme name
     * @param array $aResults If the method is called from changeMultipleTheme(), it will update its array of results
     * @param boolean $bReturn Should the method update and return aResults
     *
     * @return mixed                 null or array
     *
     * @access public
     */
    public function changeTemplate($iSurveyID, $template, $aResults = null, $bReturn = false)
    {
        $iSurveyID = sanitize_int($iSurveyID);
        $sTemplate = sanitize_dirname($template);

        $survey = Survey::model()->findByPk($iSurveyID);

        if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) {
            if (!empty($bReturn)) {
                $aResults[$iSurveyID]['title'] = $survey->correct_relation_defaultlanguage->surveyls_title;
                $aResults[$iSurveyID]['result'] = false;
                $aResults[$iSurveyID]['error'] = gT("User does not have valid permissions");
                return $aResults;
            } else {
                die('No permission');
            }
        } elseif (!Permission::model()->hasGlobalPermission('templates', 'read') && !Permission::model()->hasTemplatePermission($template)) {
            if (!empty($bReturn)) {
                $aResults[$iSurveyID]['title'] = $survey->correct_relation_defaultlanguage->surveyls_title;
                $aResults[$iSurveyID]['result'] = false;
                $aResults[$iSurveyID]['error'] = gT("User does not have permission to use this theme");
                return $aResults;
            } else {
                die('No permission');
            }
        }

        $survey->template = $sTemplate;
        $survey->save();

        $oTemplateConfiguration = $survey->surveyTemplateConfiguration;
        $oTemplateConfiguration->template_name = $sTemplate;
        $oTemplateConfiguration->save();

        // This will force the generation of the entry for survey group
        TemplateConfiguration::checkAndcreateSurveyConfig($iSurveyID);

        if (!empty($bReturn)) {
            $aResults[$iSurveyID]['title'] = $survey->correct_relation_defaultlanguage->surveyls_title;
            $aResults[$iSurveyID]['result'] = true;
            return $aResults;
        }
    }

    /**
     * This method will return the url for the current survey and set
     * the direction for the sidemenue.
     *
     * @param integer $sid Given Survey ID
     * @param integer $gid Given Group ID
     * @param integer $qid Given Question ID
     * @param string $landOnSideMenuTab Given SideMenuTab
     *
     * @return string
     */
    public function getSurveyAndSidemenueDirectionURL($sid, $gid, $qid, $landOnSideMenuTab)
    {
        $url = !empty($qid) ? 'questionAdministration/view/' : 'questionGroupsAdministration/view/';
        $params = [
            'surveyid' => $sid,
            'gid' => $gid,
        ];
        if (!empty($qid)) {
            $params['qid'] = $qid;
        }
        $params['landOnSideMenuTab'] = $landOnSideMenuTab;
        return $this->createUrl($url, $params);
    }

    /**
     * This private function creates a sample group
     *
     * @param int $iSurveyID The survey ID that the sample group will belong to
     *
     * @return int
     */
    private function createSampleGroup($iSurveyID)
    {
        // Now create a new dummy group
        $sLanguage = Survey::model()->findByPk($iSurveyID)->language;
        $oGroup = new QuestionGroup();
        $oGroup->sid = $iSurveyID;
        $oGroup->group_order = 1;
        $oGroup->grelevance = '1';
        $oGroup->save();
        $oGroupL10ns = new QuestionGroupL10n();
        $oGroupL10ns->gid = $oGroup->gid;
        $oGroupL10ns->group_name = gT('My first question group', 'html', $sLanguage);
        $oGroupL10ns->language = $sLanguage;
        $oGroupL10ns->save();
        LimeExpressionManager::SetEMLanguage($sLanguage);
        return $oGroup->gid;
    }

    /**
     * This private function creates a sample question
     *
     * @param int $iSurveyID The survey ID that the sample question will belong to
     * @param int $iGroupID The group ID that the sample question will belong to
     *
     * @return int
     */
    private function createSampleQuestion($iSurveyID, $iGroupID)
    {
        // Now create a new dummy question
        $sLanguage = Survey::model()->findByPk($iSurveyID)->language;
        $oQuestion = new Question();
        $oQuestion->sid = $iSurveyID;
        $oQuestion->gid = $iGroupID;
        $oQuestion->type = Question::QT_M_MULTIPLE_CHOICE;
        $oQuestion->title = 'Q00';
        $oQuestion->mandatory = 'N';
        $oQuestion->relevance = '1';
        $oQuestion->question_order = 1;
        $oQuestion->save();

        $oQuestionLS = new QuestionL10n();
        $oQuestionLS->question = '';
        $oQuestionLS->help = '';
        $oQuestionLS->language = $sLanguage;
        $oQuestionLS->qid = $oQuestion->qid;
        $oQuestionLS->save();

        $editorEnabled = App()->getConfig('editorEnabled') ?? false;
        if (!$editorEnabled) {
            $this->createSampleSubquestion(
                1,
                $iSurveyID,
                $iGroupID,
                $oQuestion->qid,
                $sLanguage,
                gT('Option A')
            );
            $this->createSampleSubquestion(
                2,
                $iSurveyID,
                $iGroupID,
                $oQuestion->qid,
                $sLanguage,
                gT('Option B')
            );
        }

        return $oQuestion->qid;
    }

    /**
     * Creates a sample subquestion for a parent question in a survey
     *
     * This method creates a new subquestion with the specified parameters and saves it to the database.
     * It also creates the corresponding localization entry for the subquestion.
     *
     * @param int $number The sequence number for the subquestion, used for ordering and title generation
     * @param int $surveyId The ID of the survey to which this subquestion belongs
     * @param int $groupId The ID of the question group to which this subquestion belongs
     * @param int $questionId The ID of the parent question to which this subquestion is attached
     * @param string $language The language code for the subquestion's text
     * @param string $text The actual text content of the subquestion
     *
     * @return void
     */
    private function createSampleSubquestion(
        int $number,
        int $surveyId,
        int $groupId,
        int $questionId,
        string $language,
        string $text
    ) {
        $subQuestion = new Question();
        $subQuestion->parent_qid = $questionId;
        $subQuestion->sid = $surveyId;
        $subQuestion->gid = $groupId;
        $subQuestion->type = Question::QT_T_LONG_FREE_TEXT;
        $subQuestion->title = 'SQ00' . $number;
        $subQuestion->question_order = $number;
        $subQuestion->relevance = 1;
        $subQuestion->save();

        $subQuestionL10n = new QuestionL10n();
        $subQuestionL10n->question = $text;
        $subQuestionL10n->help = '';
        $subQuestionL10n->language = $language;
        $subQuestionL10n->qid = $subQuestion->qid;
        $subQuestionL10n->save();
    }

    /**
     * Adds some other important adata variables for frontend
     *
     * this function came from Layouthelper
     *
     * @param array $aData pointer to array (this array will be changed here!!)
     *
     * @throws CException
     */
    private function surveysummary(&$aData)
    {
        $iSurveyID = $aData['surveyid'];

        $aSurveyInfo = getSurveyInfo($iSurveyID);
        /** @var Survey $oSurvey */
        if (!isset($aData['oSurvey'])) {
            $aData['oSurvey'] = Survey::model()->findByPk($aData['surveyid']);
        }
        $oSurvey = $aData['oSurvey'];
        $activated = $aSurveyInfo['active'];

        $condition = array('sid' => $iSurveyID, 'parent_qid' => 0);
        $sumcount3 = Question::model()->countByAttributes($condition); //Checked
        $sumcount2 = QuestionGroup::model()->countByAttributes(array('sid' => $iSurveyID));
        $accessMode = $aSurveyInfo['access_mode'];

        //SURVEY SUMMARY
        $aAdditionalLanguages = $oSurvey->additionalLanguages;
        $surveysummary2 = [];
        if ($aSurveyInfo['anonymized'] != "N") {
            $surveysummary2[] = gT("Responses to this survey are anonymized.");
        } else {
            $surveysummary2[] = gT("Responses to this survey are NOT anonymized.");
        }
        if ($aSurveyInfo['format'] == "S") {
            $surveysummary2[] = gT("It is presented question by question.");
        } elseif ($aSurveyInfo['format'] == "G") {
            $surveysummary2[] = gT("It is presented group by group.");
        } else {
            $surveysummary2[] = gT("It is presented on one single page.");
        }
        if ($aSurveyInfo['questionindex'] > 0) {
            if ($aSurveyInfo['format'] == 'A') {
                $surveysummary2[] = gT("No question index will be shown with this format.");
            } elseif ($aSurveyInfo['questionindex'] == 1) {
                $surveysummary2[] = gT("A question index will be shown; participants will be able to jump between viewed questions.");
            } elseif ($aSurveyInfo['questionindex'] == 2) {
                $surveysummary2[] = gT("A full question index will be shown; participants will be able to jump between relevant questions.");
            }
        }
        if ($oSurvey->isDateStamp) {
            $surveysummary2[] = gT("Responses will be date stamped.");
        }
        if ($oSurvey->isIpAddr) {
            $surveysummary2[] = gT("IP Addresses will be logged");
        }
        if ($oSurvey->isRefUrl) {
            $surveysummary2[] = gT("Referrer URL will be saved.");
        }
        if ($oSurvey->isUseCookie) {
            $surveysummary2[] = gT("It uses cookies for access control.");
        }
        if ($oSurvey->isAllowRegister) {
            $surveysummary2[] = gT("If participant access codes are used, the public may register for this survey");
        }
        if ($oSurvey->isAllowSave && !$oSurvey->isTokenAnswersPersistence) {
            $surveysummary2[] = gT("Participants can save partially finished surveys");
        }
        if ($oSurvey->emailnotificationto != '') {
            $surveysummary2[] = gT("Basic email notification is sent to:") . ' ' . htmlspecialchars((string)$aSurveyInfo['emailnotificationto']);
        }
        if ($oSurvey->emailresponseto != '') {
            $surveysummary2[] = gT("Detailed email notification with response data is sent to:") . ' ' . htmlspecialchars((string)$aSurveyInfo['emailresponseto']);
        }

        $dateformatdetails = getDateFormatData(Yii::app()->session['dateformat']);
        if (trim((string)$oSurvey->startdate) != '') {
            Yii::import('application.libraries.Date_Time_Converter');
            $datetimeobj = new Date_Time_Converter($oSurvey->startdate, 'Y-m-d H:i:s');
            $aData['startdate'] = $datetimeobj->convert($dateformatdetails['phpdate'] . ' H:i');
        } else {
            $aData['startdate'] = "-";
        }

        if (trim((string)$oSurvey->expires) != '') {
            Yii::import('application.libraries.Date_Time_Converter');
            $datetimeobj = new Date_Time_Converter($oSurvey->expires, 'Y-m-d H:i:s');
            $aData['expdate'] = $datetimeobj->convert($dateformatdetails['phpdate'] . ' H:i');
        } else {
            $aData['expdate'] = "-";
        }

        $aData['language'] = getLanguageNameFromCode($oSurvey->language, false);

        if ($oSurvey->currentLanguageSettings->surveyls_urldescription == "") {
            $aSurveyInfo['surveyls_urldescription'] = htmlspecialchars((string) $aSurveyInfo['surveyls_url']);
        }

        if ($oSurvey->currentLanguageSettings->surveyls_url != "") {
            $aData['endurl'] = " <a target='_blank' href=\"" .
                htmlspecialchars((string) $aSurveyInfo['surveyls_url']) .
                "\" title=\"" .
                htmlspecialchars((string) $aSurveyInfo['surveyls_url']) .
                "\">" .
                flattenText($oSurvey->currentLanguageSettings->surveyls_url) .
                "</a>";
        } else {
            $aData['endurl'] = "-";
        }

        $aData['sumcount3'] = $sumcount3;
        $aData['sumcount2'] = $sumcount2;
        $aData['accessMode'] = $accessMode;

        if ($activated == "N") {
            $aData['activatedlang'] = gT("No");
        } else {
            $aData['activatedlang'] = gT("Yes");
        }

        $aData['activated'] = $activated;
        if ($oSurvey->isActive) {
            $aData['surveydb'] = Yii::app()->db->tablePrefix . "survey_" . $iSurveyID;
        }

        $aData['warnings'] = [];
        if ($activated == "N" && $sumcount3 == 0) {
            $aData['warnings'][] = gT("Survey cannot be activated yet.");
            if ($sumcount2 == 0 && Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'create')) {
                $aData['warnings'][] = "<span class='statusentryhighlight'>[" . gT("You need to add question groups") . "]</span>";
            }
            if ($sumcount3 == 0 && Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'create')) {
                $aData['warnings'][] = "<span class='statusentryhighlight'>" . gT("You need to add questions") . "</span>";
            }
        }
        $aData['hints'] = $surveysummary2;

        //return (array('column'=>array($columns_used,$hard_limit) , 'size' => array($length, $size_limit) ));
        //        $aData['tableusage'] = getDBTableUsage($iSurveyID);
        // ToDo: Table usage is calculated on every menu display which is too slow with big surveys.
        // Needs to be moved to a database field and only updated if there are question/subquestions added/removed (it's currently also not functional due to the port)

        $aData['tableusage'] = false;
        $aData['aAdditionalLanguages'] = $aAdditionalLanguages;
        $aData['groups_count'] = $sumcount2;

        // We get the state of the quickaction
        // If the survey is new (ie: it has no group), it is opened by default
        $quickactionState = SettingsUser::getUserSettingValue('quickaction_state');
        if ($quickactionState === null || $quickactionState === 0) {
            $quickactionState = 1;
            SettingsUser::setUserSetting('quickaction_state', 1);
        }
        $aData['quickactionstate'] = $quickactionState !== null ? intval($quickactionState) : 1;
        $aData['subviewData'] = $aData;

        Yii::app()->getClientScript()->registerPackage('surveysummary');
    }

    /**
     * Load survey information based on $action.
     * survey::_fetchSurveyInfo()
     *
     * @param string $action Given Action
     * @param int $iSurveyID Given Survey ID
     *
     * @return void | array
     *
     * @deprecated use Survey objects instead
     */
    private function fetchSurveyInfo($action, $iSurveyID = null)
    {
        if ($action == 'newsurvey') {
            $oSurvey = new Survey();
        } elseif ($action == 'editsurvey' && $iSurveyID) {
            $oSurvey = Survey::model()->findByPk($iSurveyID);
        }

        if (isset($oSurvey)) {
            $attribs = $oSurvey->attributes;
            $attribs['googleanalyticsapikeysetting'] = $oSurvey->getGoogleanalyticsapikeysetting();
            return $attribs;
        }
    }

    /**
     * Load "General" tab of new survey screen.
     * survey::_generalTabNewSurvey()
     *
     * @return array
     */
    private function generalTabNewSurvey()
    {
        // use survey option inheritance
        $user = User::model()->findByPk(Yii::app()->session['loginID']);
        $owner = $user->attributes;
        $owner['full_name'] = 'inherit';
        $owner['email'] = 'inherit';
        $owner['bounce_email'] = 'inherit';

        $aData = [];
        $aData['action'] = "newsurvey";
        $aData['owner'] = $owner;
        $aLanguageDetails = getLanguageDetails(Yii::app()->session['adminlang']);
        $aData['sRadixDefault'] = $aLanguageDetails['radixpoint'];
        $aData['sDateFormatDefault'] = $aLanguageDetails['dateformat'];
        $aRadixPointData = [];
        foreach (getRadixPointData() as $index => $radixptdata) {
            $aRadixPointData[$index] = $radixptdata['desc'];
        }
        $aData['aRadixPointData'] = $aRadixPointData;

        foreach (getDateFormatData(0, Yii::app()->session['adminlang']) as $index => $dateformatdata) {
            $aDateFormatData[$index] = $dateformatdata['dateformat'];
        }
        $aData['aDateFormatData'] = $aDateFormatData;

        return $aData;
    }

    /**
     * Returns Data for general template.
     *
     * @param integer $iSurveyID Given Survey ID
     *
     * @return array
     */
    private function getGeneralTemplateData($iSurveyID)
    {
        $aData = [];
        $aData['surveyid'] = $iSurveyID;
        $oSurvey = Survey::model()->findByPk($iSurveyID);
        if (empty($oSurvey)) {
            $oSurvey = new Survey();
        }
        $inheritOwner = empty($oSurvey->oOptions->ownerLabel) ? $oSurvey->owner_id : $oSurvey->oOptions->ownerLabel;
        $users = getUserList();
        $aData['users'] = array();
        $aData['users']['-1'] = gT('Inherit') . ' [' . $inheritOwner . ']';
        foreach ($users as $user) {
            $aData['users'][$user['uid']] = $user['user'] . ($user['full_name'] ? ' - ' . $user['full_name'] : '');
        }
        // Sort users by name
        asort($aData['users']);
        $aData['aSurveyGroupList'] = SurveysGroups::getSurveyGroupsList();
        return $aData;
    }

    /**
     * Returns data for text edit.
     *
     * BE CAREFUL (this function is not called directly, but by call_user_func_array and the name of function in db .. )
     *
     * @param Survey $survey Given Survey.
     *
     * @return array
     */
    protected function getTextEditData($survey)
    {
        Yii::app()->getClientScript()->registerScript(
            "TextEditDataGlobal",
            //todo: this has to be changed, also in frontend packages/textelements/...
            //NEW: connectorBaseUrl: '".Yii::app()->getController()->createUrl('/surveyAdministration/getDateFormatOptions', ['sid' => $survey->sid])."',
            //// ['sid' => $survey->sid]) . "',  --> sid should be taken from frontend ...
            "window.TextEditData = {
                connectorBaseUrl: '" . Yii::app()->getController()->createUrl('surveyAdministration/') . "',
                isNewSurvey: " . ($survey->getIsNewRecord() ? "true" : "false") . ",
                sid: $survey->sid,
                i10N: {
                    'Survey title' : '" . gT('Survey title') . "',
                    'Date format' : '" . gT('Date format') . "',
                    'Decimal mark' : '" . gT('Decimal mark') . "',
                    'End url' : '" . gT('End url') . "',
                    'URL description (link text)' : '" . gT('URL description (link text)') . "',
                    'Description' : '" . gT('Description') . "',
                    'Welcome' : '" . gT('Welcome') . "',
                    'End message' : '" . gT('End message') . "'
                }
            };",
            LSYii_ClientScript::POS_BEGIN
        );

        App()->getClientScript()->registerPackage('ace');
        return [];
    }

    /**
     * Returns Date for Data Security Edit.
     * tab_edit_view_datasecurity
     * editDataSecurityLocalSettings_view
     *
     * @param Survey $survey Given Survey
     *
     * @return array
     */
    protected function getDataSecurityEditData($survey)
    {
        Yii::app()->loadHelper("admin.htmleditor");
        $aData = $aTabTitles = $aTabContents = array();

        $aData['scripts'] = PrepareEditorScript(false, $this);
        $aLanguageData = [];

        foreach ($survey->allLanguages as $i => $sLang) {
            $aLanguageData = $this->getGeneralTemplateData($survey->sid);
            // this one is created to get the right default texts fo each language
            Yii::app()->loadHelper('database');
            Yii::app()->loadHelper('surveytranslator');

            $aSurveyLanguageSettings = SurveyLanguageSetting::model()->findByPk(array('surveyls_survey_id' => $survey->sid, 'surveyls_language' => $sLang))->getAttributes();

            $aTabTitles[$sLang] = getLanguageNameFromCode($aSurveyLanguageSettings['surveyls_language'], false);

            if ($aSurveyLanguageSettings['surveyls_language'] == $survey->language) {
                $aTabTitles[$sLang] .= ' (' . gT("Base language") . ')';
            }

            $aLanguageData['aSurveyLanguageSettings'] = $aSurveyLanguageSettings;
            $aLanguageData['action'] = "surveygeneralsettings";
            $aLanguageData['subaction'] = gT('Add a new question');
            $aLanguageData['i'] = $i;
            $aLanguageData['dateformatdetails'] = getDateFormatData(Yii::app()->session['dateformat']);
            $aLanguageData['oSurvey'] = $survey;
            $aTabContents[$sLang] = $this->renderPartial('/admin/survey/editDataSecurityLocalSettings_view', $aLanguageData, true);
        }

        $aData['aTabContents'] = $aTabContents;
        $aData['aTabTitles'] = $aTabTitles;
        return $aData;
    }

    /**
     * Returns Data for Tab General Edit Survey.
     * survey::_generalTabEditSurvey()
     * Load "General" tab of edit survey screen.
     *
     * @param Survey $survey Given Survey
     *
     * @return mixed
     */
    protected function generalTabEditSurvey($survey)
    {
        $aData['survey'] = $survey;
        return $aData;
    }

    /**
     * Returns data for tab Presentation navigation.
     * survey::_tabPresentationNavigation()
     * Load "Presentation & navigation" tab.
     *
     * @param mixed $survey ?
     *
     * @return array
     */
    protected function tabPresentationNavigation($survey)
    {
        $aData = [];
        $aData['esrow'] = $survey;
        return $aData;
    }

    /**
     * Returns the data for Tab Publication Access control.
     * survey::_tabPublicationAccess()
     * Load "Publication * access control" tab.
     *
     * @param Survey $survey Given Survey
     *
     * @return array
     */
    protected function tabPublicationAccess($survey)
    {
        $aDateFormatDetails = getDateFormatData(Yii::app()->session['dateformat']);
        $aData = [];
        $aData['dateformatdetails'] = $aDateFormatDetails;
        $aData['survey'] = $survey;
        return $aData;
    }

    /**
     * Returns the data for Tab Notification and Data Management.
     * survey::_tabNotificationDataManagement()
     * Load "Notification & data management" tab.
     *
     * @param mixed $survey ?
     *
     * @return array
     */
    protected function tabNotificationDataManagement($survey)
    {
        $aData = [];
        $aData['esrow'] = $survey;
        return $aData;
    }

    /**
     * Returns the data for Tab Tokens.
     * survey::_tabTokens()
     * Load "Tokens" tab.
     *
     * @param mixed $survey ?
     *
     * @return array
     */
    protected function tabTokens($survey)
    {
        $aData = [];
        $aData['esrow'] = $survey;
        return $aData;
    }

    /**
     * Returns the data for Tab Panel Integration.
     *
     * @param Survey $survey Given Survey
     * @param string|null $sLang  Given Language
     *
     * @return array
     */
    protected function tabPanelIntegration($survey, $sLang = null)
    {
        $aData = [];
        $oResult = Question::model()->with('subquestions')->findAll("t.sid={$survey->sid} AND (t.type = 'T'  OR t.type = 'Q'  OR  t.type = 'S') AND t.parent_qid = 0");
        $aQuestions = [];
        foreach ($oResult as $oRecord) {
            if (count($oRecord->subquestions)) {
                foreach ($oRecord->subquestions as $oSubquestion) {
                    $aQuestions[] = array_merge(
                        $oRecord->attributes,
                        $oRecord->questionl10ns[$survey->language]->attributes,
                        array(
                            'sqid' => $oSubquestion->qid,
                            'sqtitle' => $oSubquestion->title,
                            'sqquestion' => $oSubquestion->questionl10ns[$survey->language]->question
                        )
                    );
                }
            } else {
                $aQuestions[] = array_merge(
                    $oRecord->attributes,
                    $oRecord->questionl10ns[$survey->language]->attributes,
                    array(
                        'sqid' => null,
                        'sqtitle' => null,
                        'sqquestion' => null
                    )
                );
            }
        }

        $aData['jsData'] = [
            'i10n' => [
                'ID' => gT('ID'),
                'Action' => gT('Action'),
                'Parameter' => gT('Parameter'),
                'Target question' => gT('Target question'),
                'Survey ID' => gT('Survey ID'),
                'Question ID' => gT('Question ID'),
                'Subquestion ID' => gT('Subquestion ID'),
                'Add URL parameter' => gT('Add URL parameter'),
                'Edit URL parameter' => gT('Edit URL parameter'),
                'No target question' => gT('(No target question)'),
                'Are you sure you want to delete this URL parameter?' => gT('Are you sure you want to delete this URL parameter?'),
                'No parameters defined' => gT('No parameters defined'),
                'Search prompt' => gT('Search:'),
                'Progress' => gT('Showing _START_ to _END_ of _TOTAL_ entries'),
                'No, cancel' => gT('No, cancel'),
                'Yes, delete' => gT('Yes, delete'),
                'Save' => gT('Save'),
                'Cancel' => gT('Cancel'),
            ],
            "surveyid" => $survey->sid,
            "getParametersUrl" => Yii::app()->createUrl('surveyAdministration/getUrlParamsJson', array('surveyid' => $survey->sid)),
        ];
        $aData['questions'] = $aQuestions;

        $model = new SurveyURLParameter('search');
        $model->sid = $survey->sid;
        $model->searched_value = Yii::app()->request->getParam('search_query');

        $aData['updateUrl'] = Yii::app()->createUrl('surveyAdministration/rendersidemenulink', ['surveyid' => $survey->sid, 'subaction' => 'panelintegration']);

        if (isset($_GET['pageSize'])) {
            Yii::app()->user->setState('pageSize', (int) $_GET['pageSize']);
        }

        $aData['model'] = $model;

        App()->getClientScript()->registerPackage('jquery-datatable-bs5');
        return $aData;
    }

    /**
     * Method to save URL Params (Panel Integration)
     *
     * @throws CException
     */
    public function actionSaveUrlParam()
    {
        $paramData = Yii::app()->request->getPost('URLParam');
        if (empty($paramData)) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                ['data' => ['success' => false, 'message' => gT("Invalid request")]]
            );
        }

        $surveyId = sanitize_int(Yii::app()->request->getPost('surveyId'));
        if (!Permission::model()->hasSurveyPermission($surveyId, 'surveysettings', 'update')) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                ['data' => ['success' => false, 'message' => gT("Access denied!")]]
            );
        }

        // Based on Database::actionUpdateSurveyLocaleSettings()
        $paramData['parameter'] = trim($paramData['parameter'] ?? '');
        if (
            $paramData['parameter'] == ''
            || !preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $paramData['parameter'])
            || $paramData['parameter'] == 'sid'
            || $paramData['parameter'] == 'newtest'
            || $paramData['parameter'] == 'token'
            || $paramData['parameter'] == 'lang'
        ) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                ['data' => ['success' => false, 'message' => gT("Invalid URL parameter")]]
            );
        }

        if ($paramData['targetqid'] == '') {
            $paramData['targetqid'] = null;
        }
        if ($paramData['targetsqid'] == '') {
            $paramData['targetsqid'] = null;
        }

        $paramId = !empty($paramData['id']) ? sanitize_int($paramData['id']) : null;
        if (empty($paramId)) {
            $URLParam = new SurveyURLParameter();
            $paramData['sid'] = $surveyId;
        } else {
            $URLParam = SurveyURLParameter::model()->findByPk($paramId);
            if (empty($URLParam || $URLParam->sid != $surveyId)) {
                return $this->renderPartial(
                    '/admin/super/_renderJson',
                    ['data' => ['success' => false, 'message' => gT("URL parameter not found")]]
                );
            }
            unset($paramData['id']);
        }

        $URLParam->setAttributes($paramData);
        if ($URLParam->save()) {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                ['data' => ['success' => true, 'message' => gT("URL parameter saved")]]
            );
        } else {
            return $this->renderPartial(
                '/admin/super/_renderJson',
                ['data' => ['success' => false, 'message' => gT("Could not save URL parameter"), 'errors' => $URLParam->getErrors()]]
            );
        }
    }

    /**
     * Method to delete URL Params (Panel Integration)
     *
     * @return void
     * @throws CDbException
     * @throws CHttpException
     */
    public function actionDeleteUrlParam()
    {
        $surveyId = sanitize_int(Yii::app()->request->getPost('surveyId'));
        $redirectUrl = ['surveyAdministration/rendersidemenulink/', 'surveyid' => $surveyId, 'subaction' => 'panelintegration'];
        $paramId = Yii::app()->request->getPost('urlParamId');
        if (empty($paramId)) {
            throw new CHttpException(400, gT('Invalid request'));
        }

        if (!Permission::model()->hasSurveyPermission($surveyId, 'surveysettings', 'update')) {
            throw new CHttpException(403, gT("Access denied!"));
        }

        $paramId = sanitize_int($paramId);
        $URLParam = SurveyURLParameter::model()->findByPk($paramId);
        if (empty($URLParam)) {
            throw new CHttpException(400, gT("URL parameter not found"));
        }

        // Delete the record
        if ($URLParam->delete()) {
            Yii::app()->user->setFlash('success', gT("URL parameter deleted"));
        } else {
            Yii::app()->user->setFlash('error', gT("Could not delete URL parameter"));
        }
        $this->redirect($redirectUrl);
    }

    /**
     * Retrieves and renders a list of surveys with optional active status filter for the box widget Ajax.
     *
     * @return string|false Rendered partial view if surveys are found, otherwise false.
     * @throws CException
     */
    public function actionBoxList()
    {
        $limit = (int)App()->request->getQuery('limit');
        $page = (int)App()->request->getQuery('page');

        $model = Survey::model();
        if ($state = App()->request->getQuery('active')) {
            $model->active = $state;
            $surveys = $model
                ->search(['pageSize' => $limit, 'currentPage' => $page]);
        } else {
            $surveys = $model
                ->search(['pageSize' => $limit, 'currentPage' => $page]);
        }


        $boxes = [];
        foreach ($surveys->getData() as $survey) {
            $state = strip_tags($survey->getRunning());
            $boxes[] = [
                'survey' => $survey,
                'type' => 0,
                'external' => false,
                'iconAlter' => $state,
                'state' => $survey->getState(),
                'buttons' => $survey->getButtons(),
                'link' => App()->createUrl('/surveyAdministration/view/surveyid/' . $survey->sid),
            ];
        }

        return $this->renderPartial(
            'ext.admin.BoxesWidget.views.box',
            array(
                'items' => $boxes
            )
        );
    }

    /**
     * AJAX action to update survey access mode
     */
    public function actionUpdateAccessMode()
    {
        $surveyId = (int) Yii::app()->request->getPost('surveyId');
        $accessMode = Yii::app()->request->getPost('accessMode');

        if (!$surveyId || !$accessMode) {
            $this->renderJSON(['success' => false, 'message' => 'Missing parameters']);
            return;
        }

        try {
            $surveyAccessModeService = new SurveyAccessModeService(
                Permission::model(),
                Survey::model(),
                Yii::app()
            );

            $result = $surveyAccessModeService->changeAccessMode($surveyId, $accessMode);

            if ($result) {
                $this->renderJSON([
                    'success' => true,
                    'message' => 'Access mode updated successfully',
                    'accessMode' => $accessMode
                ]);
            } else {
                $this->renderJSON(['success' => false, 'message' => 'No changes made']);
            }
        } catch (Exception $e) {
            $this->renderJSON(['success' => false, 'message' => $e->getMessage()]);
        }
    }
}
