Exemplo n.º 1
0
 public function actionCron($interval)
 {
     $pm = \Yii::app()->pluginManager;
     $event = new PluginEvent('cron');
     $event->set('interval', $interval);
     $pm->dispatchEvent($event);
 }
Exemplo n.º 2
0
 public function actionPublicList($lang = null)
 {
     if (!empty($lang)) {
         App()->setLanguage($lang);
     } else {
         App()->setLanguage(App()->getConfig('defaultlang'));
     }
     $oTemplate = Template::model()->getInstance(Yii::app()->getConfig("defaulttemplate"));
     if ($oTemplate->cssFramework == 'bootstrap') {
         // We now use the bootstrap package isntead of the Yiistrap TbApi::register() method
         // Then instead of using the composer dependency system for templates
         // We can use the package dependency system
         Yii::app()->getClientScript()->registerMetaTag('width=device-width, initial-scale=1.0', 'viewport');
         App()->bootstrap->registerAllScripts();
     }
     $aData = array('publicSurveys' => Survey::model()->active()->open()->public()->with('languagesettings')->findAll(), 'futureSurveys' => Survey::model()->active()->registration()->public()->with('languagesettings')->findAll());
     $htmlOut = $this->render('publicSurveyList', $aData, true);
     $event = new PluginEvent('beforeSurveysStartpageRender', $this);
     $event->set('aData', $aData);
     App()->getPluginManager()->dispatchEvent($event);
     if ($event->get('result')) {
         $htmlFromEvent = $event->get('result');
         $htmlOut = $htmlFromEvent['html'];
     }
     echo $htmlOut;
 }
 /**
  * method for dispatching plugin events
  *
  * See {@link find()} for detailed explanation about $condition and $params.
  * @param string $sEventName event name to dispatch
  * @param array	$criteria array containing attributes, conditions and params for the filter query
  * @return PluginEvent the dispatched event
  */
 public function dispatchPluginModelEvent($sEventName, $criteria = null)
 {
     $oPluginEvent = new PluginEvent($sEventName, $this);
     $oPluginEvent->set('model', $this->owner);
     if (isset($criteria)) {
         $oPluginEvent->set('filterCriteria', $criteria);
     }
     return App()->getPluginManager()->dispatchEvent($oPluginEvent);
 }
Exemplo n.º 4
0
 /**
  * Root function for any export results action
  *
  * @param mixed $iSurveyId
  * @param mixed $sLanguageCode
  * @param csv|doc|pdf|xls $sExportPlugin Type of export
  * @param FormattingOptions $oOptions
  * @param string $sFilter 
  */
 function exportSurvey($iSurveyId, $sLanguageCode, $sExportPlugin, FormattingOptions $oOptions, $sFilter = '')
 {
     //Do some input validation.
     if (empty($iSurveyId)) {
         safeDie('A survey ID must be supplied.');
     }
     if (empty($sLanguageCode)) {
         safeDie('A language code must be supplied.');
     }
     if (empty($oOptions)) {
         safeDie('Formatting options must be supplied.');
     }
     if (empty($oOptions->selectedColumns)) {
         safeDie('At least one column must be selected for export.');
     }
     //echo $oOptions->toString().PHP_EOL;
     $writer = null;
     $iSurveyId = sanitize_int($iSurveyId);
     if ($oOptions->output == 'display') {
         header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
         header("Pragma: public");
     }
     $exports = $this->getExports();
     if (array_key_exists($sExportPlugin, $exports) && !empty($exports[$sExportPlugin])) {
         // This must be a plugin, now use plugin to load the right class
         $event = new PluginEvent('newExport');
         $event->set('type', $sExportPlugin);
         $oPluginManager = App()->getPluginManager();
         $oPluginManager->dispatchEvent($event, $exports[$sExportPlugin]);
         $writer = $event->get('writer');
     }
     if (!$writer instanceof IWriter) {
         throw new Exception(sprintf('Writer for %s should implement IWriter', $sExportPlugin));
     }
     $surveyDao = new SurveyDao();
     $survey = $surveyDao->loadSurveyById($iSurveyId, $sLanguageCode);
     $writer->init($survey, $sLanguageCode, $oOptions);
     $surveyDao->loadSurveyResults($survey, $oOptions->responseMinRecord, $oOptions->responseMaxRecord, $sFilter, $oOptions->responseCompletionState);
     $writer->write($survey, $sLanguageCode, $oOptions, true);
     $result = $writer->close();
     // Close resultset if needed
     if ($survey->responses instanceof CDbDataReader) {
         $survey->responses->close();
     }
     if ($oOptions->output == 'file') {
         return $writer->filename;
     } else {
         return $result;
     }
 }
Exemplo n.º 5
0
 public function authenticate()
 {
     // First initialize the result, we can later retieve it to get the exact error code/message
     $result = new LSAuthResult(self::ERROR_NONE);
     // Check if the ip is locked out
     if (FailedLoginAttempt::model()->isLockedOut()) {
         $message = sprintf(gT('You have exceeded the number of maximum login attempts. Please wait %d minutes before trying again.'), App()->getConfig('timeOutTime') / 60);
         $result->setError(self::ERROR_IP_LOCKED_OUT, $message);
     }
     // If still ok, continue
     if ($result->isValid()) {
         if (is_null($this->plugin)) {
             $result->setError(self::ERROR_UNKNOWN_HANDLER);
         } else {
             // Delegate actual authentication to plugin
             $authEvent = new PluginEvent('newUserSession', $this);
             $authEvent->set('identity', $this);
             App()->getPluginManager()->dispatchEvent($authEvent, array($this->plugin));
             $pluginResult = $authEvent->get('result');
             if ($pluginResult instanceof LSAuthResult) {
                 //print_r($pluginResult);
                 $result = $pluginResult;
             } else {
                 //echo 'out result';
                 $result->setError(self::ERROR_UNKNOWN_IDENTITY);
             }
         }
     }
     if ($result->isValid()) {
         // Perform postlogin
         //exit('you are in post login');
         $this->postLogin();
     } else {
         // Log a failed attempt
         //exit('you login failed');
         $userHostAddress = App()->request->getUserHostAddress();
         FailedLoginAttempt::model()->addAttempt($userHostAddress);
         App()->session->regenerateID();
         // Handled on login by Yii
     }
     $this->errorCode = $result->getCode();
     $this->errorMessage = $result->getMessage();
     return $result->isValid();
 }
Exemplo n.º 6
0
 protected function menuMain()
 {
     $title = CHtml::tag('strong', array(), gT('Administration'));
     if (Yii::app()->session['loginID']) {
         $title .= ' -- ' . gT("Logged in as:");
         $text = ' ' . Yii::app()->session['user'] . ' ' . CHtml::image(Yii::app()->getConfig('adminimageurl') . 'profile_edit.png', gT("Edit your personal preferences"));
         $title .= CHtml::tag('strong', array(), CHtml::link($text, array('admin/user', 'sa' => 'personalsettings')));
     }
     $menu['title'] = CHtml::tag('div', array('class' => 'menubar-title-left'), $title);
     $menu['role'] = 'main';
     $menu['imageUrl'] = App()->getConfig('adminimageurl');
     $menu['items']['left'][] = array('href' => array('admin/survey'), 'alt' => gT('Default administration page'), 'image' => 'home.png');
     $menu['items']['left'][] = 'separator';
     if (Permission::model()->hasGlobalPermission('users', 'read')) {
         $menu['items']['left'][] = array('href' => array('admin/user'), 'alt' => gT('Manage survey administrators'), 'image' => 'security.png');
     }
     $menu['items']['left'][] = $this->userGroups();
     $menu['items']['left'][] = $this->globalSettings();
     $menu['items']['left'][] = 'separator';
     $menu['items']['left'][] = $this->checkIntegrity();
     $menu['items']['left'][] = $this->dumpDatabase();
     $menu['items']['left'][] = 'separator';
     $menu['items']['left'][] = $this->editLabels();
     $menu['items']['left'][] = 'separator';
     $menu['items']['left'][] = $this->editTemplates();
     $menu['items']['left'][] = 'separator';
     $menu['items']['left'][] = $this->participantDatabase();
     $menu['items']['left'][] = $this->pluginManager();
     $surveys = getSurveyList(true);
     $tmpList = array();
     $timeadjust = getGlobalSetting('timeadjust');
     foreach ($surveys as $survey) {
         if ($survey['active'] != 'Y') {
             $group = gT("Inactive");
             $list = 'inactive';
         } elseif ($survey['expires'] != '' && $survey['expires'] < dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust)) {
             $group = gT("Expired");
             $list = 'expired';
         } else {
             $group = gT("Active");
             $list = 'active';
         }
         $tmpList[$list][] = array('id' => $survey['sid'], 'title' => $survey['surveyls_title'], 'group' => $group);
     }
     $surveyList = array();
     if (array_key_exists('active', $tmpList)) {
         $surveyList = array_merge($surveyList, $tmpList['active']);
     }
     if (array_key_exists('expired', $tmpList)) {
         $surveyList = array_merge($surveyList, $tmpList['expired']);
     }
     if (array_key_exists('inactive', $tmpList)) {
         $surveyList = array_merge($surveyList, $tmpList['inactive']);
     }
     $menu['items']['right'][] = array('title' => gT('Surveys:'), 'type' => 'select', 'name' => 'surveyid', 'route' => 'admin/survey/sa/view', 'param' => 'surveyid', 'empty' => gT('No surveys available.'), 'values' => $surveyList, 'value' => $this->surveyId);
     $menu['items']['right'][] = array('href' => array('admin/survey', 'sa' => 'index'), 'alt' => gT('Detailed list of surveys'), 'image' => 'surveylist.png');
     $menu['items']['right'][] = $this->createSurvey();
     $menu['items']['right'][] = 'separator';
     $menu['items']['right'][] = array('href' => array('admin/authentication', 'sa' => 'logout'), 'alt' => gT('Logout'), 'image' => 'logout.png');
     $menu['items']['right'][] = array('href' => "http://docs.limesurvey.org", 'alt' => gT('LimeSurvey online manual'), 'image' => 'showhelp.png');
     $event = new PluginEvent('afterAdminMenuLoad', $this);
     $event->set('menu', $menu);
     $result = App()->getPluginManager()->dispatchEvent($event);
     $menu = $result->get('menu');
     return $menu;
 }
Exemplo n.º 7
0
 function adduser()
 {
     if (!Permission::model()->hasGlobalPermission('users', 'create')) {
         Yii::app()->setFlashMessage(gT("You do not have sufficient rights to access this page."), 'error');
         $this->getController()->redirect(array("admin/user/sa/index"));
     }
     $new_user = flattenText(Yii::app()->request->getPost('new_user'), false, true);
     $aViewUrls = array();
     if (empty($new_user)) {
         $aViewUrls['message'] = array('title' => gT("Failed to add user"), 'message' => gT("A username was not supplied or the username is invalid."), 'class' => 'text-warning');
     } elseif (User::model()->find("users_name=:users_name", array(':users_name' => $new_user))) {
         $aViewUrls['message'] = array('title' => gT("Failed to add user"), 'message' => gT("The username already exists."), 'class' => 'text-warning');
     } else {
         $event = new PluginEvent('createNewUser');
         $event->set('errorCode', AuthPluginBase::ERROR_NOT_ADDED);
         $event->set('errorMessageTitle', gT("Failed to add user"));
         $event->set('errorMessageBody', gT("Plugin is not active"));
         App()->getPluginManager()->dispatchEvent($event);
         if ($event->get('errorCode') != AuthPluginBase::ERROR_NONE) {
             $aViewUrls['message'] = array('title' => $event->get('errorMessageTitle'), 'message' => $event->get('errorMessageBody'), 'class' => 'text-warning');
         } else {
             $iNewUID = $event->get('newUserID');
             $new_pass = $event->get('newPassword');
             $new_email = $event->get('newEmail');
             $new_full_name = $event->get('newFullName');
             // add default template to template rights for user
             Permission::model()->insertSomeRecords(array('uid' => $iNewUID, 'permission' => Yii::app()->getConfig("defaulttemplate"), 'entity' => 'template', 'read_p' => 1, 'entity_id' => 0));
             // add new user to userlist
             $sresult = User::model()->getAllRecords(array('uid' => $iNewUID));
             $srow = count($sresult);
             $userlist = getUserList();
             array_push($userlist, array("user" => $srow['users_name'], "uid" => $srow['uid'], "email" => $srow['email'], "password" => $srow["password"], "parent_id" => $srow['parent_id'], "create_survey" => $srow['create_survey'], "participant_panel" => $srow['participant_panel'], "configurator" => $srow['configurator'], "create_user" => $srow['create_user'], "delete_user" => $srow['delete_user'], "superadmin" => $srow['superadmin'], "manage_template" => $srow['manage_template'], "manage_label" => $srow['manage_label']));
             // send Mail
             $body = sprintf(gT("Hello %s,"), $new_full_name) . "<br /><br />\n";
             $body .= sprintf(gT("this is an automated email to notify that a user has been created for you on the site '%s'."), Yii::app()->getConfig("sitename")) . "<br /><br />\n";
             $body .= gT("You can use now the following credentials to log into the site:") . "<br />\n";
             $body .= gT("Username") . ": " . htmlspecialchars($new_user) . "<br />\n";
             // authent is not delegated to web server or LDAP server
             if (Yii::app()->getConfig("auth_webserver") === false && Permission::model()->hasGlobalPermission('auth_db', 'read', $iNewUID)) {
                 // send password (if authorized by config)
                 if (Yii::app()->getConfig("display_user_password_in_email") === true) {
                     $body .= gT("Password") . ": " . $new_pass . "<br />\n";
                 } else {
                     $body .= gT("Password") . ": " . gT("Please contact your LimeSurvey administrator for your password.") . "<br />\n";
                 }
             }
             $body .= "<a href='" . $this->getController()->createAbsoluteUrl("/admin") . "'>" . gT("Click here to log in.") . "</a><br /><br />\n";
             $body .= sprintf(gT('If you have any questions regarding this mail please do not hesitate to contact the site administrator at %s. Thank you!'), Yii::app()->getConfig("siteadminemail")) . "<br />\n";
             $subject = sprintf(gT("User registration at '%s'", "unescaped"), Yii::app()->getConfig("sitename"));
             $to = $new_user . " <{$new_email}>";
             $from = Yii::app()->getConfig("siteadminname") . " <" . Yii::app()->getConfig("siteadminemail") . ">";
             $extra = '';
             $classMsg = '';
             if (SendEmailMessage($body, $subject, $to, $from, Yii::app()->getConfig("sitename"), true, Yii::app()->getConfig("siteadminbounce"))) {
                 $extra .= "<br />" . gT("Username") . ": {$new_user}<br />" . gT("Email") . ": {$new_email}<br />";
                 $extra .= "<br />" . gT("An email with a generated password was sent to the user.");
                 $classMsg = 'text-success';
                 $sHeader = gT("Success");
             } else {
                 // has to be sent again or no other way
                 $tmp = str_replace("{NAME}", "<strong>" . $new_user . "</strong>", gT("Email to {NAME} ({EMAIL}) failed."));
                 $extra .= "<br />" . str_replace("{EMAIL}", $new_email, $tmp) . "<br />";
                 $classMsg = 'text-warning';
                 $sHeader = gT("Warning");
             }
             $aViewUrls['mboxwithredirect'][] = $this->_messageBoxWithRedirect(gT("Add user"), $sHeader, $classMsg, $extra, $this->getController()->createUrl("admin/user/sa/setuserpermissions"), gT("Set user permissions"), array('action' => 'setuserpermissions', 'user' => $new_user, 'uid' => $iNewUID));
         }
     }
     $this->_renderWrappedTemplate('user', $aViewUrls);
 }
Exemplo n.º 8
0
 /**
  * Launch the event newUnsecureRequest
  * @param $plugin : the target
  * @param $function : the function to call from the plugin
  */
 public function actionUnsecure($plugin, $function = null)
 {
     $oEvent = new PluginEvent('newUnsecureRequest');
     // The intended target of the call.
     $oEvent->set('target', $plugin);
     // The name of the function.
     $oEvent->set('function', $function);
     $oEvent->set('request', App()->request);
     App()->getPluginManager()->dispatchEvent($oEvent);
     $sOutput = '';
     foreach ($oEvent->getAllContent() as $content) {
         $sOutput .= $content->getContent();
     }
     if (!empty($sOutput)) {
         $this->renderText($sOutput);
     }
 }
Exemplo n.º 9
0
 /**
  * Sets permissions (global or survey-specific) for a survey administrator
  * Checks what permissions may be set and automatically filters invalid ones. 
  * A permission may be invalid if the permission does not exist or that particular user may not give that permission
  * 
  * @param mixed $iUserID
  * @param mixed $iEntityID
  * @param mixed $sEntityName
  * @param mixed $aPermissions
  * @param mixed $bBypassCheck
  */
 public static function setPermissions($iUserID, $iEntityID, $sEntityName, $aPermissions, $bBypassCheck = false)
 {
     $iUserID = sanitize_int($iUserID);
     // Filter global permissions on save
     if ($sEntityName == 'global') {
         $aBasePermissions = Permission::model()->getGlobalBasePermissions();
         if (!Permission::model()->hasGlobalPermission('superadmin', 'read') && !$bBypassCheck) {
             // if not superadmin filter the available permissions as no admin may give more permissions than he owns
             // Make sure that he owns the user he wants to give global permissions for
             $oUser = User::model()->findByAttributes(array('uid' => $iUserID, 'parent_id' => Yii::app()->session['loginID']));
             if (!$oUser) {
                 die('You are not allowed to set permisisons for this user');
             }
             $aFilteredPermissions = array();
             foreach ($aBasePermissions as $PermissionName => $aPermission) {
                 foreach ($aPermission as $sPermissionKey => &$sPermissionValue) {
                     if ($sPermissionKey != 'title' && $sPermissionKey != 'img' && !Permission::model()->hasGlobalPermission($PermissionName, $sPermissionKey)) {
                         $sPermissionValue = false;
                     }
                 }
                 // Only have a row for that permission if there is at least one permission he may give to other users
                 if ($aPermission['create'] || $aPermission['read'] || $aPermission['update'] || $aPermission['delete'] || $aPermission['import'] || $aPermission['export']) {
                     $aFilteredPermissions[$PermissionName] = $aPermission;
                 }
             }
             $aBasePermissions = $aFilteredPermissions;
         } elseif (Permission::model()->hasGlobalPermission('superadmin', 'read') && Yii::app()->session['loginID'] != 1) {
             unset($aBasePermissions['superadmin']);
         }
     } elseif ($sEntityName == 'survey') {
         $aBasePermissions = Permission::model()->getSurveyBasePermissions();
     }
     $aFilteredPermissions = array();
     foreach ($aBasePermissions as $sPermissionname => $aPermission) {
         $aFilteredPermissions[$sPermissionname]['create'] = isset($aPermissions[$sPermissionname]['create']) && $aPermissions[$sPermissionname]['create'];
         $aFilteredPermissions[$sPermissionname]['read'] = isset($aPermissions[$sPermissionname]['read']) && $aPermissions[$sPermissionname]['read'];
         $aFilteredPermissions[$sPermissionname]['update'] = isset($aPermissions[$sPermissionname]['update']) && $aPermissions[$sPermissionname]['update'];
         $aFilteredPermissions[$sPermissionname]['delete'] = isset($aPermissions[$sPermissionname]['delete']) && $aPermissions[$sPermissionname]['delete'];
         $aFilteredPermissions[$sPermissionname]['import'] = isset($aPermissions[$sPermissionname]['import']) && $aPermissions[$sPermissionname]['import'];
         $aFilteredPermissions[$sPermissionname]['export'] = isset($aPermissions[$sPermissionname]['export']) && $aPermissions[$sPermissionname]['export'];
     }
     $condition = array('entity_id' => $iEntityID, 'uid' => $iUserID);
     $oEvent = new PluginEvent('beforePermissionSetSave');
     $oEvent->set('aNewPermissions', $aFilteredPermissions);
     $oEvent->set('iSurveyID', $iEntityID);
     $oEvent->set('iUserID', $iUserID);
     $result = App()->getPluginManager()->dispatchEvent($oEvent);
     // Only the original superadmin may change the superadmin permissions
     if (Yii::app()->session['loginID'] != 1) {
         Permission::model()->deleteAllByAttributes($condition, "permission <> 'superadmin'");
     } else {
         Permission::model()->deleteAllByAttributes($condition);
     }
     foreach ($aFilteredPermissions as $sPermissionname => $aPermission) {
         if ($aPermission['create'] || $aPermission['read'] || $aPermission['update'] || $aPermission['delete'] || $aPermission['import'] || $aPermission['export']) {
             $data = array('entity_id' => $iEntityID, 'entity' => $sEntityName, 'uid' => $iUserID, 'permission' => $sPermissionname, 'create_p' => (int) $aPermission['create'], 'read_p' => (int) $aPermission['read'], 'update_p' => (int) $aPermission['update'], 'delete_p' => (int) $aPermission['delete'], 'import_p' => (int) $aPermission['import'], 'export_p' => (int) $aPermission['export']);
             $permission = new self();
             foreach ($data as $k => $v) {
                 $permission->{$k} = $v;
             }
             $permission->save();
         }
     }
     return true;
 }
Exemplo n.º 10
0
 /**
  * Handle email action
  */
 function email($iSurveyId, $tokenids = null)
 {
     $clang = $this->getController()->lang;
     $iSurveyId = sanitize_int($iSurveyId);
     if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update')) {
         Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page.");
         $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}"));
     }
     // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY
     $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}');
     if (!$bTokenExists) {
         self::_newtokentable($iSurveyId);
     }
     $aTokenIds = $tokenids;
     if (empty($tokenids)) {
         $aTokenIds = Yii::app()->request->getPost('tokenids', false);
     }
     if (!empty($aTokenIds)) {
         $aTokenIds = explode('|', $aTokenIds);
         $aTokenIds = array_filter($aTokenIds);
         $aTokenIds = array_map('sanitize_int', $aTokenIds);
     }
     $aTokenIds = array_unique(array_filter((array) $aTokenIds));
     $sSubAction = Yii::app()->request->getParam('action');
     $sSubAction = !in_array($sSubAction, array('email', 'remind')) ? 'email' : $sSubAction;
     $bEmail = $sSubAction == 'email';
     Yii::app()->loadHelper('surveytranslator');
     Yii::app()->loadHelper('/admin/htmleditor');
     Yii::app()->loadHelper('replacements');
     $token = Token::model($iSurveyId)->find();
     $aExampleRow = isset($token) ? $token->attributes : array();
     $aSurveyLangs = Survey::model()->findByPk($iSurveyId)->additionalLanguages;
     $sBaseLanguage = Survey::model()->findByPk($iSurveyId)->language;
     array_unshift($aSurveyLangs, $sBaseLanguage);
     $aTokenFields = getTokenFieldsAndNames($iSurveyId, true);
     $iAttributes = 0;
     $bHtml = getEmailFormat($iSurveyId) == 'html';
     $timeadjust = Yii::app()->getConfig("timeadjust");
     $aData['thissurvey'] = getSurveyInfo($iSurveyId);
     foreach ($aSurveyLangs as $sSurveyLanguage) {
         $aData['thissurvey'][$sSurveyLanguage] = getSurveyInfo($iSurveyId, $sSurveyLanguage);
     }
     $aData['surveyid'] = $iSurveyId;
     $aData['sSubAction'] = $sSubAction;
     $aData['bEmail'] = $bEmail;
     $aData['aSurveyLangs'] = $aData['surveylangs'] = $aSurveyLangs;
     $aData['baselang'] = $sBaseLanguage;
     $aData['tokenfields'] = array_keys($aTokenFields);
     $aData['nrofattributes'] = $iAttributes;
     $aData['examplerow'] = $aExampleRow;
     $aData['tokenids'] = $aTokenIds;
     $aData['ishtml'] = $bHtml;
     $iMaxEmails = Yii::app()->getConfig('maxemails');
     if (Yii::app()->request->getPost('bypassbademails') == 'Y') {
         $SQLemailstatuscondition = "emailstatus = 'OK'";
     } else {
         $SQLemailstatuscondition = "emailstatus <> 'OptOut'";
     }
     if (!Yii::app()->request->getPost('ok')) {
         if (empty($aData['tokenids'])) {
             $aTokens = TokenDynamic::model($iSurveyId)->findUninvitedIDs($aTokenIds, 0, $bEmail, $SQLemailstatuscondition);
             foreach ($aTokens as $aToken) {
                 $aData['tokenids'][] = $aToken;
             }
         }
         $this->_renderWrappedTemplate('token', array('tokenbar', $sSubAction), $aData);
     } else {
         $SQLremindercountcondition = "";
         $SQLreminderdelaycondition = "";
         if (!$bEmail) {
             if (Yii::app()->request->getPost('maxremindercount') && Yii::app()->request->getPost('maxremindercount') != '' && intval(Yii::app()->request->getPost('maxremindercount')) != 0) {
                 $SQLremindercountcondition = "remindercount < " . intval(Yii::app()->request->getPost('maxremindercount'));
             }
             if (Yii::app()->request->getPost('minreminderdelay') && Yii::app()->request->getPost('minreminderdelay') != '' && intval(Yii::app()->request->getPost('minreminderdelay')) != 0) {
                 // Yii::app()->request->getPost('minreminderdelay') in days (86400 seconds per day)
                 $compareddate = dateShift(date("Y-m-d H:i:s", time() - 86400 * intval(Yii::app()->request->getPost('minreminderdelay'))), "Y-m-d H:i", $timeadjust);
                 $SQLreminderdelaycondition = " ( " . " (remindersent = 'N' AND sent < '" . $compareddate . "') " . " OR " . " (remindersent < '" . $compareddate . "'))";
             }
         }
         $ctresult = TokenDynamic::model($iSurveyId)->findUninvitedIDs($aTokenIds, 0, $bEmail, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition);
         $ctcount = count($ctresult);
         $emresult = TokenDynamic::model($iSurveyId)->findUninvited($aTokenIds, $iMaxEmails, $bEmail, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition);
         $emcount = count($emresult);
         foreach ($aSurveyLangs as $language) {
             // See #08683 : this allow use of {TOKEN:ANYTHING}, directly replaced by {ANYTHING}
             $sSubject[$language] = preg_replace("/{TOKEN:([A-Z0-9_]+)}/", "{" . "\$1" . "}", Yii::app()->request->getPost('subject_' . $language));
             $sMessage[$language] = preg_replace("/{TOKEN:([A-Z0-9_]+)}/", "{" . "\$1" . "}", Yii::app()->request->getPost('message_' . $language));
             if ($bHtml) {
                 $sMessage[$language] = html_entity_decode($sMessage[$language], ENT_QUOTES, Yii::app()->getConfig("emailcharset"));
             }
         }
         $attributes = array_keys(getTokenFieldsAndNames($iSurveyId, true));
         $tokenoutput = "";
         if ($emcount > 0) {
             foreach ($emresult as $emrow) {
                 $to = $fieldsarray = array();
                 $aEmailaddresses = explode(';', $emrow['email']);
                 foreach ($aEmailaddresses as $sEmailaddress) {
                     $to[] = $emrow['firstname'] . " " . $emrow['lastname'] . " <{$sEmailaddress}>";
                 }
                 $fieldsarray["{EMAIL}"] = $emrow['email'];
                 $fieldsarray["{FIRSTNAME}"] = $emrow['firstname'];
                 $fieldsarray["{LASTNAME}"] = $emrow['lastname'];
                 $fieldsarray["{TOKEN}"] = $emrow['token'];
                 $fieldsarray["{LANGUAGE}"] = $emrow['language'];
                 foreach ($attributes as $attributefield) {
                     $fieldsarray['{' . strtoupper($attributefield) . '}'] = $emrow[$attributefield];
                     $fieldsarray['{TOKEN:' . strtoupper($attributefield) . '}'] = $emrow[$attributefield];
                 }
                 $emrow['language'] = trim($emrow['language']);
                 $found = array_search($emrow['language'], $aSurveyLangs);
                 if ($emrow['language'] == '' || $found == false) {
                     $emrow['language'] = $sBaseLanguage;
                 }
                 $from = Yii::app()->request->getPost('from_' . $emrow['language']);
                 $fieldsarray["{OPTOUTURL}"] = $this->getController()->createAbsoluteUrl("/optout/tokens/langcode/" . trim($emrow['language']) . "/surveyid/{$iSurveyId}/token/{$emrow['token']}");
                 $fieldsarray["{OPTINURL}"] = $this->getController()->createAbsoluteUrl("/optin/tokens/langcode/" . trim($emrow['language']) . "/surveyid/{$iSurveyId}/token/{$emrow['token']}");
                 $fieldsarray["{SURVEYURL}"] = $this->getController()->createAbsoluteUrl("/survey/index/sid/{$iSurveyId}/token/{$emrow['token']}/lang/" . trim($emrow['language']) . "/");
                 foreach (array('OPTOUT', 'OPTIN', 'SURVEY') as $key) {
                     $url = $fieldsarray["{{$key}URL}"];
                     if ($bHtml) {
                         $fieldsarray["{{$key}URL}"] = "<a href='{$url}'>" . htmlspecialchars($url) . '</a>';
                     }
                     if ($key == 'SURVEY') {
                         $barebone_link = $url;
                     }
                 }
                 $customheaders = array('1' => "X-surveyid: " . $iSurveyId, '2' => "X-tokenid: " . $fieldsarray["{TOKEN}"]);
                 global $maildebug;
                 $modsubject = Replacefields($sSubject[$emrow['language']], $fieldsarray);
                 $modmessage = Replacefields($sMessage[$emrow['language']], $fieldsarray);
                 if (isset($barebone_link)) {
                     $modsubject = str_replace("@@SURVEYURL@@", $barebone_link, $modsubject);
                     $modmessage = str_replace("@@SURVEYURL@@", $barebone_link, $modmessage);
                 }
                 if (trim($emrow['validfrom']) != '' && convertDateTimeFormat($emrow['validfrom'], 'Y-m-d H:i:s', 'U') * 1 > date('U') * 1) {
                     $tokenoutput .= $emrow['tid'] . " " . ReplaceFields($clang->gT("Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) delayed: Token is not yet valid.") . "<br />", $fieldsarray);
                 } elseif (trim($emrow['validuntil']) != '' && convertDateTimeFormat($emrow['validuntil'], 'Y-m-d H:i:s', 'U') * 1 < date('U') * 1) {
                     $tokenoutput .= $emrow['tid'] . " " . ReplaceFields($clang->gT("Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) skipped: Token is not valid anymore.") . "<br />", $fieldsarray);
                 } else {
                     /*
                      * Get attachments.
                      */
                     if ($sSubAction == 'email') {
                         $sTemplate = 'invitation';
                     } elseif ($sSubAction == 'remind') {
                         $sTemplate = 'reminder';
                     }
                     $aRelevantAttachments = array();
                     if (isset($aData['thissurvey'][$emrow['language']]['attachments'])) {
                         $aAttachments = unserialize($aData['thissurvey'][$emrow['language']]['attachments']);
                         if (!empty($aAttachments)) {
                             if (isset($aAttachments[$sTemplate])) {
                                 LimeExpressionManager::singleton()->loadTokenInformation($aData['thissurvey']['sid'], $emrow['token']);
                                 foreach ($aAttachments[$sTemplate] as $aAttachment) {
                                     if (LimeExpressionManager::singleton()->ProcessRelevance($aAttachment['relevance'])) {
                                         $aRelevantAttachments[] = $aAttachment['url'];
                                     }
                                 }
                             }
                         }
                     }
                     /**
                      * Event for email handling.
                      * Parameter    type    description:
                      * subject      rw      Body of the email
                      * to           rw      Recipient(s)
                      * from         rw      Sender(s)
                      * type         r       "invitation" or "reminder"
                      * send         w       If true limesurvey will send the email. Setting this to false will cause limesurvey to assume the mail has been sent by the plugin.
                      * error        w       If set and "send" is true, log the error as failed email attempt.
                      * token        r       Raw token data.
                      */
                     $event = new PluginEvent('beforeTokenEmail');
                     $event->set('type', $sTemplate);
                     $event->set('subject', $modsubject);
                     $event->set('to', $to);
                     $event->set('body', $modmessage);
                     $event->set('from', $from);
                     $event->set('bounce', getBounceEmail($iSurveyId));
                     $event->set('token', $emrow);
                     App()->getPluginManager()->dispatchEvent($event);
                     $modsubject = $event->get('subject');
                     $modmessage = $event->get('body');
                     $to = $event->get('to');
                     $from = $event->get('from');
                     if ($event->get('send', true) == false) {
                         // This is some ancient global used for error reporting instead of a return value from the actual mail function..
                         $maildebug = $event->get('error', $maildebug);
                         $success = $event->get('error') == null;
                     } else {
                         $success = SendEmailMessage($modmessage, $modsubject, $to, $from, Yii::app()->getConfig("sitename"), $bHtml, getBounceEmail($iSurveyId), $aRelevantAttachments, $customheaders);
                     }
                     if ($success) {
                         // Put date into sent
                         $token = Token::model($iSurveyId)->findByPk($emrow['tid']);
                         if ($bEmail) {
                             $tokenoutput .= $clang->gT("Invitation sent to:");
                             $token->sent = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust"));
                         } else {
                             $tokenoutput .= $clang->gT("Reminder sent to:");
                             $token->remindersent = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust"));
                             $token->remindercount++;
                         }
                         $token->save();
                         //Update central participant survey_links
                         if (!empty($emrow['participant_id'])) {
                             $slquery = SurveyLink::model()->find('participant_id = :pid AND survey_id = :sid AND token_id = :tid', array(':pid' => $emrow['participant_id'], ':sid' => $iSurveyId, ':tid' => $emrow['tid']));
                             if (!is_null($slquery)) {
                                 $slquery->date_invited = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust"));
                                 $slquery->save();
                             }
                         }
                         $tokenoutput .= "{$emrow['tid']}: {$emrow['firstname']} {$emrow['lastname']} ({$emrow['email']})<br />\n";
                         if (Yii::app()->getConfig("emailsmtpdebug") == 2) {
                             $tokenoutput .= $maildebug;
                         }
                     } else {
                         $tokenoutput .= ReplaceFields($clang->gT("Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) failed. Error Message:") . " " . $maildebug . "<br />", $fieldsarray);
                     }
                 }
                 unset($fieldsarray);
             }
             $aViewUrls = array('tokenbar', 'emailpost');
             $aData['tokenoutput'] = $tokenoutput;
             if ($ctcount > $emcount) {
                 $i = 0;
                 if (isset($aTokenIds)) {
                     while ($i < $iMaxEmails) {
                         array_shift($aTokenIds);
                         $i++;
                     }
                     $aData['tids'] = implode('|', $aTokenIds);
                 }
                 $aData['lefttosend'] = $ctcount - $iMaxEmails;
                 $aViewUrls[] = 'emailwarning';
             } else {
                 $aData['tokenoutput'] .= "<strong class='result success text-success'>" . gT("All emails were sent.") . "<strong>";
             }
             $this->_renderWrappedTemplate('token', $aViewUrls, $aData);
         } else {
             $this->_renderWrappedTemplate('token', array('tokenbar', 'message' => array('title' => $clang->gT("Warning"), 'message' => $clang->gT("There were no eligible emails to send. This will be because none satisfied the criteria of:") . "<br/>&nbsp;<ul><li>" . $clang->gT("having a valid email address") . "</li>" . "<li>" . $clang->gT("not having been sent an invitation already") . "</li>" . "<li>" . $clang->gT("having already completed the survey") . "</li>" . "<li>" . $clang->gT("having a token") . "</li></ul>")), $aData);
         }
     }
 }
Exemplo n.º 11
0
 /**
  * @param PluginEvent $event
  */
 public function listQuestionPlugins(PluginEvent $event)
 {
     if (!empty($this->questionTypes)) {
         $event->set('questionplugins.' . get_class($this), $this->questionTypes);
     }
 }
Exemplo n.º 12
0
 /**
  * Checks if a user has a certain permission
  *
  * @param $iEntityID integer The entity ID
  * @param $sEntityName string The entity name
  * @param $sPermission string Name of the permission
  * @param $sCRUD string The permission detail you want to check on: 'create','read','update','delete','import' or 'export'
  * @param $iUserID integer User ID - if not given the one of the current user is used
  * @return bool True if user has the permission
  */
 function hasPermission($iEntityID, $sEntityName, $sPermission, $sCRUD = 'read', $iUserID = null)
 {
     static $aPermissionStatic;
     $oEvent = new PluginEvent('beforeHasPermission');
     $oEvent->set('iEntityID', $iEntityID);
     $oEvent->set('sEntityName', $sEntityName);
     $oEvent->set('sPermission', $sPermission);
     $oEvent->set('sCRUD', $sCRUD);
     $oEvent->set('iUserID', $iUserID);
     App()->getPluginManager()->dispatchEvent($oEvent);
     $pluginbPermission = $oEvent->get('bPermission');
     // isset — Determine if a variable is set and is not NULL. And isset seems little speedest.
     if (isset($pluginbPermission)) {
         return $pluginbPermission;
     }
     if (!in_array($sCRUD, array('create', 'read', 'update', 'delete', 'import', 'export'))) {
         return false;
     }
     $sCRUD = $sCRUD . '_p';
     $iUserID = self::getUserId($iUserID);
     if (!$iUserID) {
         return false;
     }
     // Check if superadmin and cache it
     if (!isset($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'])) {
         $aPermission = $this->findByAttributes(array("entity_id" => 0, 'entity' => 'global', "uid" => $iUserID, "permission" => 'superadmin'));
         $bPermission = is_null($aPermission) ? array() : $aPermission->attributes;
         if (!isset($bPermission['read_p']) || $bPermission['read_p'] == 0) {
             $bPermission = false;
         } else {
             $bPermission = true;
         }
         $aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'] = $bPermission;
     }
     if ($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p']) {
         return true;
     }
     if (!isset($aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD])) {
         $query = $this->findByAttributes(array("entity_id" => $iEntityID, "uid" => $iUserID, "entity" => $sEntityName, "permission" => $sPermission));
         $bPermission = is_null($query) ? array() : $query->attributes;
         if (!isset($bPermission[$sCRUD]) || $bPermission[$sCRUD] == 0) {
             $bPermission = false;
         } else {
             $bPermission = true;
         }
         $aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD] = $bPermission;
     }
     return $aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD];
 }
Exemplo n.º 13
0
 /**
  * This function dispatches an event to all registered plugins.
  * @param PluginEvent $event Object holding all event properties
  * @param string|array $target Optional name of plugin to fire the event on
  * 
  * @return PluginEvent
  */
 public function dispatchEvent(PluginEvent $event, $target = array())
 {
     $eventName = $event->getEventName();
     if (is_string($target)) {
         $target = array($target);
     }
     if (isset($this->subscriptions[$eventName])) {
         foreach ($this->subscriptions[$eventName] as $subscription) {
             if (!$event->isStopped() && (empty($target) || in_array(get_class($subscription[0]), $target))) {
                 $subscription[0]->setEvent($event);
                 call_user_func($subscription);
             }
         }
     }
     return $event;
 }
Exemplo n.º 14
0
 /**
  * Database::index()
  *
  * @param mixed $sa
  * @return
  */
 function index($sa = null)
 {
     $sAction = Yii::app()->request->getPost('action');
     $iSurveyID = isset($_POST['sid']) ? $_POST['sid'] : returnGlobal('sid');
     $iQuestionGroupID = returnGlobal('gid');
     $iQuestionID = returnGlobal('qid');
     // TODO: This variable seems to be never set or used in any function call?
     $sDBOutput = '';
     $oFixCKeditor = new LSYii_Validators();
     $oFixCKeditor->fixCKeditor = true;
     $oFixCKeditor->xssfilter = false;
     if ($sAction == "updatedefaultvalues" && Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
         $aSurveyLanguages = Survey::model()->findByPk($iSurveyID)->additionalLanguages;
         $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
         array_unshift($aSurveyLanguages, $sBaseLanguage);
         Question::model()->updateAll(array('same_default' => Yii::app()->request->getPost('samedefault') ? 1 : 0), 'sid=:sid ANd qid=:qid', array(':sid' => $iSurveyID, ':qid' => $iQuestionID));
         $arQuestion = Question::model()->findByAttributes(array('qid' => $iQuestionID));
         $sQuestionType = $arQuestion['type'];
         $aQuestionTypeList = getQuestionTypeList('', 'array');
         if ($aQuestionTypeList[$sQuestionType]['answerscales'] > 0 && $aQuestionTypeList[$sQuestionType]['subquestions'] == 0) {
             for ($iScaleID = 0; $iScaleID < $aQuestionTypeList[$sQuestionType]['answerscales']; $iScaleID++) {
                 foreach ($aSurveyLanguages as $sLanguage) {
                     if (!is_null(Yii::app()->request->getPost('defaultanswerscale_' . $iScaleID . '_' . $sLanguage))) {
                         $this->_updateDefaultValues($iQuestionID, 0, $iScaleID, '', $sLanguage, Yii::app()->request->getPost('defaultanswerscale_' . $iScaleID . '_' . $sLanguage), true);
                     }
                     if (!is_null(Yii::app()->request->getPost('other_' . $iScaleID . '_' . $sLanguage))) {
                         $this->_updateDefaultValues($iQuestionID, 0, $iScaleID, 'other', $sLanguage, Yii::app()->request->getPost('other_' . $iScaleID . '_' . $sLanguage), true);
                     }
                 }
             }
         }
         if ($aQuestionTypeList[$sQuestionType]['subquestions'] > 0) {
             foreach ($aSurveyLanguages as $sLanguage) {
                 $arQuestions = Question::model()->findAllByAttributes(array('sid' => $iSurveyID, 'gid' => $iQuestionGroupID, 'parent_qid' => $iQuestionID, 'language' => $sLanguage, 'scale_id' => 0));
                 for ($iScaleID = 0; $iScaleID < $aQuestionTypeList[$sQuestionType]['subquestions']; $iScaleID++) {
                     foreach ($arQuestions as $aSubquestionrow) {
                         if (!is_null(Yii::app()->request->getPost('defaultanswerscale_' . $iScaleID . '_' . $sLanguage . '_' . $aSubquestionrow['qid']))) {
                             $this->_updateDefaultValues($iQuestionID, $aSubquestionrow['qid'], $iScaleID, '', $sLanguage, Yii::app()->request->getPost('defaultanswerscale_' . $iScaleID . '_' . $sLanguage . '_' . $aSubquestionrow['qid']), true);
                         }
                     }
                 }
             }
         }
         if ($aQuestionTypeList[$sQuestionType]['answerscales'] == 0 && $aQuestionTypeList[$sQuestionType]['subquestions'] == 0) {
             foreach ($aSurveyLanguages as $sLanguage) {
                 // Qick and dirty insert for yes/no defaul value
                 // write the the selectbox option, or if "EM" is slected, this value to table
                 if ($sQuestionType == 'Y') {
                     /// value for all langs
                     if (Yii::app()->request->getPost('samedefault') == 1) {
                         $sLanguage = $aSurveyLanguages[0];
                         // turn
                     } else {
                         $sCurrentLang = $sLanguage;
                         // edit the next lines
                     }
                     if (Yii::app()->request->getPost('defaultanswerscale_0_' . $sLanguage) == 'EM') {
                         // Case EM, write expression to database
                         $this->_updateDefaultValues($iQuestionID, 0, 0, '', $sLanguage, Yii::app()->request->getPost('defaultanswerscale_0_' . $sLanguage . '_EM'), true);
                     } else {
                         // Case "other", write list value to database
                         $this->_updateDefaultValues($iQuestionID, 0, 0, '', $sLanguage, Yii::app()->request->getPost('defaultanswerscale_0_' . $sLanguage), true);
                     }
                     ///// end yes/no
                 } else {
                     if (!is_null(Yii::app()->request->getPost('defaultanswerscale_0_' . $sLanguage . '_0'))) {
                         $this->_updateDefaultValues($iQuestionID, 0, 0, '', $sLanguage, Yii::app()->request->getPost('defaultanswerscale_0_' . $sLanguage . '_0'), true);
                     }
                 }
             }
         }
         Yii::app()->session['flashmessage'] = gT("Default value settings were successfully saved.");
         LimeExpressionManager::SetDirtyFlag();
         if ($sDBOutput != '') {
             echo $sDBOutput;
         } else {
             if (Yii::app()->request->getPost('close-after-save') === 'true') {
                 $this->getController()->redirect(array('admin/questions/sa/view/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
             }
             $this->getController()->redirect(array('admin/questions/sa/editdefaultvalues/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
         }
     }
     if ($sAction == "updateansweroptions" && Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
         Yii::app()->loadHelper('database');
         $aSurveyLanguages = Survey::model()->findByPk($iSurveyID)->additionalLanguages;
         $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
         array_unshift($aSurveyLanguages, $sBaseLanguage);
         $arQuestion = Question::model()->findByAttributes(array('qid' => $iQuestionID));
         $sQuestionType = $arQuestion['type'];
         // Checked)
         $aQuestionTypeList = getQuestionTypeList('', 'array');
         $iScaleCount = $aQuestionTypeList[$sQuestionType]['answerscales'];
         //First delete all answers
         Answer::model()->deleteAllByAttributes(array('qid' => $iQuestionID));
         LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID);
         for ($iScaleID = 0; $iScaleID < $iScaleCount; $iScaleID++) {
             $iMaxCount = (int) Yii::app()->request->getPost('answercount_' . $iScaleID);
             for ($iSortOrderID = 1; $iSortOrderID < $iMaxCount; $iSortOrderID++) {
                 $sCode = sanitize_paranoid_string(Yii::app()->request->getPost('code_' . $iSortOrderID . '_' . $iScaleID));
                 $iAssessmentValue = (int) Yii::app()->request->getPost('assessment_' . $iSortOrderID . '_' . $iScaleID);
                 foreach ($aSurveyLanguages as $sLanguage) {
                     $sAnswerText = Yii::app()->request->getPost('answer_' . $sLanguage . '_' . $iSortOrderID . '_' . $iScaleID);
                     // Fix bug with FCKEditor saving strange BR types
                     $sAnswerText = $oFixCKeditor->fixCKeditor($sAnswerText);
                     // Now we insert the answers
                     $iInsertCount = Answer::model()->insertRecords(array('code' => $sCode, 'answer' => $sAnswerText, 'qid' => $iQuestionID, 'sortorder' => $iSortOrderID, 'language' => $sLanguage, 'assessment_value' => $iAssessmentValue, 'scale_id' => $iScaleID));
                     if (!$iInsertCount) {
                         Yii::app()->setFlashMessage(gT("Failed to update answers"), 'error');
                     }
                 }
                 // Updating code (oldcode!==null) => update condition with the new code
                 $sOldCode = Yii::app()->request->getPost('oldcode_' . $iSortOrderID . '_' . $iScaleID);
                 if (isset($sOldCode) && $sCode !== $sOldCode) {
                     Condition::model()->updateAll(array('value' => $sCode), 'cqid=:cqid AND value=:value', array(':cqid' => $iQuestionID, ':value' => $sOldCode));
                 }
             }
             // for ($sortorderid=0;$sortorderid<$maxcount;$sortorderid++)
         }
         //  for ($scale_id=0;
         LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID);
         if (!Yii::app()->request->getPost('bFullPOST')) {
             Yii::app()->setFlashMessage(gT("Not all answer options were saved. This usually happens due to server limitations ( PHP setting max_input_vars) - please contact your system administrator."));
         } else {
             Yii::app()->session['flashmessage'] = gT("Answer options were successfully saved.");
         }
         LimeExpressionManager::SetDirtyFlag();
         if ($sDBOutput != '') {
             echo $sDBOutput;
         } else {
             if (Yii::app()->request->getPost('close-after-save') === 'true') {
                 $this->getController()->redirect(array('admin/questions/sa/view/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
             }
             $this->getController()->redirect(array('/admin/questions/sa/answeroptions/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
         }
     }
     if ($sAction == "updatesubquestions" && Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
         Yii::app()->loadHelper('database');
         $aSurveyLanguages = Survey::model()->findByPk($iSurveyID)->additionalLanguages;
         $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
         array_unshift($aSurveyLanguages, $sBaseLanguage);
         $arQuestion = Question::model()->findByAttributes(array('qid' => $iQuestionID));
         $sQuestionType = $arQuestion['type'];
         // Checked
         $aQuestionTypeList = getQuestionTypeList('', 'array');
         $iScaleCount = $aQuestionTypeList[$sQuestionType]['subquestions'];
         // First delete any deleted ids
         $aDeletedQIDs = explode(' ', trim(Yii::app()->request->getPost('deletedqids')));
         LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID);
         $aDeletedQIDs = array_unique($aDeletedQIDs, SORT_NUMERIC);
         foreach ($aDeletedQIDs as $iDeletedQID) {
             $iDeletedQID = (int) $iDeletedQID;
             if ($iDeletedQID > 0) {
                 // don't remove undefined
                 $iInsertCount = Question::model()->deleteAllByAttributes(array('qid' => $iDeletedQID));
                 if (!$iInsertCount) {
                     Yii::app()->setFlashMessage(gT("Failed to delete answer"), 'error');
                 }
             }
         }
         //Determine ids by evaluating the hidden field
         $aRows = array();
         $aCodes = array();
         $aOldCodes = array();
         $aRelevance = array();
         foreach ($_POST as $sPOSTKey => $sPOSTValue) {
             $sPOSTKey = explode('_', $sPOSTKey);
             if ($sPOSTKey[0] == 'answer') {
                 $aRows[$sPOSTKey[3]][$sPOSTKey[1]][$sPOSTKey[2]] = $sPOSTValue;
             }
             if ($sPOSTKey[0] == 'code') {
                 $aCodes[$sPOSTKey[2]][] = $sPOSTValue;
             }
             if ($sPOSTKey[0] == 'oldcode') {
                 $aOldCodes[$sPOSTKey[2]][] = $sPOSTValue;
             }
             if ($sPOSTKey[0] == 'relevance') {
                 $aRelevance[$sPOSTKey[2]][] = $sPOSTValue;
             }
         }
         $aInsertQID = array();
         for ($iScaleID = 0; $iScaleID < $iScaleCount; $iScaleID++) {
             foreach ($aSurveyLanguages as $sLanguage) {
                 $iPosition = 0;
                 foreach ($aRows[$iScaleID][$sLanguage] as $subquestionkey => $subquestionvalue) {
                     if (substr($subquestionkey, 0, 3) != 'new') {
                         $oSubQuestion = Question::model()->find("qid=:qid AND language=:language", array(":qid" => $subquestionkey, ':language' => $sLanguage));
                         if (!is_object($oSubQuestion)) {
                             throw new CHttpException(502, "could not find subquestion {$subquestionkey} !");
                         }
                         $oSubQuestion->question_order = $iPosition + 1;
                         $oSubQuestion->title = $aCodes[$iScaleID][$iPosition];
                         $oSubQuestion->question = $subquestionvalue;
                         $oSubQuestion->scale_id = $iScaleID;
                         $oSubQuestion->relevance = isset($aRelevance[$iScaleID][$iPosition]) ? $aRelevance[$iScaleID][$iPosition] : "";
                     } else {
                         if (!isset($aInsertQID[$iScaleID][$iPosition])) {
                             $oSubQuestion = new Question();
                             $oSubQuestion->sid = $iSurveyID;
                             $oSubQuestion->gid = $iQuestionGroupID;
                             $oSubQuestion->question_order = $iPosition + 1;
                             $oSubQuestion->title = $aCodes[$iScaleID][$iPosition];
                             $oSubQuestion->question = $subquestionvalue;
                             $oSubQuestion->parent_qid = $iQuestionID;
                             $oSubQuestion->language = $sLanguage;
                             $oSubQuestion->scale_id = $iScaleID;
                             $oSubQuestion->relevance = isset($aRelevance[$iScaleID][$iPosition]) ? $aRelevance[$iScaleID][$iPosition] : "";
                         } else {
                             $oSubQuestion = Question::model()->find("qid=:qid AND language=:language", array(":qid" => $aInsertQID[$iScaleID][$iPosition], ':language' => $sLanguage));
                             if (!$oSubQuestion) {
                                 $oSubQuestion = new Question();
                             }
                             $oSubQuestion->sid = $iSurveyID;
                             $oSubQuestion->qid = $aInsertQID[$iScaleID][$iPosition];
                             $oSubQuestion->gid = $iQuestionGroupID;
                             $oSubQuestion->question_order = $iPosition + 1;
                             $oSubQuestion->title = $aCodes[$iScaleID][$iPosition];
                             $oSubQuestion->question = $subquestionvalue;
                             $oSubQuestion->parent_qid = $iQuestionID;
                             $oSubQuestion->language = $sLanguage;
                             $oSubQuestion->scale_id = $iScaleID;
                             $oSubQuestion->relevance = isset($aRelevance[$iScaleID][$iPosition]) ? $aRelevance[$iScaleID][$iPosition] : "";
                         }
                     }
                     if ($oSubQuestion->qid) {
                         switchMSSQLIdentityInsert('questions', true);
                         $bSubQuestionResult = $oSubQuestion->save();
                         switchMSSQLIdentityInsert('questions', false);
                     } else {
                         $bSubQuestionResult = $oSubQuestion->save();
                     }
                     if ($bSubQuestionResult) {
                         if (substr($subquestionkey, 0, 3) != 'new' && isset($aOldCodes[$iScaleID][$iPosition]) && $aCodes[$iScaleID][$iPosition] !== $aOldCodes[$iScaleID][$iPosition]) {
                             Condition::model()->updateAll(array('cfieldname' => '+' . $iSurveyID . 'X' . $iQuestionGroupID . 'X' . $iQuestionID . $aCodes[$iScaleID][$iPosition], 'value' => $aCodes[$iScaleID][$iPosition]), 'cqid=:cqid AND cfieldname=:cfieldname AND value=:value', array(':cqid' => $iQuestionID, ':cfieldname' => $iSurveyID . 'X' . $iQuestionGroupID . 'X' . $iQuestionID, ':value' => $aOldCodes[$iScaleID][$iPosition]));
                         }
                         if (!isset($aInsertQID[$iScaleID][$iPosition])) {
                             $aInsertQID[$iScaleID][$iPosition] = $oSubQuestion->qid;
                         }
                     } else {
                         $aErrors = $oSubQuestion->getErrors();
                         if (count($aErrors)) {
                             //$sErrorMessage=gT("Question could not be updated with this errors:");
                             foreach ($aErrors as $sAttribute => $aStringErrors) {
                                 foreach ($aStringErrors as $sStringErrors) {
                                     Yii::app()->setFlashMessage(sprintf(gT("Error on %s for subquestion %s: %s"), $sAttribute, $aCodes[$iScaleID][$iPosition], $sStringErrors), 'error');
                                 }
                             }
                         } else {
                             Yii::app()->setFlashMessage(sprintf(gT("Subquestions %s could not be updated."), $aCodes[$iScaleID][$iPosition]), 'error');
                         }
                     }
                     $iPosition++;
                 }
             }
         }
         LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID);
         // Do it only if there are no error ?
         if (!isset($aErrors) || !count($aErrors)) {
             if (!Yii::app()->request->getPost('bFullPOST')) {
                 Yii::app()->session['flashmessage'] = gT("Not all subquestions were saved. This usually happens due to server limitations ( PHP setting max_input_vars) - please contact your system administrator.");
             } else {
                 Yii::app()->session['flashmessage'] = gT("Subquestions were successfully saved.");
             }
         }
         //$action='editsubquestions';
         LimeExpressionManager::SetDirtyFlag();
         if ($sDBOutput != '') {
             echo 'Problem in database controller: ' . $sDBOutput;
         } else {
             if (Yii::app()->request->getPost('close-after-save') === 'true') {
                 $this->getController()->redirect(array('/admin/questions/sa/view/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
             }
             $this->getController()->redirect(array('/admin/questions/sa/subquestions/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
         }
     }
     /**
      * Insert / Copy question
      */
     if (in_array($sAction, array('insertquestion', 'copyquestion')) && Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'create')) {
         $survey = Survey::model()->findByPk($iSurveyID);
         $sBaseLanguage = $survey->language;
         // Abort if survey is active
         if ($survey->active !== 'N') {
             Yii::app()->setFlashMessage(gT("You can't insert a new question when the survey is active."), 'error');
             $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/" . $survey->sid), "refresh");
         }
         if (strlen(Yii::app()->request->getPost('title')) < 1) {
             Yii::app()->setFlashMessage(gT("The question could not be added. You must enter at least a question code."), 'error');
         } else {
             // For Bootstrap Version usin YiiWheels switch :
             $_POST['mandatory'] = Yii::app()->request->getPost('mandatory') == '1' ? 'Y' : 'N';
             $_POST['other'] = Yii::app()->request->getPost('other') == '1' ? 'Y' : 'N';
             if (Yii::app()->request->getPost('questionposition', "") != "") {
                 $iQuestionOrder = intval(Yii::app()->request->getPost('questionposition'));
                 //Need to renumber all questions on or after this
                 $sQuery = "UPDATE {{questions}} SET question_order=question_order+1 WHERE gid=:gid AND question_order >= :order";
                 Yii::app()->db->createCommand($sQuery)->bindValues(array(':gid' => $iQuestionGroupID, ':order' => $iQuestionOrder))->query();
             } else {
                 $iQuestionOrder = getMaxQuestionOrder($iQuestionGroupID, $iSurveyID);
                 $iQuestionOrder++;
             }
             $sQuestionText = Yii::app()->request->getPost('question_' . $sBaseLanguage, '');
             $sQuestionHelp = Yii::app()->request->getPost('help_' . $sBaseLanguage, '');
             // Fix bug with FCKEditor saving strange BR types : in rules ?
             $sQuestionText = $oFixCKeditor->fixCKeditor($sQuestionText);
             $sQuestionHelp = $oFixCKeditor->fixCKeditor($sQuestionHelp);
             $iQuestionID = 0;
             $oQuestion = new Question();
             $oQuestion->sid = $iSurveyID;
             $oQuestion->gid = $iQuestionGroupID;
             $oQuestion->type = Yii::app()->request->getPost('type');
             $oQuestion->title = Yii::app()->request->getPost('title');
             $oQuestion->question = $sQuestionText;
             $oQuestion->preg = Yii::app()->request->getPost('preg');
             $oQuestion->help = $sQuestionHelp;
             $oQuestion->other = Yii::app()->request->getPost('other');
             // For Bootstrap Version usin YiiWheels switch :
             $oQuestion->mandatory = Yii::app()->request->getPost('mandatory');
             $oQuestion->other = Yii::app()->request->getPost('other');
             $oQuestion->relevance = Yii::app()->request->getPost('relevance');
             $oQuestion->question_order = $iQuestionOrder;
             $oQuestion->language = $sBaseLanguage;
             $oQuestion->save();
             if ($oQuestion) {
                 $iQuestionID = $oQuestion->qid;
             }
             $aErrors = $oQuestion->getErrors();
             if (count($aErrors)) {
                 foreach ($aErrors as $sAttribute => $aStringErrors) {
                     foreach ($aStringErrors as $sStringErrors) {
                         Yii::app()->setFlashMessage(sprintf(gT("Question could not be created with error on %s: %s"), $sAttribute, $sStringErrors), 'error');
                     }
                 }
             }
             // Add other languages
             if ($iQuestionID) {
                 $addlangs = Survey::model()->findByPk($iSurveyID)->additionalLanguages;
                 foreach ($addlangs as $alang) {
                     if ($alang != "") {
                         $langqid = 0;
                         $oQuestion = new Question();
                         $oQuestion->qid = $iQuestionID;
                         $oQuestion->sid = $iSurveyID;
                         $oQuestion->gid = $iQuestionGroupID;
                         $oQuestion->type = Yii::app()->request->getPost('type');
                         $oQuestion->title = Yii::app()->request->getPost('title');
                         $oQuestion->question = Yii::app()->request->getPost('question_' . $alang);
                         $oQuestion->preg = Yii::app()->request->getPost('preg');
                         $oQuestion->help = Yii::app()->request->getPost('help_' . $alang);
                         $oQuestion->other = Yii::app()->request->getPost('other');
                         $oQuestion->mandatory = Yii::app()->request->getPost('mandatory');
                         $oQuestion->relevance = Yii::app()->request->getPost('relevance');
                         $oQuestion->question_order = $iQuestionOrder;
                         $oQuestion->language = $alang;
                         switchMSSQLIdentityInsert('questions', true);
                         // Not sure for this one ?
                         $oQuestion->save();
                         switchMSSQLIdentityInsert('questions', false);
                         if ($oQuestion) {
                             $langqid = $oQuestion->qid;
                         }
                         $aErrors = $oQuestion->getErrors();
                         if (count($aErrors)) {
                             foreach ($aErrors as $sAttribute => $aStringErrors) {
                                 foreach ($aStringErrors as $sStringErrors) {
                                     Yii::app()->setFlashMessage(sprintf(gT("Question in language %s could not be created with error on %s: %s"), $alang, $sAttribute, $sStringErrors), 'error');
                                 }
                             }
                         }
                         #                            if (!$langqid)
                         #                            {
                         #                                Yii::app()->setFlashMessage(gT("Question in language %s could not be created."),'error');
                         #                            }
                     }
                 }
             }
             if (!$iQuestionID) {
                 Yii::app()->setFlashMessage(gT("Question could not be created."), 'error');
             } else {
                 /**
                  *
                  * Copy Question
                  *
                  */
                 if ($sAction == 'copyquestion') {
                     if (returnGlobal('copysubquestions') == "Y") {
                         $aSQIDMappings = array();
                         $r1 = Question::model()->getSubQuestions(returnGlobal('oldqid'));
                         $aSubQuestions = $r1->readAll();
                         foreach ($aSubQuestions as $qr1) {
                             $qr1['parent_qid'] = $iQuestionID;
                             if (isset($aSQIDMappings[$qr1['qid']])) {
                                 $qr1['qid'] = $aSQIDMappings[$qr1['qid']];
                             } else {
                                 $oldqid = $qr1['qid'];
                                 unset($qr1['qid']);
                             }
                             $qr1['gid'] = $iQuestionGroupID;
                             $iInsertID = Question::model()->insertRecords($qr1);
                             if (!isset($qr1['qid'])) {
                                 $aSQIDMappings[$oldqid] = $iInsertID;
                             }
                         }
                     }
                     if (returnGlobal('copyanswers') == "Y") {
                         $r1 = Answer::model()->getAnswers(returnGlobal('oldqid'));
                         $aAnswerOptions = $r1->readAll();
                         foreach ($aAnswerOptions as $qr1) {
                             Answer::model()->insertRecords(array('qid' => $iQuestionID, 'code' => $qr1['code'], 'answer' => $qr1['answer'], 'assessment_value' => $qr1['assessment_value'], 'sortorder' => $qr1['sortorder'], 'language' => $qr1['language'], 'scale_id' => $qr1['scale_id']));
                         }
                     }
                     /**
                      * Copy attribute
                      */
                     if (returnGlobal('copyattributes') == "Y") {
                         $oOldAttributes = QuestionAttribute::model()->findAll("qid=:qid", array("qid" => returnGlobal('oldqid')));
                         foreach ($oOldAttributes as $oOldAttribute) {
                             $attribute = new QuestionAttribute();
                             $attribute->qid = $iQuestionID;
                             $attribute->value = $oOldAttribute->value;
                             $attribute->attribute = $oOldAttribute->attribute;
                             $attribute->language = $oOldAttribute->language;
                             $attribute->save();
                         }
                     }
                     // Since 2.5, user can edit attribute while copying
                     $qattributes = questionAttributes();
                     $validAttributes = $qattributes[Yii::app()->request->getPost('type')];
                     $aLanguages = array_merge(array(Survey::model()->findByPk($iSurveyID)->language), Survey::model()->findByPk($iSurveyID)->additionalLanguages);
                     foreach ($validAttributes as $validAttribute) {
                         if ($validAttribute['i18n']) {
                             foreach ($aLanguages as $sLanguage) {
                                 $value = Yii::app()->request->getPost($validAttribute['name'] . '_' . $sLanguage);
                                 $iInsertCount = QuestionAttribute::model()->findAllByAttributes(array('attribute' => $validAttribute['name'], 'qid' => $iQuestionID, 'language' => $sLanguage));
                                 if (count($iInsertCount) > 0) {
                                     if ($value != '') {
                                         QuestionAttribute::model()->updateAll(array('value' => $value), 'attribute=:attribute AND qid=:qid AND language=:language', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID, ':language' => $sLanguage));
                                     } else {
                                         QuestionAttribute::model()->deleteAll('attribute=:attribute AND qid=:qid AND language=:language', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID, ':language' => $sLanguage));
                                     }
                                 } elseif ($value != '') {
                                     $attribute = new QuestionAttribute();
                                     $attribute->qid = $iQuestionID;
                                     $attribute->value = $value;
                                     $attribute->attribute = $validAttribute['name'];
                                     $attribute->language = $sLanguage;
                                     $attribute->save();
                                 }
                             }
                         } else {
                             $value = Yii::app()->request->getPost($validAttribute['name']);
                             if ($validAttribute['name'] == 'multiflexible_step' && trim($value) != '') {
                                 $value = floatval($value);
                                 if ($value == 0) {
                                     $value = 1;
                                 }
                             }
                             $iInsertCount = QuestionAttribute::model()->findAllByAttributes(array('attribute' => $validAttribute['name'], 'qid' => $iQuestionID));
                             if (count($iInsertCount) > 0) {
                                 if ($value != $validAttribute['default'] && trim($value) != "") {
                                     QuestionAttribute::model()->updateAll(array('value' => $value), 'attribute=:attribute AND qid=:qid', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID));
                                 } else {
                                     QuestionAttribute::model()->deleteAll('attribute=:attribute AND qid=:qid', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID));
                                 }
                             } elseif ($value != $validAttribute['default'] && trim($value) != "") {
                                 $attribute = new QuestionAttribute();
                                 $attribute->qid = $iQuestionID;
                                 $attribute->value = $value;
                                 $attribute->attribute = $validAttribute['name'];
                                 $attribute->save();
                             }
                         }
                     }
                 } else {
                     $qattributes = questionAttributes();
                     $validAttributes = $qattributes[Yii::app()->request->getPost('type')];
                     $aLanguages = array_merge(array(Survey::model()->findByPk($iSurveyID)->language), Survey::model()->findByPk($iSurveyID)->additionalLanguages);
                     foreach ($validAttributes as $validAttribute) {
                         if ($validAttribute['i18n']) {
                             foreach ($aLanguages as $sLanguage) {
                                 $value = Yii::app()->request->getPost($validAttribute['name'] . '_' . $sLanguage);
                                 $iInsertCount = QuestionAttribute::model()->findAllByAttributes(array('attribute' => $validAttribute['name'], 'qid' => $iQuestionID, 'language' => $sLanguage));
                                 if (count($iInsertCount) > 0) {
                                     if ($value != '') {
                                         QuestionAttribute::model()->updateAll(array('value' => $value), 'attribute=:attribute AND qid=:qid AND language=:language', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID, ':language' => $sLanguage));
                                     } else {
                                         QuestionAttribute::model()->deleteAll('attribute=:attribute AND qid=:qid AND language=:language', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID, ':language' => $sLanguage));
                                     }
                                 } elseif ($value != '') {
                                     $attribute = new QuestionAttribute();
                                     $attribute->qid = $iQuestionID;
                                     $attribute->value = $value;
                                     $attribute->attribute = $validAttribute['name'];
                                     $attribute->language = $sLanguage;
                                     $attribute->save();
                                 }
                             }
                         } else {
                             $value = Yii::app()->request->getPost($validAttribute['name']);
                             if ($validAttribute['name'] == 'multiflexible_step' && trim($value) != '') {
                                 $value = floatval($value);
                                 if ($value == 0) {
                                     $value = 1;
                                 }
                             }
                             $iInsertCount = QuestionAttribute::model()->findAllByAttributes(array('attribute' => $validAttribute['name'], 'qid' => $iQuestionID));
                             if (count($iInsertCount) > 0) {
                                 if ($value != $validAttribute['default'] && trim($value) != "") {
                                     QuestionAttribute::model()->updateAll(array('value' => $value), 'attribute=:attribute AND qid=:qid', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID));
                                 } else {
                                     QuestionAttribute::model()->deleteAll('attribute=:attribute AND qid=:qid', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID));
                                 }
                             } elseif ($value != $validAttribute['default'] && trim($value) != "") {
                                 $attribute = new QuestionAttribute();
                                 $attribute->qid = $iQuestionID;
                                 $attribute->value = $value;
                                 $attribute->attribute = $validAttribute['name'];
                                 $attribute->save();
                             }
                         }
                     }
                 }
                 Question::model()->updateQuestionOrder($iQuestionGroupID, $iSurveyID);
                 Yii::app()->session['flashmessage'] = gT("Question was successfully added.");
             }
         }
         LimeExpressionManager::SetDirtyFlag();
         // so refreshes syntax highlighting
         if ($sDBOutput != '') {
             echo $sDBOutput;
         } else {
             //admin/survey/sa/view/surveyid/
             $this->getController()->redirect(array('admin/questions/sa/view/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
         }
     }
     /**
      * Update question
      */
     if ($sAction == "updatequestion" && Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) {
         LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID);
         $cqr = Question::model()->findByAttributes(array('qid' => $iQuestionID));
         $oldtype = $cqr['type'];
         $oldgid = $cqr['gid'];
         $survey = Survey::model()->findByPk($iSurveyID);
         // If the survey is activate the question type may not be changed
         if ($survey->active !== 'N') {
             $sQuestionType = $oldtype;
         } else {
             $sQuestionType = Yii::app()->request->getPost('type');
         }
         // Remove invalid question attributes on saving
         $qattributes = questionAttributes();
         $criteria = new CDbCriteria();
         $criteria->compare('qid', $iQuestionID);
         if (isset($qattributes[$sQuestionType])) {
             $validAttributes = $qattributes[$sQuestionType];
             foreach ($validAttributes as $validAttribute) {
                 $criteria->compare('attribute', '<>' . $validAttribute['name']);
             }
         }
         QuestionAttribute::model()->deleteAll($criteria);
         $aLanguages = array_merge(array(Survey::model()->findByPk($iSurveyID)->language), Survey::model()->findByPk($iSurveyID)->additionalLanguages);
         //now save all valid attributes
         $validAttributes = $qattributes[$sQuestionType];
         foreach ($validAttributes as $validAttribute) {
             if ($validAttribute['i18n']) {
                 foreach ($aLanguages as $sLanguage) {
                     // TODO sanitise XSS
                     $value = Yii::app()->request->getPost($validAttribute['name'] . '_' . $sLanguage);
                     $iInsertCount = QuestionAttribute::model()->findAllByAttributes(array('attribute' => $validAttribute['name'], 'qid' => $iQuestionID, 'language' => $sLanguage));
                     if (count($iInsertCount) > 0) {
                         if ($value != '') {
                             QuestionAttribute::model()->updateAll(array('value' => $value), 'attribute=:attribute AND qid=:qid AND language=:language', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID, ':language' => $sLanguage));
                         } else {
                             QuestionAttribute::model()->deleteAll('attribute=:attribute AND qid=:qid AND language=:language', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID, ':language' => $sLanguage));
                         }
                     } elseif ($value != '') {
                         $attribute = new QuestionAttribute();
                         $attribute->qid = $iQuestionID;
                         $attribute->value = $value;
                         $attribute->attribute = $validAttribute['name'];
                         $attribute->language = $sLanguage;
                         $attribute->save();
                     }
                 }
             } else {
                 $value = Yii::app()->request->getPost($validAttribute['name']);
                 if ($validAttribute['name'] == 'multiflexible_step' && trim($value) != '') {
                     $value = floatval($value);
                     if ($value == 0) {
                         $value = 1;
                     }
                 }
                 $iInsertCount = QuestionAttribute::model()->findAllByAttributes(array('attribute' => $validAttribute['name'], 'qid' => $iQuestionID));
                 if (count($iInsertCount) > 0) {
                     if ($value != $validAttribute['default'] && trim($value) != "") {
                         QuestionAttribute::model()->updateAll(array('value' => $value), 'attribute=:attribute AND qid=:qid', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID));
                     } else {
                         QuestionAttribute::model()->deleteAll('attribute=:attribute AND qid=:qid', array(':attribute' => $validAttribute['name'], ':qid' => $iQuestionID));
                     }
                 } elseif ($value != $validAttribute['default'] && trim($value) != "") {
                     $attribute = new QuestionAttribute();
                     $attribute->qid = $iQuestionID;
                     $attribute->value = $value;
                     $attribute->attribute = $validAttribute['name'];
                     $attribute->save();
                 }
             }
         }
         $aQuestionTypeList = getQuestionTypeList('', 'array');
         // These are the questions types that have no answers and therefore we delete the answer in that case
         $iAnswerScales = $aQuestionTypeList[$sQuestionType]['answerscales'];
         $iSubquestionScales = $aQuestionTypeList[$sQuestionType]['subquestions'];
         // These are the questions types that have the other option therefore we set everything else to 'No Other'
         if ($sQuestionType != "L" && $sQuestionType != "!" && $sQuestionType != "P" && $sQuestionType != "M") {
             $_POST['other'] = 'N';
         }
         // These are the questions types that have no validation - so zap it accordingly
         if ($sQuestionType == "!" || $sQuestionType == "L" || $sQuestionType == "M" || $sQuestionType == "P" || $sQuestionType == "F" || $sQuestionType == "H" || $sQuestionType == "X" || $sQuestionType == "") {
             $_POST['preg'] = '';
         }
         // For Bootstrap Version usin YiiWheels switch :
         $_POST['mandatory'] = Yii::app()->request->getPost('mandatory') == '1' ? 'Y' : 'N';
         $_POST['other'] = Yii::app()->request->getPost('other') == '1' ? 'Y' : 'N';
         // These are the questions types that have no mandatory property - so zap it accordingly
         if ($sQuestionType == "X" || $sQuestionType == "|") {
             $_POST['mandatory'] = 'N';
         }
         if ($oldtype != $sQuestionType) {
             // TMSW Condition->Relevance:  Do similar check via EM, but do allow such a change since will be easier to modify relevance
             //Make sure there are no conditions based on this question, since we are changing the type
             $ccresult = Condition::model()->findAllByAttributes(array('cqid' => $iQuestionID));
             $cccount = count($ccresult);
             foreach ($ccresult as $ccr) {
                 $qidarray[] = $ccr['qid'];
             }
             if (isset($qidarray) && $qidarray) {
                 $qidlist = implode(", ", $qidarray);
             }
         }
         if (isset($cccount) && $cccount) {
             Yii::app()->setFlashMessage(gT("Question could not be updated. There are conditions for other questions that rely on the answers to this question and changing the type will cause problems. You must delete these conditions  before you can change the type of this question."), 'error');
         } else {
             if (isset($iQuestionGroupID) && $iQuestionGroupID != "") {
                 //                    $array_result=checkMoveQuestionConstraintsForConditions(sanitize_int($surveyid),sanitize_int($qid), sanitize_int($gid));
                 //                    // If there is no blocking conditions that could prevent this move
                 //
                 //                    if (is_null($array_result['notAbove']) && is_null($array_result['notBelow']))
                 //                    {
                 $aSurveyLanguages = Survey::model()->findByPk($iSurveyID)->additionalLanguages;
                 $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
                 array_push($aSurveyLanguages, $sBaseLanguage);
                 foreach ($aSurveyLanguages as $qlang) {
                     if (isset($qlang) && $qlang != "") {
                         // &eacute; to é and &amp; to & : really needed ? Why not for answers ? (130307)
                         $sQuestionText = Yii::app()->request->getPost('question_' . $qlang, '');
                         $sQuestionHelp = Yii::app()->request->getPost('help_' . $qlang, '');
                         // Fix bug with FCKEditor saving strange BR types : in rules ?
                         $sQuestionText = $oFixCKeditor->fixCKeditor($sQuestionText);
                         $sQuestionHelp = $oFixCKeditor->fixCKeditor($sQuestionHelp);
                         $udata = array('type' => $sQuestionType, 'title' => Yii::app()->request->getPost('title'), 'question' => $sQuestionText, 'preg' => Yii::app()->request->getPost('preg'), 'help' => $sQuestionHelp, 'gid' => $iQuestionGroupID, 'other' => Yii::app()->request->getPost('other'), 'mandatory' => Yii::app()->request->getPost('mandatory'), 'relevance' => Yii::app()->request->getPost('relevance'));
                         // Update question module
                         if (Yii::app()->request->getPost('module_name') != '') {
                             // The question module is not empty. So it's an external question module.
                             $udata['modulename'] = Yii::app()->request->getPost('module_name');
                         } else {
                             // If it was a module before, we must
                             $udata['modulename'] = '';
                         }
                         if ($oldgid != $iQuestionGroupID) {
                             if (getGroupOrder($iSurveyID, $oldgid) > getGroupOrder($iSurveyID, $iQuestionGroupID)) {
                                 // TMSW Condition->Relevance:  What is needed here?
                                 // Moving question to a 'upper' group
                                 // insert question at the end of the destination group
                                 // this prevent breaking conditions if the target qid is in the dest group
                                 $insertorder = getMaxQuestionOrder($iQuestionGroupID, $iSurveyID) + 1;
                                 $udata = array_merge($udata, array('question_order' => $insertorder));
                             } else {
                                 // Moving question to a 'lower' group
                                 // insert question at the beginning of the destination group
                                 shiftOrderQuestions($iSurveyID, $iQuestionGroupID, 1);
                                 // makes 1 spare room for new question at top of dest group
                                 $udata = array_merge($udata, array('question_order' => 0));
                             }
                         }
                         //$condn = array('sid' => $surveyid, 'qid' => $qid, 'language' => $qlang);
                         $oQuestion = Question::model()->findByPk(array("qid" => $iQuestionID, 'language' => $qlang));
                         foreach ($udata as $k => $v) {
                             $oQuestion->{$k} = $v;
                         }
                         $uqresult = $oQuestion->save();
                         //($uqquery); // or safeDie ("Error Update Question: ".$uqquery."<br />");  // Checked)
                         if (!$uqresult) {
                             $bOnError = true;
                             $aErrors = $oQuestion->getErrors();
                             if (count($aErrors)) {
                                 foreach ($aErrors as $sAttribute => $aStringErrors) {
                                     foreach ($aStringErrors as $sStringErrors) {
                                         Yii::app()->setFlashMessage(sprintf(gT("Question could not be updated with error on %s: %s"), $sAttribute, $sStringErrors), 'error');
                                     }
                                 }
                             } else {
                                 Yii::app()->setFlashMessage(gT("Question could not be updated."), 'error');
                             }
                         }
                     }
                 }
                 // Update the group ID on subquestions, too
                 if ($oldgid != $iQuestionGroupID) {
                     Question::model()->updateAll(array('gid' => $iQuestionGroupID), 'qid=:qid and parent_qid>0', array(':qid' => $iQuestionID));
                     // if the group has changed then fix the sortorder of old and new group
                     Question::model()->updateQuestionOrder($oldgid, $iSurveyID);
                     Question::model()->updateQuestionOrder($iQuestionGroupID, $iSurveyID);
                     // If some questions have conditions set on this question's answers
                     // then change the cfieldname accordingly
                     fixMovedQuestionConditions($iQuestionID, $oldgid, $iQuestionGroupID);
                 }
                 // Update subquestions
                 if ($oldtype != $sQuestionType) {
                     Question::model()->updateAll(array('type' => $sQuestionType), 'parent_qid=:qid', array(':qid' => $iQuestionID));
                 }
                 // Update subquestions if question module
                 if (Yii::app()->request->getPost('module_name') != '') {
                     // The question module is not empty. So it's an external question module.
                     Question::model()->updateAll(array('modulename' => Yii::app()->request->getPost('module_name')), 'parent_qid=:qid', array(':qid' => $iQuestionID));
                 } else {
                     // If it was a module before, we must
                     Question::model()->updateAll(array('modulename' => ''), 'parent_qid=:qid', array(':qid' => $iQuestionID));
                 }
                 Answer::model()->deleteAllByAttributes(array('qid' => $iQuestionID), 'scale_id >= :scale_id', array(':scale_id' => $iAnswerScales));
                 // Remove old subquestion scales
                 Question::model()->deleteAllByAttributes(array('parent_qid' => $iQuestionID), 'scale_id >= :scale_id', array(':scale_id' => $iSubquestionScales));
                 if (!isset($bOnError) || !$bOnError) {
                     // This really a quick hack and need a better system
                     Yii::app()->setFlashMessage(gT("Question was successfully saved."));
                 }
                 //                    }
                 //                    else
                 //                    {
                 //
                 //                        // There are conditions constraints: alert the user
                 //                        $errormsg="";
                 //                        if (!is_null($array_result['notAbove']))
                 //                        {
                 //                            $errormsg.=gT("This question relies on other question's answers and can't be moved above groupId:","js")
                 //                            . " " . $array_result['notAbove'][0][0] . " " . gT("in position","js")." ".$array_result['notAbove'][0][1]."\\n"
                 //                            . gT("See conditions:")."\\n";
                 //
                 //                            foreach ($array_result['notAbove'] as $notAboveCond)
                 //                            {
                 //                                $errormsg.="- cid:". $notAboveCond[3]."\\n";
                 //                            }
                 //
                 //                        }
                 //                        if (!is_null($array_result['notBelow']))
                 //                        {
                 //                            $errormsg.=gT("Some questions rely on this question's answers. You can't move this question below groupId:","js")
                 //                            . " " . $array_result['notBelow'][0][0] . " " . gT("in position","js")." ".$array_result['notBelow'][0][1]."\\n"
                 //                            . gT("See conditions:")."\\n";
                 //
                 //                            foreach ($array_result['notBelow'] as $notBelowCond)
                 //                            {
                 //                                $errormsg.="- cid:". $notBelowCond[3]."\\n";
                 //                            }
                 //                        }
                 //
                 //                        $databaseoutput .= "<script type=\"text/javascript\">\n<!--\n alert(\"$errormsg\")\n //-->\n</script>\n";
                 //                        $gid= $oldgid; // group move impossible ==> keep display on oldgid
                 //                    }
             } else {
                 Yii::app()->setFlashMessage(gT("Question could not be updated"), 'error');
             }
         }
         LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID);
         if ($sDBOutput != '') {
             echo $sDBOutput;
         } else {
             $closeAfterSave = Yii::app()->request->getPost('close-after-save') === 'true';
             if ($closeAfterSave) {
                 // Redirect to summary
                 $this->getController()->redirect(array('admin/questions/sa/view/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
             } else {
                 // Redirect to edit
                 $this->getController()->redirect(array('admin/questions/sa/editquestion/surveyid/' . $iSurveyID . '/gid/' . $iQuestionGroupID . '/qid/' . $iQuestionID));
                 // This works too: $this->getController()->redirect(Yii::app()->request->urlReferrer);
             }
         }
     }
     /**
      * updatesurveylocalesettings
      */
     if ($sAction == "updatesurveylocalesettings" && Permission::model()->hasSurveyPermission($iSurveyID, 'surveylocale', 'update')) {
         $languagelist = Survey::model()->findByPk($iSurveyID)->additionalLanguages;
         $languagelist[] = Survey::model()->findByPk($iSurveyID)->language;
         Yii::app()->loadHelper('database');
         foreach ($languagelist as $langname) {
             if ($langname) {
                 $url = Yii::app()->request->getPost('url_' . $langname);
                 if ($url == 'http://') {
                     $url = "";
                 }
                 $sURLDescription = html_entity_decode(Yii::app()->request->getPost('urldescrip_' . $langname), ENT_QUOTES, "UTF-8");
                 $sURL = html_entity_decode(Yii::app()->request->getPost('url_' . $langname), ENT_QUOTES, "UTF-8");
                 // Fix bug with FCKEditor saving strange BR types
                 $short_title = Yii::app()->request->getPost('short_title_' . $langname);
                 $description = Yii::app()->request->getPost('description_' . $langname);
                 $welcome = Yii::app()->request->getPost('welcome_' . $langname);
                 $endtext = Yii::app()->request->getPost('endtext_' . $langname);
                 $short_title = $oFixCKeditor->fixCKeditor($short_title);
                 $description = $oFixCKeditor->fixCKeditor($description);
                 $welcome = $oFixCKeditor->fixCKeditor($welcome);
                 $endtext = $oFixCKeditor->fixCKeditor($endtext);
                 $data = array('surveyls_title' => $short_title, 'surveyls_description' => $description, 'surveyls_welcometext' => $welcome, 'surveyls_endtext' => $endtext, 'surveyls_url' => $sURL, 'surveyls_urldescription' => $sURLDescription, 'surveyls_dateformat' => Yii::app()->request->getPost('dateformat_' . $langname), 'surveyls_numberformat' => Yii::app()->request->getPost('numberformat_' . $langname));
                 $SurveyLanguageSetting = SurveyLanguageSetting::model()->findByPk(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $langname));
                 $SurveyLanguageSetting->attributes = $data;
                 $SurveyLanguageSetting->save();
                 // save the change to database
             }
         }
         //Yii::app()->session['flashmessage'] = gT("Survey text elements successfully saved.");
         ////////////////////////////////////////////////////////////////////////////////////
         // General settings (copy / paste from surveyadmin::update)
         // Preload survey
         $oSurvey = Survey::model()->findByPk($iSurveyID);
         // Save plugin settings.
         $pluginSettings = App()->request->getPost('plugin', array());
         foreach ($pluginSettings as $plugin => $settings) {
             $settingsEvent = new PluginEvent('newSurveySettings');
             $settingsEvent->set('settings', $settings);
             $settingsEvent->set('survey', $iSurveyID);
             App()->getPluginManager()->dispatchEvent($settingsEvent, $plugin);
         }
         /* Start to fix some param before save (TODO : use models directly ?) */
         /* Date management */
         Yii::app()->loadHelper('surveytranslator');
         $formatdata = getDateFormatData(Yii::app()->session['dateformat']);
         Yii::app()->loadLibrary('Date_Time_Converter');
         $startdate = App()->request->getPost('startdate');
         if (trim($startdate) == "") {
             $startdate = null;
         } else {
             Yii::app()->loadLibrary('Date_Time_Converter');
             $datetimeobj = new date_time_converter($startdate, $formatdata['phpdate'] . ' H:i');
             //new Date_Time_Converter($startdate,$formatdata['phpdate'].' H:i');
             $startdate = $datetimeobj->convert("Y-m-d H:i:s");
         }
         $expires = App()->request->getPost('expires');
         if (trim($expires) == "") {
             $expires = null;
         } else {
             $datetimeobj = new date_time_converter($expires, $formatdata['phpdate'] . ' H:i');
             //new Date_Time_Converter($expires, $formatdata['phpdate'].' H:i');
             $expires = $datetimeobj->convert("Y-m-d H:i:s");
         }
         // We have $oSurvey : update and save it
         $oSurvey->owner_id = Yii::app()->request->getPost('owner_id');
         $oSurvey->admin = Yii::app()->request->getPost('admin');
         $oSurvey->expires = $expires;
         $oSurvey->startdate = $startdate;
         $oSurvey->faxto = App()->request->getPost('faxto');
         $oSurvey->format = App()->request->getPost('format');
         $oSurvey->template = Yii::app()->request->getPost('template');
         $oSurvey->assessments = App()->request->getPost('assessments');
         $oSurvey->additional_languages = Yii::app()->request->getPost('languageids');
         if ($oSurvey->active != 'Y') {
             $oSurvey->anonymized = App()->request->getPost('anonymized');
             $oSurvey->savetimings = App()->request->getPost('savetimings');
             $oSurvey->datestamp = App()->request->getPost('datestamp');
             $oSurvey->ipaddr = App()->request->getPost('ipaddr');
             $oSurvey->refurl = App()->request->getPost('refurl');
         }
         $oSurvey->publicgraphs = App()->request->getPost('publicgraphs');
         $oSurvey->usecookie = App()->request->getPost('usecookie');
         $oSurvey->allowregister = App()->request->getPost('allowregister');
         $oSurvey->allowsave = App()->request->getPost('allowsave');
         $oSurvey->navigationdelay = App()->request->getPost('navigationdelay');
         $oSurvey->printanswers = App()->request->getPost('printanswers');
         $oSurvey->publicstatistics = App()->request->getPost('publicstatistics');
         $oSurvey->autoredirect = App()->request->getPost('autoredirect');
         $oSurvey->showxquestions = App()->request->getPost('showxquestions');
         $oSurvey->showgroupinfo = App()->request->getPost('showgroupinfo');
         $oSurvey->showqnumcode = App()->request->getPost('showqnumcode');
         $oSurvey->shownoanswer = App()->request->getPost('shownoanswer');
         $oSurvey->showwelcome = App()->request->getPost('showwelcome');
         $oSurvey->allowprev = App()->request->getPost('allowprev');
         $oSurvey->questionindex = App()->request->getPost('questionindex');
         $oSurvey->nokeyboard = App()->request->getPost('nokeyboard');
         $oSurvey->showprogress = App()->request->getPost('showprogress');
         $oSurvey->listpublic = App()->request->getPost('public');
         $oSurvey->htmlemail = App()->request->getPost('htmlemail');
         $oSurvey->sendconfirmation = App()->request->getPost('sendconfirmation');
         $oSurvey->tokenanswerspersistence = App()->request->getPost('tokenanswerspersistence');
         $oSurvey->alloweditaftercompletion = App()->request->getPost('alloweditaftercompletion');
         $oSurvey->usecaptcha = Survey::transcribeCaptchaOptions();
         $oSurvey->emailresponseto = App()->request->getPost('emailresponseto');
         $oSurvey->emailnotificationto = App()->request->getPost('emailnotificationto');
         $oSurvey->googleanalyticsapikey = App()->request->getPost('googleanalyticsapikey');
         $oSurvey->googleanalyticsstyle = App()->request->getPost('googleanalyticsstyle');
         $oSurvey->tokenlength = App()->request->getPost('tokenlength');
         $oSurvey->adminemail = App()->request->getPost('adminemail');
         $oSurvey->bounce_email = App()->request->getPost('bounce_email');
         if ($oSurvey->save()) {
             Yii::app()->setFlashMessage(gT("Survey settings were successfully saved."));
         } else {
             Yii::app()->setFlashMessage(gT("Survey could not be updated."), "error");
             tracevar($oSurvey->getErrors());
         }
         /* Reload $oSurvey (language are fixed : need it ?) */
         $oSurvey = Survey::model()->findByPk($iSurveyID);
         /* Delete removed language cleanLanguagesFromSurvey do it already why redo it (cleanLanguagesFromSurvey must be moved to model) ?*/
         $aAvailableLanguage = $oSurvey->getAllLanguages();
         $oCriteria = new CDbCriteria();
         $oCriteria->compare('surveyls_survey_id', $iSurveyID);
         $oCriteria->addNotInCondition('surveyls_language', $aAvailableLanguage);
         SurveyLanguageSetting::model()->deleteAll($oCriteria);
         /* Add new language fixLanguageConsistency do it ?*/
         foreach ($oSurvey->additionalLanguages as $sLang) {
             if ($sLang) {
                 $oLanguageSettings = SurveyLanguageSetting::model()->find('surveyls_survey_id=:surveyid AND surveyls_language=:langname', array(':surveyid' => $iSurveyID, ':langname' => $sLang));
                 if (!$oLanguageSettings) {
                     $oLanguageSettings = new SurveyLanguageSetting();
                     $languagedetails = getLanguageDetails($sLang);
                     $oLanguageSettings->surveyls_survey_id = $iSurveyID;
                     $oLanguageSettings->surveyls_language = $sLang;
                     $oLanguageSettings->surveyls_title = '';
                     // Not in default model ?
                     $oLanguageSettings->surveyls_dateformat = $languagedetails['dateformat'];
                     if (!$oLanguageSettings->save()) {
                         Yii::app()->setFlashMessage(gT("Survey language could not be created."), "error");
                         tracevar($oLanguageSettings->getErrors());
                     }
                 }
             }
         }
         /* Language fix : remove and add question/group */
         cleanLanguagesFromSurvey($iSurveyID, implode(" ", $oSurvey->additionalLanguages));
         fixLanguageConsistency($iSurveyID, implode(" ", $oSurvey->additionalLanguages));
         // Url params in json
         $aURLParams = json_decode(Yii::app()->request->getPost('allurlparams'), true);
         SurveyURLParameter::model()->deleteAllByAttributes(array('sid' => $iSurveyID));
         if (isset($aURLParams)) {
             foreach ($aURLParams as $aURLParam) {
                 $aURLParam['parameter'] = trim($aURLParam['parameter']);
                 if ($aURLParam['parameter'] == '' || !preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $aURLParam['parameter']) || $aURLParam['parameter'] == 'sid' || $aURLParam['parameter'] == 'newtest' || $aURLParam['parameter'] == 'token' || $aURLParam['parameter'] == 'lang') {
                     continue;
                     // this parameter name seems to be invalid - just ignore it
                 }
                 unset($aURLParam['act']);
                 unset($aURLParam['title']);
                 unset($aURLParam['id']);
                 if ($aURLParam['targetqid'] == '') {
                     $aURLParam['targetqid'] = NULL;
                 }
                 if ($aURLParam['targetsqid'] == '') {
                     $aURLParam['targetsqid'] = NULL;
                 }
                 $aURLParam['sid'] = $iSurveyID;
                 $param = new SurveyURLParameter();
                 foreach ($aURLParam as $k => $v) {
                     $param->{$k} = $v;
                 }
                 $param->save();
             }
         }
         ////////////////////////////////////////
         if ($sDBOutput != '') {
             echo $sDBOutput;
         } else {
             if (Yii::app()->request->getPost('close-after-save') === 'true') {
                 $this->getController()->redirect(array('admin/survey/sa/view/surveyid/' . $iSurveyID));
             }
             $this->getController()->redirect(array('/admin/survey/sa/editlocalsettings/surveyid/' . $iSurveyID));
         }
     }
     $this->getController()->redirect(array("/admin"), "refresh");
 }
/**
* checkCompletedQuota() returns matched quotas information for the current response
* @param integer $surveyid - Survey identification number
* @param bool $return - set to true to return information, false do the quota
* @return array|void - nested array, Quotas->Members->Fields, includes quota information matched in session.
*/
function checkCompletedQuota($surveyid, $return = false)
{
    /* Check if session is set */
    if (!isset(App()->session['survey_' . $surveyid]['srid'])) {
        return;
    }
    /* Check is Response is already submitted : only when "do" the quota: allow to send information about quota */
    $oResponse = Response::model($surveyid)->findByPk(App()->session['survey_' . $surveyid]['srid']);
    if (!$return && $oResponse && !is_null($oResponse->submitdate)) {
        return;
    }
    static $aMatchedQuotas;
    // EM call 2 times quotas with 3 lines of php code, then use static.
    if (!$aMatchedQuotas) {
        $aMatchedQuotas = array();
        $quota_info = $aQuotasInfo = getQuotaInformation($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']);
        // $aQuotasInfo have an 'active' key, we don't use it ?
        if (!$aQuotasInfo || empty($aQuotasInfo)) {
            return $aMatchedQuotas;
        }
        // OK, we have some quota, then find if this $_SESSION have some set
        $aPostedFields = explode("|", Yii::app()->request->getPost('fieldnames', ''));
        // Needed for quota allowing update
        foreach ($aQuotasInfo as $aQuotaInfo) {
            if (count($aQuotaInfo['members']) === 0) {
                continue;
            }
            $iMatchedAnswers = 0;
            $bPostedField = false;
            // Array of field with quota array value
            $aQuotaFields = array();
            // Array of fieldnames with relevance value : EM fill $_SESSION with default value even is unrelevant (em_manager_helper line 6548)
            $aQuotaRelevantFieldnames = array();
            // To count number of hidden questions
            $aQuotaQid = array();
            foreach ($aQuotaInfo['members'] as $aQuotaMember) {
                $aQuotaFields[$aQuotaMember['fieldname']][] = $aQuotaMember['value'];
                $aQuotaRelevantFieldnames[$aQuotaMember['fieldname']] = isset($_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']]) && $_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']];
                $aQuotaQid[] = $aQuotaMember['qid'];
            }
            $aQuotaQid = array_unique($aQuotaQid);
            // For each field : test if actual responses is in quota (and is relevant)
            foreach ($aQuotaFields as $sFieldName => $aValues) {
                $bInQuota = isset($_SESSION['survey_' . $surveyid][$sFieldName]) && in_array($_SESSION['survey_' . $surveyid][$sFieldName], $aValues);
                if ($bInQuota && $aQuotaRelevantFieldnames[$sFieldName]) {
                    $iMatchedAnswers++;
                }
                if (in_array($sFieldName, $aPostedFields)) {
                    // Need only one posted value
                    $bPostedField = true;
                }
            }
            // Condition to count quota : Answers are the same in quota + an answer is submitted at this time (bPostedField) OR all questions is hidden (bAllHidden)
            $bAllHidden = QuestionAttribute::model()->countByAttributes(array('qid' => $aQuotaQid), 'attribute=:attribute', array(':attribute' => 'hidden')) == count($aQuotaQid);
            if ($iMatchedAnswers == count($aQuotaFields) && ($bPostedField || $bAllHidden)) {
                if ($aQuotaInfo['qlimit'] == 0) {
                    // Always add the quota if qlimit==0
                    $aMatchedQuotas[] = $aQuotaInfo;
                } else {
                    $iCompleted = getQuotaCompletedCount($surveyid, $aQuotaInfo['id']);
                    if (!is_null($iCompleted) && (int) $iCompleted >= (int) $aQuotaInfo['qlimit']) {
                        // This remove invalid quota and not completed
                        $aMatchedQuotas[] = $aQuotaInfo;
                    }
                }
            }
        }
    }
    if ($return) {
        return $aMatchedQuotas;
    }
    if (empty($aMatchedQuotas)) {
        return;
    }
    // Now we have all the information we need about the quotas and their status.
    // We need to construct the page and do all needed action
    $aSurveyInfo = getSurveyInfo($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']);
    $oTemplate = Template::model()->getInstance('', $surveyid);
    $sTemplatePath = $oTemplate->path;
    $sTemplateViewPath = $oTemplate->viewPath;
    $sClientToken = isset($_SESSION['survey_' . $surveyid]['token']) ? $_SESSION['survey_' . $surveyid]['token'] : "";
    // $redata for templatereplace
    $aDataReplacement = array('thissurvey' => $aSurveyInfo, 'clienttoken' => $sClientToken, 'token' => $sClientToken);
    // We take only the first matched quota, no need for each
    $aMatchedQuota = $aMatchedQuotas[0];
    // If a token is used then mark the token as completed, do it before event : this allow plugin to update token information
    $event = new PluginEvent('afterSurveyQuota');
    $event->set('surveyId', $surveyid);
    $event->set('responseId', $_SESSION['survey_' . $surveyid]['srid']);
    // We allways have a responseId
    $event->set('aMatchedQuotas', $aMatchedQuotas);
    // Give all the matched quota : the first is the active
    App()->getPluginManager()->dispatchEvent($event);
    $blocks = array();
    foreach ($event->getAllContent() as $blockData) {
        /* @var $blockData PluginEventContent */
        $blocks[] = CHtml::tag('div', array('id' => $blockData->getCssId(), 'class' => $blockData->getCssClass()), $blockData->getContent());
    }
    // Allow plugin to update message, url, url description and action
    $sMessage = $event->get('message', $aMatchedQuota['quotals_message']);
    $sUrl = $event->get('url', $aMatchedQuota['quotals_url']);
    $sUrlDescription = $event->get('urldescrip', $aMatchedQuota['quotals_urldescrip']);
    $sAction = $event->get('action', $aMatchedQuota['action']);
    $sAutoloadUrl = $event->get('autoloadurl', $aMatchedQuota['autoload_url']);
    // Doing the action and show the page
    if ($sAction == "1" && $sClientToken) {
        submittokens(true);
    }
    // Construct the default message
    $sMessage = templatereplace($sMessage, array(), $aDataReplacement, 'QuotaMessage', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true);
    $sUrl = passthruReplace($sUrl, $aSurveyInfo);
    $sUrl = templatereplace($sUrl, array(), $aDataReplacement, 'QuotaUrl', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true);
    $sUrlDescription = templatereplace($sUrlDescription, array(), $aDataReplacement, 'QuotaUrldescription', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true);
    // Construction of default message inside quotamessage class
    $sHtmlQuotaMessage = "<div class='quotamessage limesurveycore'>\n";
    $sHtmlQuotaMessage .= "\t" . $sMessage . "\n";
    $sHtmlQuotaUrl = $sUrl ? "<a href='" . $sUrl . "'>" . $sUrlDescription . "</a>" : "";
    // Add the navigator with Previous button if quota allow modification.
    if ($sAction == "2") {
        $sQuotaStep = isset($_SESSION['survey_' . $surveyid]['step']) ? $_SESSION['survey_' . $surveyid]['step'] : 0;
        // Surely not needed
        $sNavigator = CHtml::htmlButton(gT("Previous"), array('type' => 'submit', 'id' => "moveprevbtn", 'value' => $sQuotaStep, 'name' => 'move', 'accesskey' => 'p', 'class' => "submit button btn btn-default"));
        //$sNavigator .= " ".CHtml::htmlButton(gT("Submit"),array('type'=>'submit','id'=>"movesubmit",'value'=>"movesubmit",'name'=>"movesubmit",'accesskey'=>'l','class'=>"submit button"));
        $sHtmlQuotaMessage .= CHtml::form(array("/survey/index", "sid" => $surveyid), 'post', array('id' => 'limesurvey', 'name' => 'limesurvey', 'class' => 'survey-form-container QuotaMessage'));
        $sHtmlQuotaMessage .= templatereplace(file_get_contents($sTemplateViewPath . "/navigator.pstpl"), array('NAVIGATOR' => $sNavigator, 'SAVE' => ''), $aDataReplacement);
        $sHtmlQuotaMessage .= CHtml::hiddenField('sid', $surveyid);
        $sHtmlQuotaMessage .= CHtml::hiddenField('token', $sClientToken);
        // Did we really need it ?
        $sHtmlQuotaMessage .= CHtml::endForm();
    }
    $sHtmlQuotaMessage .= "</div>\n";
    // Add the plugin message before default message
    $sHtmlQuotaMessage = implode("\n", $blocks) . "\n" . $sHtmlQuotaMessage;
    // Send page to user and end.
    sendCacheHeaders();
    if ($sAutoloadUrl == 1 && $sUrl != "") {
        if ($sAction == "1") {
            killSurveySession($surveyid);
        }
        header("Location: " . $sUrl);
    }
    doHeader();
    echo templatereplace(file_get_contents($sTemplateViewPath . "/startpage.pstpl"), array(), $aDataReplacement);
    echo templatereplace(file_get_contents($sTemplateViewPath . "/completed.pstpl"), array("COMPLETED" => $sHtmlQuotaMessage, "URL" => $sHtmlQuotaUrl), $aDataReplacement);
    echo templatereplace(file_get_contents($sTemplateViewPath . "/endpage.pstpl"), array(), $aDataReplacement);
    doFooter();
    if ($sAction == "1") {
        killSurveySession($surveyid);
    }
    Yii::app()->end();
}
Exemplo n.º 16
0
 /**
  * Checks if a user has a certain permission
  *
  * @param $iEntityID integer The entity ID
  * @param $sEntityName string The entity name
  * @param $sPermission string Name of the permission
  * @param $sCRUD string The permission detail you want to check on: 'create','read','update','delete','import' or 'export'
  * @param $iUserID integer User ID - if not given the one of the current user is used
  * @return bool True if user has the permission
  */
 public function hasPermission($iEntityID, $sEntityName, $sPermission, $sCRUD = 'read', $iUserID = null)
 {
     // TODO: in entry script, if CConsoleApplication, set user as superadmin
     if (is_null($iUserID) && Yii::app() instanceof CConsoleApplication) {
         return true;
     }
     static $aPermissionStatic;
     /* Allow plugin to set own permission */
     // TODO: plugin should not be able to override the permission system (security issue),
     //      they should read permissions via the model
     //      and they should add row in permission table  (entity = plugin, etc)
     $oEvent = new PluginEvent('beforeHasPermission');
     $oEvent->set('iEntityID', $iEntityID);
     $oEvent->set('sEntityName', $sEntityName);
     $oEvent->set('sPermission', $sPermission);
     $oEvent->set('sCRUD', $sCRUD);
     $oEvent->set('iUserID', $iUserID);
     App()->getPluginManager()->dispatchEvent($oEvent);
     $pluginbPermission = $oEvent->get('bPermission');
     if (isset($pluginbPermission)) {
         return $pluginbPermission;
     }
     /* Always return true for CConsoleApplication (before or after plugin ? All other seems better after plugin) */
     // TODO: see above about entry script and superadmin
     if (is_null($iUserID) && Yii::app() instanceof CConsoleApplication) {
         return true;
     }
     /* Always return false for unknow sCRUD */
     // TODO: should not be necessary
     if (!in_array($sCRUD, array('create', 'read', 'update', 'delete', 'import', 'export'))) {
         return false;
     }
     $sCRUD = $sCRUD . '_p';
     /* Always return false for guests */
     // TODO: should not be necessary
     if (!$this->getUserId($iUserID)) {
         return false;
     } else {
         $iUserID = $this->getUserId($iUserID);
     }
     /* Always return true if you are the owner : this can be done in core plugin ? */
     // TODO: give the rights to owner adding line in permissions table, so it will return true with the normal way
     if ($iUserID == $this->getOwnerId($iEntityID, $sEntityName)) {
         return true;
     }
     /* Check if superadmin and static it */
     // TODO: give the rights to superadmin adding line in permissions table, so it will return true with the normal way
     if (!isset($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'])) {
         $aPermission = $this->findByAttributes(array("entity_id" => 0, 'entity' => 'global', "uid" => $iUserID, "permission" => 'superadmin'));
         $bPermission = is_null($aPermission) ? array() : $aPermission->attributes;
         if (!isset($bPermission['read_p']) || $bPermission['read_p'] == 0) {
             $bPermission = false;
         } else {
             $bPermission = true;
         }
         $aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'] = $bPermission;
     }
     if ($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p']) {
         return true;
     }
     /* Check in permission DB and static it */
     // TODO: that should be the only way to get the permission,
     // and it should be accessible from any object with relations :
     // $obj->permissions->read or $obj->permissions->write, etc.
     // relation :
     // 'permissions' => array(self::HAS_ONE, 'Permission', array(), 'condition'=> 'entity_id='.{ENTITYID}.' && uid='.Yii::app()->user->id.' && entity="{ENTITY}" && permission="{PERMISSIONS}"', 'together' => true ),
     if (!isset($aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD])) {
         $query = $this->findByAttributes(array("entity_id" => $iEntityID, "uid" => $iUserID, "entity" => $sEntityName, "permission" => $sPermission));
         $bPermission = is_null($query) ? array() : $query->attributes;
         if (!isset($bPermission[$sCRUD]) || $bPermission[$sCRUD] == 0) {
             $bPermission = false;
         } else {
             $bPermission = true;
         }
         $aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD] = $bPermission;
     }
     return $aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD];
 }
 /**
  * Performs a transformation of the response value.
  * Reload the survey to use own value
  *
  * @param string $sValue
  * @param string $fieldType
  * @param FormattingOptions $oOptions
  * @param string $sColumn The name of the column
  * @return string
  */
 protected function transformResponseValue($sValue, $fieldType, FormattingOptions $oOptions, $sColumn = null)
 {
     static $aColumnDone = array();
     // If $sValue is already done for column :; we can take it again, but a lot of memory ....
     if ($this->exportAnswerPosition == 'aseperatecodetext') {
         if (!array_key_exists($sColumn, $aColumnDone)) {
             $bExportAnswerCode = !self::sameTextAndCode($fieldType, $sColumn);
             $bExportAnswerText = self::sameTextAndCode($fieldType, $sColumn);
             $aColumnDone[$sColumn] = 1;
         } else {
             $bExportAnswerCode = false;
             $bExportAnswerText = true;
             unset($aColumnDone[$sColumn]);
         }
     } else {
         $bExportAnswerCode = $this->exportAnswerCode && !self::sameTextAndCode($fieldType, $sColumn);
         $bExportAnswerText = $this->exportAnswerText || self::sameTextAndCode($fieldType, $sColumn);
     }
     $sAnswerFull = "";
     $sAnswerText = "";
     $sAnswerCode = "";
     $oSurvey = $this->oSurvey;
     // We need survey to get answers ...
     // New event to allow another plugin to do something
     $oEvent = new PluginEvent('exportCompleteAnswersTransformResponseValue');
     $oEvent->set('sValue', $sValue);
     $oEvent->set('fieldType', $fieldType);
     $oEvent->set('oOptions', $oOptions);
     // Needed ?
     $oEvent->set('oSurvey', $oSurvey);
     App()->getPluginManager()->dispatchEvent($oEvent);
     $sAnswerFull = $oEvent->get('answerValue');
     // if $sAnswerFull is done by plugin, return it
     if (null !== $sAnswerFull) {
         return $sAnswerFull;
     }
     if ($bExportAnswerCode) {
         if (is_null($sValue)) {
             $sAnswerCode = $this->codeStringForNull;
         } else {
             $sAnswerCode = Writer::transformResponseValue($sValue, $fieldType, $oOptions, $sColumn);
         }
         if ($sValue != "" || $sValue === "" && $this->exportNullEmptyAnswerCode != "notempty" || is_null($sValue) && $this->exportNullEmptyAnswerCode == "always") {
             if ($this->exportAnswerPosition != 'aseperatecodetext') {
                 $sAnswerCode = $this->exportAnswerCodeBefore . $sAnswerCode . $this->exportAnswerCodeAfter;
             }
         }
     }
     if ($bExportAnswerText) {
         if (is_null($sValue)) {
             $sAnswerText = $this->textStringForNull;
         } else {
             $sAnswerText = Writer::transformResponseValue($oSurvey->getFullAnswer($sColumn, $sValue, $this->translator, $this->languageCode), $fieldType, $oOptions, $sColumn);
         }
         // Remove not needed N/A ....
         $aNaType = array('Y', 'G', 'M', 'P');
         if (in_array($fieldType, $aNaType) && $sAnswerText == "N/A") {
             $sAnswerText = "";
         }
     }
     if ($this->exportAnswerPosition == 'acodetext') {
         $sAnswerFull = $sAnswerCode . $sAnswerText;
     } elseif ($this->exportAnswerPosition == 'atextcode') {
         $sAnswerFull = $sAnswerText . $sAnswerCode;
     }
     return $sAnswerFull;
 }
Exemplo n.º 18
0
 /**
  * The pre-filter for controller actions.
  * This method is invoked before the currently requested controller action and all its filters
  * are executed. You may override this method with logic that needs to be done
  * before all controller actions.
  * @param CController $controller the controller
  * @param CAction $action the action
  * @return boolean whether the action should be executed.
  */
 public function beforeControllerAction($controller, $action)
 {
     /**
      * Plugin event done before all web controller action
      * Can set run to false to deactivate action
      */
     $event = new PluginEvent('beforeControllerAction');
     $event->set('controller', $controller->getId());
     $event->set('action', $action->getId());
     App()->getPluginManager()->dispatchEvent($event);
     return $event->get("run", parent::beforeControllerAction($controller, $action));
 }
Exemplo n.º 19
0
 /**
  * Send the register email with $_POST value
  * @param $iSurveyId Survey Id to register
  * @return boolean : if email is set to sent (before SMTP problem)
  */
 public function sendRegistrationEmail($iSurveyId, $iTokenId)
 {
     $sLanguage = App()->language;
     $aSurveyInfo = getSurveyInfo($iSurveyId, $sLanguage);
     $aMail['subject'] = $aSurveyInfo['email_register_subj'];
     $aMail['message'] = $aSurveyInfo['email_register'];
     $aReplacementFields = array();
     $aReplacementFields["{ADMINNAME}"] = $aSurveyInfo['adminname'];
     $aReplacementFields["{ADMINEMAIL}"] = $aSurveyInfo['adminemail'];
     $aReplacementFields["{SURVEYNAME}"] = $aSurveyInfo['name'];
     $aReplacementFields["{SURVEYDESCRIPTION}"] = $aSurveyInfo['description'];
     $aReplacementFields["{EXPIRY}"] = $aSurveyInfo["expiry"];
     $oToken = Token::model($iSurveyId)->findByPk($iTokenId);
     // Reload the token (needed if just created)
     foreach ($oToken->attributes as $attribute => $value) {
         $aReplacementFields["{" . strtoupper($attribute) . "}"] = $value;
     }
     $sToken = $oToken->token;
     $useHtmlEmail = getEmailFormat($iSurveyId) == 'html';
     $aMail['subject'] = preg_replace("/{TOKEN:([A-Z0-9_]+)}/", "{" . "\$1" . "}", $aMail['subject']);
     $aMail['message'] = preg_replace("/{TOKEN:([A-Z0-9_]+)}/", "{" . "\$1" . "}", $aMail['message']);
     $aReplacementFields["{SURVEYURL}"] = App()->createAbsoluteUrl("/survey/index/sid/{$iSurveyId}", array('lang' => $sLanguage, 'token' => $sToken));
     $aReplacementFields["{OPTOUTURL}"] = App()->createAbsoluteUrl("/optout/tokens/surveyid/{$iSurveyId}", array('langcode' => $sLanguage, 'token' => $sToken));
     $aReplacementFields["{OPTINURL}"] = App()->createAbsoluteUrl("/optin/tokens/surveyid/{$iSurveyId}", array('langcode' => $sLanguage, 'token' => $sToken));
     foreach (array('OPTOUT', 'OPTIN', 'SURVEY') as $key) {
         $url = $aReplacementFields["{{$key}URL}"];
         if ($useHtmlEmail) {
             $aReplacementFields["{{$key}URL}"] = "<a href='{$url}'>" . htmlspecialchars($url) . '</a>';
         }
         $aMail['subject'] = str_replace("@@{$key}URL@@", $url, $aMail['subject']);
         $aMail['message'] = str_replace("@@{$key}URL@@", $url, $aMail['message']);
     }
     // Replace the fields
     $aMail['subject'] = ReplaceFields($aMail['subject'], $aReplacementFields);
     $aMail['message'] = ReplaceFields($aMail['message'], $aReplacementFields);
     $sFrom = "{$aSurveyInfo['adminname']} <{$aSurveyInfo['adminemail']}>";
     $sBounce = getBounceEmail($iSurveyId);
     $sTo = $oToken->email;
     $sitename = Yii::app()->getConfig('sitename');
     // Plugin event for email handling (Same than admin token but with register type)
     $event = new PluginEvent('beforeTokenEmail');
     $event->set('type', 'register');
     $event->set('subject', $aMail['subject']);
     $event->set('to', $sTo);
     $event->set('body', $aMail['message']);
     $event->set('from', $sFrom);
     $event->set('bounce', $sBounce);
     $event->set('token', $oToken->attributes);
     $aMail['subject'] = $event->get('subject');
     $aMail['message'] = $event->get('body');
     $sTo = $event->get('to');
     $sFrom = $event->get('from');
     if ($event->get('send', true) == false) {
         $this->sMessage = $event->get('message', '');
         if ($event->get('error') == null) {
             // mimic token system, set send to today
             $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig('timeadjust'));
             $oToken->sent = $today;
             $oToken->save();
         }
     } elseif (SendEmailMessage($aMail['message'], $aMail['subject'], $sTo, $sFrom, $sitename, $useHtmlEmail, $sBounce)) {
         // TLR change to put date into sent
         $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig('timeadjust'));
         $oToken->sent = $today;
         $oToken->save();
         $this->sMessage = "<div id='wrapper' class='message tokenmessage'>" . "<p>" . gT("Thank you for registering to participate in this survey.") . "</p>\n" . "<p>{$this->sMailMessage}</p>\n" . "<p>" . sprintf(gT("Survey administrator %s (%s)"), $aSurveyInfo['adminname'], $aSurveyInfo['adminemail']) . "</p>" . "</div>\n";
     } else {
         $this->sMessage = "<div id='wrapper' class='message tokenmessage'>" . "<p>" . gT("Thank you for registering to participate in this survey.") . "</p>\n" . "<p>" . gT("You are registered but an error happened when trying to send the email - please contact the survey administrator.") . "</p>\n" . "<p>" . sprintf(gT("Survey administrator %s (%s)"), $aSurveyInfo['adminname'], $aSurveyInfo['adminemail']) . "</p>" . "</div>\n";
     }
     // Allways return true : if we come here, we allways trye to send an email
     return true;
 }
Exemplo n.º 20
0
 public function save($runValidation = true, $attributes = null)
 {
     $beforeTokenSave = new PluginEvent('beforeTokenSave');
     $beforeTokenSave->set('model', $this);
     $beforeTokenSave->set('iSurveyID', $this->dynamicId);
     App()->getPluginManager()->dispatchEvent($beforeTokenSave);
     return parent::save($runValidation, $attributes);
 }
Exemplo n.º 21
0
 function action()
 {
     global $surveyid;
     global $thissurvey, $thisstep;
     global $clienttoken, $tokensexist, $token;
     // only attempt to change session lifetime if using a DB backend
     // with file based sessions, it's up to the admin to configure maxlifetime
     if (isset(Yii::app()->session->connectionID)) {
         @ini_set('session.gc_maxlifetime', Yii::app()->getConfig('iSessionExpirationTime'));
     }
     $this->_loadRequiredHelpersAndLibraries();
     $param = $this->_getParameters(func_get_args(), $_POST);
     $surveyid = $param['sid'];
     Yii::app()->setConfig('surveyID', $surveyid);
     $thisstep = $param['thisstep'];
     $move = getMove();
     Yii::app()->setConfig('move', $move);
     $clienttoken = trim($param['token']);
     $standardtemplaterootdir = Yii::app()->getConfig('standardtemplaterootdir');
     if (is_null($thissurvey) && !is_null($surveyid)) {
         $thissurvey = getSurveyInfo($surveyid);
     }
     // unused vars in this method (used in methods using compacted method vars)
     @($loadname = $param['loadname']);
     @($loadpass = $param['loadpass']);
     $sitename = Yii::app()->getConfig('sitename');
     if (isset($param['newtest']) && $param['newtest'] == "Y") {
         killSurveySession($surveyid);
     }
     $surveyExists = $surveyid && Survey::model()->findByPk($surveyid);
     $isSurveyActive = $surveyExists && Survey::model()->findByPk($surveyid)->active == "Y";
     // collect all data in this method to pass on later
     $redata = compact(array_keys(get_defined_vars()));
     $this->_loadLimesurveyLang($surveyid);
     if ($this->_isClientTokenDifferentFromSessionToken($clienttoken, $surveyid)) {
         $sReloadUrl = $this->getController()->createUrl("/survey/index/sid/{$surveyid}", array('token' => $clienttoken, 'lang' => App()->language, 'newtest' => 'Y'));
         $asMessage = array(gT('Token mismatch'), gT('The token you provided doesn\'t match the one in your session.'), "<a class='reloadlink newsurvey' href={$sReloadUrl}>" . gT("Click here to start the survey.") . "</a>");
         $this->_createNewUserSessionAndRedirect($surveyid, $redata, __LINE__, $asMessage);
     }
     if ($this->_isSurveyFinished($surveyid) && ($thissurvey['alloweditaftercompletion'] != 'Y' || $thissurvey['tokenanswerspersistence'] != 'Y')) {
         $aReloadUrlParam = array('lang' => App()->language, 'newtest' => 'Y');
         if ($clienttoken) {
             $aReloadUrlParam['token'] = $clienttoken;
         }
         $sReloadUrl = $this->getController()->createUrl("/survey/index/sid/{$surveyid}", $aReloadUrlParam);
         $asMessage = array(gT('Previous session is set to be finished.'), gT('Your browser reports that it was used previously to answer this survey. We are resetting the session so that you can start from the beginning.'), "<a class='reloadlink newsurvey' href={$sReloadUrl}>" . gT("Click here to start the survey.") . "</a>");
         $this->_createNewUserSessionAndRedirect($surveyid, $redata, __LINE__, $asMessage);
     }
     $previewmode = false;
     if (isset($param['action']) && in_array($param['action'], array('previewgroup', 'previewquestion'))) {
         if (!$this->_canUserPreviewSurvey($surveyid)) {
             $asMessage = array(gT('Error'), gT("We are sorry but you don't have permissions to do this."));
             $this->_niceExit($redata, __LINE__, null, $asMessage);
         } else {
             if (intval($param['qid']) && $param['action'] == 'previewquestion') {
                 $previewmode = 'question';
             }
             if (intval($param['gid']) && $param['action'] == 'previewgroup') {
                 $previewmode = 'group';
             }
         }
     }
     Yii::app()->setConfig('previewmode', $previewmode);
     if ($this->_surveyCantBeViewedWithCurrentPreviewAccess($surveyid, $isSurveyActive, $surveyExists)) {
         $bPreviewRight = $this->_userHasPreviewAccessSession($surveyid);
         if ($bPreviewRight === false) {
             $asMessage = array(gT("Error"), gT("We are sorry but you don't have permissions to do this."), sprintf(gT("Please contact %s ( %s ) for further assistance."), $thissurvey['adminname'], $thissurvey['adminemail']));
             $this->_niceExit($redata, __LINE__, null, $asMessage);
         }
     }
     // TODO can this be moved to the top?
     // (Used to be global, used in ExpressionManager, merged into amVars. If not filled in === '')
     // can this be added in the first computation of $redata?
     if (isset($_SESSION['survey_' . $surveyid]['srid'])) {
         $saved_id = $_SESSION['survey_' . $surveyid]['srid'];
     }
     // recompute $redata since $saved_id used to be a global
     $redata = compact(array_keys(get_defined_vars()));
     if ($this->_didSessionTimeOut($surveyid)) {
         // @TODO is this still required ?
         $asMessage = array(gT("Error"), gT("We are sorry but your session has expired."), gT("Either you have been inactive for too long, you have cookies disabled for your browser, or there were problems with your connection."), sprintf(gT("Please contact %s ( %s ) for further assistance."), $thissurvey['adminname'], $thissurvey['adminemail']));
         $this->_niceExit($redata, __LINE__, null, $asMessage);
     }
     // Set the language of the survey, either from POST, GET parameter of session var
     // Keep the old value, because SetSurveyLanguage update $_SESSION
     $sOldLang = isset($_SESSION['survey_' . $surveyid]['s_lang']) ? $_SESSION['survey_' . $surveyid]['s_lang'] : "";
     // Keep the old value, because SetSurveyLanguage update $_SESSION
     if (!empty($param['lang'])) {
         $sDisplayLanguage = $param['lang'];
         // $param take lang from returnGlobal and returnGlobal sanitize langagecode
     } elseif (isset($_SESSION['survey_' . $surveyid]['s_lang'])) {
         $sDisplayLanguage = $_SESSION['survey_' . $surveyid]['s_lang'];
     } elseif (Survey::model()->findByPk($surveyid)) {
         $sDisplayLanguage = Survey::model()->findByPk($surveyid)->language;
     } else {
         $sDisplayLanguage = Yii::app()->getConfig('defaultlang');
     }
     //CHECK FOR REQUIRED INFORMATION (sid)
     if ($surveyid && $surveyExists) {
         LimeExpressionManager::SetSurveyId($surveyid);
         // must be called early - it clears internal cache if a new survey is being used
         SetSurveyLanguage($surveyid, $sDisplayLanguage);
         if ($previewmode) {
             LimeExpressionManager::SetPreviewMode($previewmode);
         }
         if (App()->language != $sOldLang) {
             UpdateGroupList($surveyid, App()->language);
             // to refresh the language strings in the group list session variable
             UpdateFieldArray();
             // to refresh question titles and question text
         }
     } else {
         throw new CHttpException(404, "The survey in which you are trying to participate does not seem to exist. It may have been deleted or the link you were given is outdated or incorrect.");
     }
     // Get token
     if (!isset($token)) {
         $token = $clienttoken;
     }
     //GET BASIC INFORMATION ABOUT THIS SURVEY
     $thissurvey = getSurveyInfo($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']);
     $event = new PluginEvent('beforeSurveyPage');
     $event->set('surveyId', $surveyid);
     App()->getPluginManager()->dispatchEvent($event);
     if (!is_null($event->get('template'))) {
         $thissurvey['templatedir'] = $event->get('template');
     }
     //SEE IF SURVEY USES TOKENS
     if ($surveyExists == 1 && tableExists('{{tokens_' . $thissurvey['sid'] . '}}')) {
         $tokensexist = 1;
     } else {
         $tokensexist = 0;
         unset($_POST['token']);
         unset($param['token']);
         unset($token);
         unset($clienttoken);
     }
     //SET THE TEMPLATE DIRECTORY
     global $oTemplate;
     $thistpl = $oTemplate->viewPath;
     $timeadjust = Yii::app()->getConfig("timeadjust");
     //MAKE SURE SURVEY HASN'T EXPIRED
     if ($thissurvey['expiry'] != '' and dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust) > $thissurvey['expiry'] && $thissurvey['active'] != 'N' && !$previewmode) {
         $redata = compact(array_keys(get_defined_vars()));
         $asMessage = array(gT("Error"), gT("This survey is no longer available."), sprintf(gT("Please contact %s ( %s ) for further assistance."), $thissurvey['adminname'], $thissurvey['adminemail']));
         $this->_niceExit($redata, __LINE__, $thissurvey['templatedir'], $asMessage);
     }
     //MAKE SURE SURVEY IS ALREADY VALID
     if ($thissurvey['startdate'] != '' and dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust) < $thissurvey['startdate'] && $thissurvey['active'] != 'N' && !$previewmode) {
         $redata = compact(array_keys(get_defined_vars()));
         $asMessage = array(gT("Error"), gT("This survey is not yet started."), sprintf(gT("Please contact %s ( %s ) for further assistance."), $thissurvey['adminname'], $thissurvey['adminemail']));
         $this->_niceExit($redata, __LINE__, $thissurvey['templatedir'], $asMessage);
     }
     //CHECK FOR PREVIOUSLY COMPLETED COOKIE
     //If cookies are being used, and this survey has been completed, a cookie called "PHPSID[sid]STATUS" will exist (ie: SID6STATUS) and will have a value of "COMPLETE"
     $sCookieName = "LS_" . $surveyid . "_STATUS";
     if (isset($_COOKIE[$sCookieName]) && $_COOKIE[$sCookieName] == "COMPLETE" && $thissurvey['usecookie'] == "Y" && $tokensexist != 1 && (!isset($param['newtest']) || $param['newtest'] != "Y")) {
         $redata = compact(array_keys(get_defined_vars()));
         $asMessage = array(gT("Error"), gT("You have already completed this survey."), sprintf(gT("Please contact %s ( %s ) for further assistance."), $thissurvey['adminname'], $thissurvey['adminemail']));
         $this->_niceExit($redata, __LINE__, $thissurvey['templatedir'], $asMessage);
     }
     //LOAD SAVED SURVEY
     if (Yii::app()->request->getParam('loadall') == "reload") {
         $errormsg = "";
         $sLoadName = Yii::app()->request->getParam('loadname');
         $sLoadPass = Yii::app()->request->getParam('loadpass');
         if (isset($sLoadName) && !$sLoadName) {
             $errormsg .= gT("You did not provide a name") . "<br />\n";
         }
         if (isset($sLoadPass) && !$sLoadPass) {
             $errormsg .= gT("You did not provide a password") . "<br />\n";
         }
         // if security question answer is incorrect
         // Not called if scid is set in GET params (when using email save/reload reminder URL)
         if (function_exists("ImageCreate") && isCaptchaEnabled('saveandloadscreen', $thissurvey['usecaptcha']) && is_null(Yii::app()->request->getQuery('scid'))) {
             $sLoadSecurity = Yii::app()->request->getPost('loadsecurity');
             if (empty($sLoadSecurity)) {
                 $errormsg .= gT("You did not answer to the security question.") . "<br />\n";
             } elseif (!isset($_SESSION['survey_' . $surveyid]['secanswer']) || $sLoadSecurity != $_SESSION['survey_' . $surveyid]['secanswer']) {
                 $errormsg .= gT("The answer to the security question is incorrect.") . "<br />\n";
             }
         }
         if ($errormsg == "") {
             LimeExpressionManager::SetDirtyFlag();
             buildsurveysession($surveyid);
             if (loadanswers()) {
                 Yii::app()->setConfig('move', 'reload');
                 $move = "reload";
                 // veyRunTimeHelper use $move in $arg
             } else {
                 $errormsg .= gT("There is no matching saved survey");
             }
         }
         if ($errormsg) {
             Yii::app()->setConfig('move', "loadall");
             // Show loading form
         }
     }
     //Allow loading of saved survey
     if (Yii::app()->getConfig('move') == "loadall") {
         $redata = compact(array_keys(get_defined_vars()));
         Yii::import("application.libraries.Load_answers");
         $tmp = new Load_answers();
         $tmp->run($redata);
     }
     //Check if TOKEN is used for EVERY PAGE
     //This function fixes a bug where users able to submit two surveys/votes
     //by checking that the token has not been used at each page displayed.
     // bypass only this check at first page (Step=0) because
     // this check is done in buildsurveysession and error message
     // could be more interresting there (takes into accound captcha if used)
     if ($tokensexist == 1 && isset($token) && $token != "" && isset($_SESSION['survey_' . $surveyid]['step']) && $_SESSION['survey_' . $surveyid]['step'] > 0 && tableExists("tokens_{$surveyid}}}")) {
         // check also if it is allowed to change survey after completion
         if ($thissurvey['alloweditaftercompletion'] == 'Y') {
             $tokenInstance = Token::model($surveyid)->findByAttributes(array('token' => $token));
         } else {
             $tokenInstance = Token::model($surveyid)->usable()->incomplete()->findByAttributes(array('token' => $token));
         }
         if (!isset($tokenInstance) && !$previewmode) {
             //TOKEN DOESN'T EXIST OR HAS ALREADY BEEN USED. EXPLAIN PROBLEM AND EXIT
             $asMessage = array(null, gT("This is a controlled survey. You need a valid token to participate."), sprintf(gT("For further information please contact %s"), $thissurvey['adminname'] . " (<a href='mailto:{$thissurvey['adminemail']}'>" . "{$thissurvey['adminemail']}</a>)"));
             $this->_niceExit($redata, __LINE__, $thistpl, $asMessage, true);
         }
     }
     if ($tokensexist == 1 && isset($token) && $token != "" && tableExists("{{tokens_" . $surveyid . "}}") && !$previewmode) {
         // check also if it is allowed to change survey after completion
         if ($thissurvey['alloweditaftercompletion'] == 'Y') {
             $tokenInstance = Token::model($surveyid)->editable()->findByAttributes(array('token' => $token));
         } else {
             $tokenInstance = Token::model($surveyid)->usable()->incomplete()->findByAttributes(array('token' => $token));
         }
         if (!isset($tokenInstance)) {
             $oToken = Token::model($surveyid)->findByAttributes(array('token' => $token));
             if ($oToken) {
                 $now = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", Yii::app()->getConfig("timeadjust"));
                 if ($oToken->completed != 'N' && !empty($oToken->completed)) {
                     $sError = gT("This invitation has already been used.");
                 } elseif (strtotime($now) < strtotime($oToken->validfrom)) {
                     $sError = gT("This invitation is not valid yet.");
                 } elseif (strtotime($now) > strtotime($oToken->validuntil)) {
                     $sError = gT("This invitation is not valid anymore.");
                 } else {
                     $sError = gT("This is a controlled survey. You need a valid token to participate.");
                 }
             } else {
                 $sError = gT("This is a controlled survey. You need a valid token to participate.");
             }
             $asMessage = array($sError, gT("We are sorry but you are not allowed to enter this survey."), sprintf(gT("For further information please contact %s"), $thissurvey['adminname'] . " (<a href='mailto:{$thissurvey['adminemail']}'>" . "{$thissurvey['adminemail']}</a>)"));
             $this->_niceExit($redata, __LINE__, $thistpl, $asMessage, true);
         }
     }
     //Clear session and remove the incomplete response if requested.
     if (isset($move) && $move == "clearall") {
         // delete the response but only if not already completed
         $s_lang = $_SESSION['survey_' . $surveyid]['s_lang'];
         if (isset($_SESSION['survey_' . $surveyid]['srid']) && !SurveyDynamic::model($surveyid)->isCompleted($_SESSION['survey_' . $surveyid]['srid'])) {
             // delete the response but only if not already completed
             $result = dbExecuteAssoc('DELETE FROM {{survey_' . $surveyid . '}} WHERE id=' . $_SESSION['survey_' . $surveyid]['srid'] . " AND submitdate IS NULL");
             if ($result->count() > 0) {
                 // Using count() here *should* be okay for MSSQL because it is a delete statement
                 // find out if there are any fuqt questions - checked
                 $fieldmap = createFieldMap($surveyid, 'short', false, false, $s_lang);
                 foreach ($fieldmap as $field) {
                     if ($field['type'] == "|" && !strpos($field['fieldname'], "_filecount")) {
                         if (!isset($qid)) {
                             $qid = array();
                         }
                         $qid[] = $field['fieldname'];
                     }
                 }
                 // if yes, extract the response json to those questions
                 if (isset($qid)) {
                     $query = "SELECT * FROM {{survey_" . $surveyid . "}} WHERE id=" . $_SESSION['survey_' . $surveyid]['srid'];
                     $result = dbExecuteAssoc($query);
                     foreach ($result->readAll() as $row) {
                         foreach ($qid as $question) {
                             $json = $row[$question];
                             if ($json == "" || $json == NULL) {
                                 continue;
                             }
                             // decode them
                             $phparray = json_decode($json);
                             foreach ($phparray as $metadata) {
                                 $target = Yii::app()->getConfig("uploaddir") . "/surveys/" . $surveyid . "/files/";
                                 // delete those files
                                 unlink($target . $metadata->filename);
                             }
                         }
                     }
                 }
                 // done deleting uploaded files
             }
             // also delete a record from saved_control when there is one
             dbExecuteAssoc('DELETE FROM {{saved_control}} WHERE srid=' . $_SESSION['survey_' . $surveyid]['srid'] . ' AND sid=' . $surveyid);
         }
         killSurveySession($surveyid);
         sendCacheHeaders();
         doHeader();
         $redata = compact(array_keys(get_defined_vars()));
         $this->_printTemplateContent($thistpl . '/startpage.pstpl', $redata, __LINE__);
         echo "\n\n<!-- JAVASCRIPT FOR CONDITIONAL QUESTIONS -->\n" . "\t<script type='text/javascript'>\n" . "\t<!--\n" . "function checkconditions(value, name, type, evt_type)\n" . "\t{\n" . "\t}\n" . "\t//-->\n" . "\t</script>\n\n";
         //Present the clear all page using clearall.pstpl template
         $this->_printTemplateContent($thistpl . '/clearall.pstpl', $redata, __LINE__);
         $this->_printTemplateContent($thistpl . '/endpage.pstpl', $redata, __LINE__);
         doFooter();
         exit;
     }
     //Check to see if a refering URL has been captured.
     if (!isset($_SESSION['survey_' . $surveyid]['refurl'])) {
         $_SESSION['survey_' . $surveyid]['refurl'] = GetReferringUrl();
         // do not overwrite refurl
     }
     // Let's do this only if
     //  - a saved answer record hasn't been loaded through the saved feature
     //  - the survey is not anonymous
     //  - the survey is active
     //  - a token information has been provided
     //  - the survey is setup to allow token-response-persistence
     if (!isset($_SESSION['survey_' . $surveyid]['srid']) && $thissurvey['anonymized'] == "N" && $thissurvey['active'] == "Y" && isset($token) && $token != '') {
         // load previous answers if any (dataentry with nosubmit)
         $oResponses = Response::model($surveyid)->findAllByAttributes(array('token' => $token), array('order' => 'id DESC'));
         if (!empty($oResponses)) {
             /**
              * We fire the response selection event when at least 1 response was found.
              * If there is just 1 response the plugin still has to option to choose
              * NOT to use it.
              */
             $event = new PluginEvent('beforeLoadResponse');
             $event->set('responses', $oResponses);
             $event->set('surveyId', $surveyid);
             App()->pluginManager->dispatchEvent($event);
             $oResponse = $event->get('response');
             // If $oResponse is false we act as if no response was found.
             // This allows a plugin to deny continuing a response.
             if ($oResponse !== false) {
                 // If plugin does not set a response we use the first one found, (this replicates pre-plugin behavior)
                 if (!isset($oResponse) && (!isset($oResponses[0]->submitdate) || $thissurvey['alloweditaftercompletion'] == 'Y') && $thissurvey['tokenanswerspersistence'] == 'Y') {
                     $oResponse = $oResponses[0];
                 }
                 if (isset($oResponse)) {
                     $_SESSION['survey_' . $surveyid]['srid'] = $oResponse->id;
                     if (!empty($oResponse->lastpage)) {
                         $_SESSION['survey_' . $surveyid]['LEMtokenResume'] = true;
                         // If the response was completed and user is allowed to edit after completion start at the beginning and not at the last page - just makes more sense
                         if (!($oResponse->submitdate && $thissurvey['alloweditaftercompletion'] == 'Y')) {
                             $_SESSION['survey_' . $surveyid]['step'] = $oResponse->lastpage;
                         }
                     }
                     buildsurveysession($surveyid);
                     if (!empty($oResponse->submitdate)) {
                         $_SESSION['survey_' . $surveyid]['maxstep'] = $_SESSION['survey_' . $surveyid]['totalsteps'];
                     }
                     loadanswers();
                 }
             }
         }
     }
     // Preview action : Preview right already tested before
     if ($previewmode) {
         // Unset all SESSION: be sure to have the last version
         unset($_SESSION['fieldmap-' . $surveyid . App()->language]);
         // Needed by createFieldMap: else fieldmap can be outdated
         unset($_SESSION['survey_' . $surveyid]);
         if ($param['action'] == 'previewgroup') {
             $thissurvey['format'] = 'G';
         } elseif ($param['action'] == 'previewquestion') {
             $thissurvey['format'] = 'S';
         }
         buildsurveysession($surveyid, true);
     }
     sendCacheHeaders();
     //Send local variables to the appropriate survey type
     unset($redata);
     $redata = compact(array_keys(get_defined_vars()));
     Yii::import('application.helpers.SurveyRuntimeHelper');
     $tmp = new SurveyRuntimeHelper();
     $tmp->run($surveyid, $redata);
     if (isset($_POST['saveall']) || isset($flashmessage)) {
         echo "<script type='text/javascript'> \$(document).ready( function() { alert('" . gT("Your responses were successfully saved.", "js") . "');}) </script>";
     }
 }
Exemplo n.º 22
0
 /**
  * Main function
  *
  * @param mixed $surveyid
  * @param mixed $args
  */
 function run($surveyid, $args)
 {
     global $errormsg;
     extract($args);
     if (!$thissurvey) {
         $thissurvey = getSurveyInfo($surveyid);
     }
     $LEMsessid = 'survey_' . $surveyid;
     $this->setJavascriptVar($surveyid, isset($clang->langcode) ? $clang->langcode : $thissurvey['language']);
     $sTemplatePath = getTemplatePath(Yii::app()->getConfig("defaulttemplate")) . DIRECTORY_SEPARATOR;
     if (isset($_SESSION['survey_' . $surveyid]['templatepath'])) {
         $sTemplatePath = $_SESSION['survey_' . $surveyid]['templatepath'];
     }
     // $LEMdebugLevel - customizable debugging for Lime Expression Manager
     $LEMdebugLevel = 0;
     // LEM_DEBUG_TIMING;    // (LEM_DEBUG_TIMING + LEM_DEBUG_VALIDATION_SUMMARY + LEM_DEBUG_VALIDATION_DETAIL);
     $LEMskipReprocessing = false;
     // true if used GetLastMoveResult to avoid generation of unneeded extra JavaScript
     switch ($thissurvey['format']) {
         case "A":
             //All in one
             $surveyMode = 'survey';
             break;
         default:
         case "S":
             //One at a time
             $surveyMode = 'question';
             break;
         case "G":
             //Group at a time
             $surveyMode = 'group';
             break;
     }
     $radix = getRadixPointData($thissurvey['surveyls_numberformat']);
     $radix = $radix['separator'];
     $surveyOptions = array('active' => $thissurvey['active'] == 'Y', 'allowsave' => $thissurvey['allowsave'] == 'Y', 'anonymized' => $thissurvey['anonymized'] != 'N', 'assessments' => $thissurvey['assessments'] == 'Y', 'datestamp' => $thissurvey['datestamp'] == 'Y', 'deletenonvalues' => Yii::app()->getConfig('deletenonvalues'), 'hyperlinkSyntaxHighlighting' => ($LEMdebugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY, 'ipaddr' => $thissurvey['ipaddr'] == 'Y', 'radix' => $radix, 'refurl' => $thissurvey['refurl'] == "Y" && isset($_SESSION[$LEMsessid]['refurl']) ? $_SESSION[$LEMsessid]['refurl'] : NULL, 'savetimings' => $thissurvey['savetimings'] == "Y", 'surveyls_dateformat' => isset($thissurvey['surveyls_dateformat']) ? $thissurvey['surveyls_dateformat'] : 1, 'startlanguage' => isset($clang->langcode) ? $clang->langcode : $thissurvey['language'], 'target' => Yii::app()->getConfig('uploaddir') . DIRECTORY_SEPARATOR . 'surveys' . DIRECTORY_SEPARATOR . $thissurvey['sid'] . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR, 'tempdir' => Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR, 'timeadjust' => isset($timeadjust) ? $timeadjust : 0, 'token' => isset($clienttoken) ? $clienttoken : NULL);
     //Security Checked: POST, GET, SESSION, REQUEST, returnGlobal, DB
     $previewgrp = false;
     if ($surveyMode == 'group' && isset($param['action']) && $param['action'] == 'previewgroup') {
         $previewgrp = true;
     }
     $previewquestion = false;
     if ($surveyMode == 'question' && isset($param['action']) && $param['action'] == 'previewquestion') {
         $previewquestion = true;
     }
     //        if (isset($param['newtest']) && $param['newtest'] == "Y")
     //            setcookie("limesurvey_timers", "0");   //@todo fix - sometimes results in headers already sent error
     $show_empty_group = false;
     if ($previewgrp || $previewquestion) {
         $_SESSION[$LEMsessid]['prevstep'] = 2;
         $_SESSION[$LEMsessid]['maxstep'] = 0;
     } else {
         //RUN THIS IF THIS IS THE FIRST TIME , OR THE FIRST PAGE ########################################
         if (!isset($_SESSION[$LEMsessid]['step'])) {
             buildsurveysession($surveyid);
             $sTemplatePath = $_SESSION[$LEMsessid]['templatepath'];
             if ($surveyid != LimeExpressionManager::getLEMsurveyId()) {
                 LimeExpressionManager::SetDirtyFlag();
             }
             LimeExpressionManager::StartSurvey($surveyid, $surveyMode, $surveyOptions, false, $LEMdebugLevel);
             $_SESSION[$LEMsessid]['step'] = 0;
             if ($surveyMode == 'survey') {
                 LimeExpressionManager::JumpTo(1, false, false, true);
             } elseif (isset($thissurvey['showwelcome']) && $thissurvey['showwelcome'] == 'N') {
                 $moveResult = LimeExpressionManager::JumpTo(1, false, false, true);
                 $_SESSION[$LEMsessid]['step'] = 1;
             }
         } elseif ($surveyid != LimeExpressionManager::getLEMsurveyId()) {
             LimeExpressionManager::StartSurvey($surveyid, $surveyMode, $surveyOptions, false, $LEMdebugLevel);
             LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, false);
         }
         $totalquestions = $_SESSION['survey_' . $surveyid]['totalquestions'];
         if (!isset($_SESSION[$LEMsessid]['totalsteps'])) {
             $_SESSION[$LEMsessid]['totalsteps'] = 0;
         }
         if (!isset($_SESSION[$LEMsessid]['maxstep'])) {
             $_SESSION[$LEMsessid]['maxstep'] = 0;
         }
         if (isset($_SESSION[$LEMsessid]['LEMpostKey']) && isset($_POST['LEMpostKey']) && $_POST['LEMpostKey'] != $_SESSION[$LEMsessid]['LEMpostKey']) {
             // then trying to resubmit (e.g. Next, Previous, Submit) from a cached copy of the page
             // Does not try to save anything from the page to the database
             $moveResult = LimeExpressionManager::GetLastMoveResult(true);
             if (isset($_POST['thisstep']) && isset($moveResult['seq']) && $_POST['thisstep'] == $moveResult['seq']) {
                 // then pressing F5 or otherwise refreshing the current page, which is OK
                 $LEMskipReprocessing = true;
                 $move = "movenext";
                 // so will re-display the survey
             } else {
                 // trying to use browser back buttons, which may be disallowed if no 'previous' button is present
                 $LEMskipReprocessing = true;
                 $move = "movenext";
                 // so will re-display the survey
                 $invalidLastPage = true;
                 $backpopup = $clang->gT("Please use the LimeSurvey navigation buttons or index.  It appears you attempted to use the browser back button to re-submit a page.");
             }
         }
         if (isset($move) && $move == "clearcancel") {
             $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, true, false, true);
             //$backpopup=$clang->gT("Clear all need confirmation.");
         }
         if (!(isset($_POST['saveall']) || isset($_POST['saveprompt']) || isset($_GET['sid']) || $LEMskipReprocessing || isset($move) && preg_match('/^changelang_/', $move))) {
             $_SESSION[$LEMsessid]['prevstep'] = $_SESSION[$LEMsessid]['step'];
         }
         if (!isset($_SESSION[$LEMsessid]['prevstep'])) {
             $_SESSION[$LEMsessid]['prevstep'] = -1;
             // this only happens on re-load
         }
         if (isset($_SESSION[$LEMsessid]['LEMtokenResume'])) {
             LimeExpressionManager::StartSurvey($thissurvey['sid'], $surveyMode, $surveyOptions, false, $LEMdebugLevel);
             if (isset($_SESSION[$LEMsessid]['maxstep']) && $_SESSION[$LEMsessid]['maxstep'] > $_SESSION[$LEMsessid]['step']) {
                 LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['maxstep'], false, false);
             }
             $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, false);
             // if late in the survey, will re-validate contents, which may be overkill
             unset($_SESSION[$LEMsessid]['LEMtokenResume']);
         } else {
             if (!$LEMskipReprocessing) {
                 //Move current step ###########################################################################
                 if (isset($move) && $move == 'moveprev' && ($thissurvey['allowprev'] == 'Y' || $thissurvey['questionindex'] > 0)) {
                     $moveResult = LimeExpressionManager::NavigateBackwards();
                     if ($moveResult['at_start']) {
                         $_SESSION[$LEMsessid]['step'] = 0;
                         unset($moveResult);
                         // so display welcome page again
                     }
                 }
                 if (isset($move) && $move == "movenext") {
                     $moveResult = LimeExpressionManager::NavigateForwards();
                 }
                 if (isset($move) && $move == 'movesubmit') {
                     if ($surveyMode == 'survey') {
                         $moveResult = LimeExpressionManager::NavigateForwards();
                     } else {
                         // may be submitting from the navigation bar, in which case need to process all intervening questions
                         // in order to update equations and ensure there are no intervening relevant mandatory or relevant invalid questions
                         $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['totalsteps'] + 1, false);
                     }
                 }
                 if (isset($move) && $move == 'changelang') {
                     // jump to current step using new language, processing POST values
                     $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, true, true, true);
                     // do process the POST data
                 }
                 if (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 1) {
                     $move = (int) $move;
                     if ($move > 0 && ($move <= $_SESSION[$LEMsessid]['step'] || isset($_SESSION[$LEMsessid]['maxstep']) && $move <= $_SESSION[$LEMsessid]['maxstep'])) {
                         $moveResult = LimeExpressionManager::JumpTo($move, false);
                     }
                 } elseif (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 2) {
                     $move = (int) $move;
                     $moveResult = LimeExpressionManager::JumpTo($move, false, true, true);
                 }
                 if (!isset($moveResult) && !($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] == 0)) {
                     // Just in case not set via any other means, but don't do this if it is the welcome page
                     $moveResult = LimeExpressionManager::GetLastMoveResult(true);
                     $LEMskipReprocessing = true;
                 }
             }
         }
         if (isset($moveResult) && isset($moveResult['seq'])) {
             // With complete index, we need to revalidate whole group bug #08806. It's actually the only mode where we JumpTo with force
             if ($moveResult['finished'] == true && $thissurvey['questionindex'] == 2) {
                 //LimeExpressionManager::JumpTo(-1, false, false, true);
                 LimeExpressionManager::StartSurvey($surveyid, $surveyMode, $surveyOptions);
                 $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['totalsteps'] + 1, false, false, false);
                 // no preview, no save data and NO force
                 if (!$moveResult['mandViolation'] && $moveResult['valid'] && empty($moveResult['invalidSQs'])) {
                     $moveResult['finished'] = true;
                 }
             }
             if ($moveResult['finished'] == true) {
                 $move = 'movesubmit';
             } else {
                 $_SESSION[$LEMsessid]['step'] = $moveResult['seq'] + 1;
                 // step is index base 1
                 $stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']);
             }
             if ($move == "movesubmit" && $moveResult['finished'] == false) {
                 // then there are errors, so don't finalize the survey
                 $move = "movenext";
                 // so will re-display the survey
                 $invalidLastPage = true;
             }
         }
         // We do not keep the participant session anymore when the same browser is used to answer a second time a survey (let's think of a library PC for instance).
         // Previously we used to keep the session and redirect the user to the
         // submit page.
         if ($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] == 0) {
             $_SESSION[$LEMsessid]['test'] = time();
             display_first_page();
             Yii::app()->end();
             // So we can still see debug messages
         }
         // TODO FIXME
         if ($thissurvey['active'] == "Y") {
             Yii::import("application.libraries.Save");
             $cSave = new Save();
         }
         if ($thissurvey['active'] == "Y" && Yii::app()->request->getPost('saveall')) {
             $bTokenAnswerPersitance = $thissurvey['tokenanswerspersistence'] == 'Y' && isset($surveyid) && tableExists('tokens_' . $surveyid);
             // must do this here to process the POSTed values
             $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false);
             // by jumping to current step, saves data so far
             if (!isset($_SESSION[$LEMsessid]['scid']) && !$bTokenAnswerPersitance) {
                 $cSave->showsaveform();
                 // generates a form and exits, awaiting input
             } else {
                 // Intentional retest of all conditions to be true, to make sure we do have tokens and surveyid
                 // Now update lastpage to $_SESSION[$LEMsessid]['step'] in SurveyDynamic, otherwise we land on
                 // the previous page when we return.
                 $iResponseID = $_SESSION[$LEMsessid]['srid'];
                 $oResponse = SurveyDynamic::model($surveyid)->findByPk($iResponseID);
                 $oResponse->lastpage = $_SESSION[$LEMsessid]['step'];
                 $oResponse->save();
             }
         }
         if ($thissurvey['active'] == "Y" && Yii::app()->request->getParam('savesubmit')) {
             // The response from the save form
             // CREATE SAVED CONTROL RECORD USING SAVE FORM INFORMATION
             $popup = $cSave->savedcontrol();
             if (isset($errormsg) && $errormsg != "") {
                 $cSave->showsaveform();
                 // reshow the form if there is an error
             }
             $moveResult = LimeExpressionManager::GetLastMoveResult(true);
             $LEMskipReprocessing = true;
             // TODO - does this work automatically for token answer persistence? Used to be savedsilent()
         }
         //Now, we check mandatory questions if necessary
         //CHECK IF ALL CONDITIONAL MANDATORY QUESTIONS THAT APPLY HAVE BEEN ANSWERED
         global $notanswered;
         if (isset($moveResult) && !$moveResult['finished']) {
             $unansweredSQList = $moveResult['unansweredSQs'];
             if (strlen($unansweredSQList) > 0) {
                 $notanswered = explode('|', $unansweredSQList);
             } else {
                 $notanswered = array();
             }
             //CHECK INPUT
             $invalidSQList = $moveResult['invalidSQs'];
             if (strlen($invalidSQList) > 0) {
                 $notvalidated = explode('|', $invalidSQList);
             } else {
                 $notvalidated = array();
             }
         }
         // CHECK UPLOADED FILES
         // TMSW - Move this into LEM::NavigateForwards?
         $filenotvalidated = checkUploadedFileValidity($surveyid, $move);
         //SEE IF THIS GROUP SHOULD DISPLAY
         $show_empty_group = false;
         if ($_SESSION[$LEMsessid]['step'] == 0) {
             $show_empty_group = true;
         }
         $redata = compact(array_keys(get_defined_vars()));
         //SUBMIT ###############################################################################
         if (isset($move) && $move == "movesubmit") {
             //                setcookie("limesurvey_timers", "", time() - 3600); // remove the timers cookies   //@todo fix - sometimes results in headers already sent error
             if ($thissurvey['refurl'] == "Y") {
                 if (!in_array("refurl", $_SESSION[$LEMsessid]['insertarray'])) {
                     $_SESSION[$LEMsessid]['insertarray'][] = "refurl";
                 }
             }
             resetTimers();
             //Before doing the "templatereplace()" function, check the $thissurvey['url']
             //field for limereplace stuff, and do transformations!
             $thissurvey['surveyls_url'] = passthruReplace($thissurvey['surveyls_url'], $thissurvey);
             $thissurvey['surveyls_url'] = templatereplace($thissurvey['surveyls_url'], array(), $redata, 'URLReplace', false, NULL, array(), true);
             // to do INSERTANS substitutions
             //END PAGE - COMMIT CHANGES TO DATABASE
             if ($thissurvey['active'] != "Y") {
                 if ($thissurvey['assessments'] == "Y") {
                     $assessments = doAssessment($surveyid);
                 }
                 sendCacheHeaders();
                 doHeader();
                 echo templatereplace(file_get_contents($sTemplatePath . "startpage.pstpl"), array(), $redata, 'SubmitStartpageI', false, NULL, array(), true);
                 //Check for assessments
                 if ($thissurvey['assessments'] == "Y" && $assessments) {
                     echo templatereplace(file_get_contents($sTemplatePath . "assessment.pstpl"), array(), $redata, 'SubmitAssessmentI', false, NULL, array(), true);
                 }
                 // fetch all filenames from $_SESSIONS['files'] and delete them all
                 // from the /upload/tmp/ directory
                 /* echo "<pre>";print_r($_SESSION);echo "</pre>";
                    for($i = 1; isset($_SESSION[$LEMsessid]['files'][$i]); $i++)
                    {
                    unlink('upload/tmp/'.$_SESSION[$LEMsessid]['files'][$i]['filename']);
                    }
                    */
                 // can't kill session before end message, otherwise INSERTANS doesn't work.
                 $completed = templatereplace($thissurvey['surveyls_endtext'], array(), $redata, 'SubmitEndtextI', false, NULL, array(), true);
                 $completed .= "<br /><strong><font size='2' color='red'>" . $clang->gT("Did Not Save") . "</font></strong><br /><br />\n\n";
                 $completed .= $clang->gT("Your survey responses have not been recorded. This survey is not yet active.") . "<br /><br />\n";
                 if ($thissurvey['printanswers'] == 'Y') {
                     // 'Clear all' link is only relevant for survey with printanswers enabled
                     // in other cases the session is cleared at submit time
                     $completed .= "<a href='" . Yii::app()->getController()->createUrl("survey/index/sid/{$surveyid}/move/clearall") . "'>" . $clang->gT("Clear Responses") . "</a><br /><br />\n";
                 }
             } else {
                 if ($thissurvey['usecookie'] == "Y" && $tokensexist != 1) {
                     setcookie("LS_" . $surveyid . "_STATUS", "COMPLETE", time() + 31536000);
                     //Cookie will expire in 365 days
                 }
                 $content = '';
                 $content .= templatereplace(file_get_contents($sTemplatePath . "startpage.pstpl"), array(), $redata, 'SubmitStartpage', false, NULL, array(), true);
                 //Check for assessments
                 if ($thissurvey['assessments'] == "Y") {
                     $assessments = doAssessment($surveyid);
                     if ($assessments) {
                         $content .= templatereplace(file_get_contents($sTemplatePath . "assessment.pstpl"), array(), $redata, 'SubmitAssessment', false, NULL, array(), true);
                     }
                 }
                 //Update the token if needed and send a confirmation email
                 if (isset($_SESSION['survey_' . $surveyid]['token'])) {
                     submittokens();
                 }
                 //Send notifications
                 sendSubmitNotifications($surveyid);
                 $content = '';
                 $content .= templatereplace(file_get_contents($sTemplatePath . "startpage.pstpl"), array(), $redata, 'SubmitStartpage', false, NULL, array(), true);
                 //echo $thissurvey['url'];
                 //Check for assessments
                 if ($thissurvey['assessments'] == "Y") {
                     $assessments = doAssessment($surveyid);
                     if ($assessments) {
                         $content .= templatereplace(file_get_contents($sTemplatePath . "assessment.pstpl"), array(), $redata, 'SubmitAssessment', false, NULL, array(), true);
                     }
                 }
                 if (trim(str_replace(array('<p>', '</p>'), '', $thissurvey['surveyls_endtext'])) == '') {
                     $completed = "<br /><span class='success'>" . $clang->gT("Thank you!") . "</span><br /><br />\n\n" . $clang->gT("Your survey responses have been recorded.") . "<br /><br />\n";
                 } else {
                     $completed = templatereplace($thissurvey['surveyls_endtext'], array(), $redata, 'SubmitAssessment', false, NULL, array(), true);
                 }
                 // Link to Print Answer Preview  **********
                 if ($thissurvey['printanswers'] == 'Y') {
                     $url = Yii::app()->getController()->createUrl("/printanswers/view/surveyid/{$surveyid}");
                     $completed .= "<br /><br />" . "<a class='printlink' href='{$url}'  target='_blank'>" . $clang->gT("Print your answers.") . "</a><br />\n";
                 }
                 //*****************************************
                 if ($thissurvey['publicstatistics'] == 'Y' && $thissurvey['printanswers'] == 'Y') {
                     $completed .= '<br />' . $clang->gT("or");
                 }
                 // Link to Public statistics  **********
                 if ($thissurvey['publicstatistics'] == 'Y') {
                     $url = Yii::app()->getController()->createUrl("/statistics_user/action/surveyid/{$surveyid}/language/" . $_SESSION[$LEMsessid]['s_lang']);
                     $completed .= "<br /><br />" . "<a class='publicstatisticslink' href='{$url}' target='_blank'>" . $clang->gT("View the statistics for this survey.") . "</a><br />\n";
                 }
                 //*****************************************
                 $_SESSION[$LEMsessid]['finished'] = true;
                 $_SESSION[$LEMsessid]['sid'] = $surveyid;
                 sendCacheHeaders();
                 if (isset($thissurvey['autoredirect']) && $thissurvey['autoredirect'] == "Y" && $thissurvey['surveyls_url']) {
                     //Automatically redirect the page to the "url" setting for the survey
                     header("Location: {$thissurvey['surveyls_url']}");
                 }
                 doHeader();
                 echo $content;
             }
             $redata['completed'] = $completed;
             // @todo Remove direct session access.
             $event = new PluginEvent('afterSurveyComplete');
             if (isset($_SESSION[$LEMsessid]['srid'])) {
                 $event->set('responseId', $_SESSION[$LEMsessid]['srid']);
             }
             $event->set('surveyId', $surveyid);
             App()->getPluginManager()->dispatchEvent($event);
             $blocks = array();
             foreach ($event->getAllContent() as $blockData) {
                 /* @var $blockData PluginEventContent */
                 $blocks[] = CHtml::tag('div', array('id' => $blockData->getCssId(), 'class' => $blockData->getCssClass()), $blockData->getContent());
             }
             $redata['completed'] = implode("\n", $blocks) . "\n" . $redata['completed'];
             $redata['thissurvey']['surveyls_url'] = $thissurvey['surveyls_url'];
             echo templatereplace(file_get_contents($sTemplatePath . "completed.pstpl"), array('completed' => $completed), $redata, 'SubmitCompleted', false, NULL, array(), true);
             echo "\n";
             if (($LEMdebugLevel & LEM_DEBUG_TIMING) == LEM_DEBUG_TIMING) {
                 echo LimeExpressionManager::GetDebugTimingMessage();
             }
             if (($LEMdebugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY) {
                 echo "<table><tr><td align='left'><b>Group/Question Validation Results:</b>" . $moveResult['message'] . "</td></tr></table>\n";
             }
             echo templatereplace(file_get_contents($sTemplatePath . "endpage.pstpl"), array(), $redata, 'SubmitEndpage', false, NULL, array(), true);
             doFooter();
             // The session cannot be killed until the page is completely rendered
             if ($thissurvey['printanswers'] != 'Y') {
                 killSurveySession($surveyid);
             }
             exit;
         }
     }
     $redata = compact(array_keys(get_defined_vars()));
     // IF GOT THIS FAR, THEN DISPLAY THE ACTIVE GROUP OF QUESTIONSs
     //SEE IF $surveyid EXISTS ####################################################################
     if ($surveyExists < 1) {
         //SURVEY DOES NOT EXIST. POLITELY EXIT.
         echo templatereplace(file_get_contents($sTemplatePath . "startpage.pstpl"), array(), $redata);
         echo "\t<center><br />\n";
         echo "\t" . $clang->gT("Sorry. There is no matching survey.") . "<br /></center>&nbsp;\n";
         echo templatereplace(file_get_contents($sTemplatePath . "endpage.pstpl"), array(), $redata);
         doFooter();
         exit;
     }
     createFieldMap($surveyid, 'full', false, false, $_SESSION[$LEMsessid]['s_lang']);
     //GET GROUP DETAILS
     if ($surveyMode == 'group' && $previewgrp) {
         //            setcookie("limesurvey_timers", "0"); //@todo fix - sometimes results in headers already sent error
         $_gid = sanitize_int($param['gid']);
         LimeExpressionManager::StartSurvey($thissurvey['sid'], 'group', $surveyOptions, false, $LEMdebugLevel);
         $gseq = LimeExpressionManager::GetGroupSeq($_gid);
         if ($gseq == -1) {
             echo $clang->gT('Invalid group number for this survey: ') . $_gid;
             exit;
         }
         $moveResult = LimeExpressionManager::JumpTo($gseq + 1, true);
         if (is_null($moveResult)) {
             echo $clang->gT('This group contains no questions.  You must add questions to this group before you can preview it');
             exit;
         }
         if (isset($moveResult)) {
             $_SESSION[$LEMsessid]['step'] = $moveResult['seq'] + 1;
             // step is index base 1?
         }
         $stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']);
         $gid = $stepInfo['gid'];
         $groupname = $stepInfo['gname'];
         $groupdescription = $stepInfo['gtext'];
     } else {
         if ($show_empty_group || !isset($_SESSION[$LEMsessid]['grouplist'])) {
             $gid = -1;
             // Make sure the gid is unused. This will assure that the foreach (fieldarray as ia) has no effect.
             $groupname = $clang->gT("Submit your answers");
             $groupdescription = $clang->gT("There are no more questions. Please press the <Submit> button to finish this survey.");
         } else {
             if ($surveyMode != 'survey') {
                 if ($previewquestion) {
                     $_qid = sanitize_int($param['qid']);
                     LimeExpressionManager::StartSurvey($surveyid, 'question', $surveyOptions, false, $LEMdebugLevel);
                     $qSec = LimeExpressionManager::GetQuestionSeq($_qid);
                     $moveResult = LimeExpressionManager::JumpTo($qSec + 1, true, false, true);
                     $stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']);
                 } else {
                     $stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']);
                 }
                 $gid = $stepInfo['gid'];
                 $groupname = $stepInfo['gname'];
                 $groupdescription = $stepInfo['gtext'];
             }
         }
     }
     if ($previewquestion) {
         $_SESSION[$LEMsessid]['step'] = 0;
         //maybe unset it after the question has been displayed?
     }
     if ($_SESSION[$LEMsessid]['step'] > $_SESSION[$LEMsessid]['maxstep']) {
         $_SESSION[$LEMsessid]['maxstep'] = $_SESSION[$LEMsessid]['step'];
     }
     // If the survey uses answer persistence and a srid is registered in SESSION
     // then loadanswers from this srid
     /* Only survey mode used this - should all?
        if ($thissurvey['tokenanswerspersistence'] == 'Y' &&
        $thissurvey['anonymized'] == "N" &&
        isset($_SESSION[$LEMsessid]['srid']) &&
        $thissurvey['active'] == "Y")
        {
        loadanswers();
        }
        */
     //******************************************************************************************************
     //PRESENT SURVEY
     //******************************************************************************************************
     $okToShowErrors = !$previewgrp && (isset($invalidLastPage) || $_SESSION[$LEMsessid]['prevstep'] == $_SESSION[$LEMsessid]['step']);
     Yii::app()->getController()->loadHelper('qanda');
     setNoAnswerMode($thissurvey);
     //Iterate through the questions about to be displayed:
     $inputnames = array();
     foreach ($_SESSION[$LEMsessid]['grouplist'] as $gl) {
         $gid = $gl['gid'];
         $qnumber = 0;
         if ($surveyMode != 'survey') {
             $onlyThisGID = $stepInfo['gid'];
             if ($onlyThisGID != $gid) {
                 continue;
             }
         }
         // TMSW - could iterate through LEM::currentQset instead
         foreach ($_SESSION[$LEMsessid]['fieldarray'] as $key => $ia) {
             ++$qnumber;
             $ia[9] = $qnumber;
             // incremental question count;
             if (isset($ia[10]) && $ia[10] == $gid || !isset($ia[10]) && $ia[5] == $gid) {
                 if ($surveyMode == 'question' && $ia[0] != $stepInfo['qid']) {
                     continue;
                 }
                 $qidattributes = getQuestionAttributeValues($ia[0], $ia[4]);
                 if ($ia[4] != '*' && ($qidattributes === false || !isset($qidattributes['hidden']) || $qidattributes['hidden'] == 1)) {
                     continue;
                 }
                 //Get the answers/inputnames
                 // TMSW - can content of retrieveAnswers() be provided by LEM?  Review scope of what it provides.
                 // TODO - retrieveAnswers is slow - queries database separately for each question. May be fixed in _CI or _YII ports, so ignore for now
                 list($plus_qanda, $plus_inputnames) = retrieveAnswers($ia, $surveyid);
                 if ($plus_qanda) {
                     $plus_qanda[] = $ia[4];
                     $plus_qanda[] = $ia[6];
                     // adds madatory identifyer for adding mandatory class to question wrapping div
                     // Add a finalgroup in qa array , needed for random attribute : TODO: find a way to have it in new quanda_helper in 2.1
                     if (isset($ia[10])) {
                         $plus_qanda['finalgroup'] = $ia[10];
                     } else {
                         $plus_qanda['finalgroup'] = $ia[5];
                     }
                     $qanda[] = $plus_qanda;
                 }
                 if ($plus_inputnames) {
                     $inputnames = addtoarray_single($inputnames, $plus_inputnames);
                 }
                 //Display the "mandatory" popup if necessary
                 // TMSW - get question-level error messages - don't call **_popup() directly
                 if ($okToShowErrors && $stepInfo['mandViolation']) {
                     list($mandatorypopup, $popup) = mandatory_popup($ia, $notanswered);
                 }
                 //Display the "validation" popup if necessary
                 if ($okToShowErrors && !$stepInfo['valid']) {
                     list($validationpopup, $vpopup) = validation_popup($ia, $notvalidated);
                 }
                 // Display the "file validation" popup if necessary
                 if ($okToShowErrors && isset($filenotvalidated)) {
                     list($filevalidationpopup, $fpopup) = file_validation_popup($ia, $filenotvalidated);
                 }
             }
             if ($ia[4] == "|") {
                 $upload_file = TRUE;
             }
         }
         //end iteration
     }
     if ($surveyMode != 'survey' && isset($thissurvey['showprogress']) && $thissurvey['showprogress'] == 'Y') {
         if ($show_empty_group) {
             $percentcomplete = makegraph($_SESSION[$LEMsessid]['totalsteps'] + 1, $_SESSION[$LEMsessid]['totalsteps']);
         } else {
             $percentcomplete = makegraph($_SESSION[$LEMsessid]['step'], $_SESSION[$LEMsessid]['totalsteps']);
         }
     }
     if (!(isset($languagechanger) && strlen($languagechanger) > 0) && function_exists('makeLanguageChangerSurvey')) {
         $languagechanger = makeLanguageChangerSurvey($_SESSION[$LEMsessid]['s_lang']);
     }
     //READ TEMPLATES, INSERT DATA AND PRESENT PAGE
     sendCacheHeaders();
     doHeader();
     $redata = compact(array_keys(get_defined_vars()));
     echo templatereplace(file_get_contents($sTemplatePath . "startpage.pstpl"), array(), $redata);
     $aPopup = array();
     // We can move this part where we want now
     if (isset($backpopup)) {
         $aPopup[] = $backpopup;
         // If user click reload: no need other popup
     } else {
         if (isset($popup)) {
             $aPopup[] = $popup;
         }
         if (isset($vpopup)) {
             $aPopup[] = $vpopup;
         }
         if (isset($fpopup)) {
             $aPopup[] = $fpopup;
         }
     }
     Yii::app()->clientScript->registerScript("showpopup", "showpopup=" . (int) Yii::app()->getConfig('showpopups') . ";", CClientScript::POS_HEAD);
     //if(count($aPopup))
     Yii::app()->clientScript->registerScript('startPopup', "startPopups=" . json_encode($aPopup) . ";", CClientScript::POS_HEAD);
     //ALTER PAGE CLASS TO PROVIDE WHOLE-PAGE ALTERNATION
     if ($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] != $_SESSION[$LEMsessid]['prevstep'] || isset($_SESSION[$LEMsessid]['stepno']) && $_SESSION[$LEMsessid]['stepno'] % 2) {
         if (!isset($_SESSION[$LEMsessid]['stepno'])) {
             $_SESSION[$LEMsessid]['stepno'] = 0;
         }
         if ($_SESSION[$LEMsessid]['step'] != $_SESSION[$LEMsessid]['prevstep']) {
             ++$_SESSION[$LEMsessid]['stepno'];
         }
         if ($_SESSION[$LEMsessid]['stepno'] % 2) {
             echo "<script type=\"text/javascript\">\n" . "  \$(\"body\").addClass(\"page-odd\");\n" . "</script>\n";
         }
     }
     $hiddenfieldnames = implode("|", $inputnames);
     if (isset($upload_file) && $upload_file) {
         echo CHtml::form(array("survey/index"), 'post', array('enctype' => 'multipart/form-data', 'id' => 'limesurvey', 'name' => 'limesurvey', 'autocomplete' => 'off')) . "\n\n            <!-- INPUT NAMES -->\n            <input type='hidden' name='fieldnames' value='{$hiddenfieldnames}' id='fieldnames' />\n";
     } else {
         echo CHtml::form(array("survey/index"), 'post', array('id' => 'limesurvey', 'name' => 'limesurvey', 'autocomplete' => 'off')) . "\n\n            <!-- INPUT NAMES -->\n            <input type='hidden' name='fieldnames' value='{$hiddenfieldnames}' id='fieldnames' />\n";
     }
     // <-- END FEATURE - SAVE
     // The default submit button
     echo CHtml::htmlButton("default", array('type' => 'submit', 'id' => "defaultbtn", 'value' => "default", 'name' => 'move', 'class' => "submit noview", 'style' => 'display:none'));
     if ($surveyMode == 'survey') {
         if (isset($thissurvey['showwelcome']) && $thissurvey['showwelcome'] == 'N') {
             //Hide the welcome screen if explicitly set
         } else {
             echo templatereplace(file_get_contents($sTemplatePath . "welcome.pstpl"), array(), $redata) . "\n";
         }
         if ($thissurvey['anonymized'] == "Y") {
             echo templatereplace(file_get_contents($sTemplatePath . "privacy.pstpl"), array(), $redata) . "\n";
         }
     }
     // <-- START THE SURVEY -->
     if ($surveyMode != 'survey') {
         echo templatereplace(file_get_contents($sTemplatePath . "survey.pstpl"), array(), $redata);
     }
     // runonce element has been changed from a hidden to a text/display:none one. In order to workaround an not-reproduced issue #4453 (lemeur)
     // We don't need runonce actually (140228): the script was updated and replaced by EM see #08783 (grep show no other runonce)
     // echo "<input type='text' id='runonce' value='0' style='display: none;'/>";
     $showpopups = Yii::app()->getConfig('showpopups');
     //Display the "mandatory" message on page if necessary
     if (!$showpopups && $stepInfo['mandViolation'] && $okToShowErrors) {
         echo "<p class='errormandatory'>" . $clang->gT("One or more mandatory questions have not been answered. You cannot proceed until these have been completed.") . "</p>";
     }
     //Display the "validation" message on page if necessary
     if (!$showpopups && !$stepInfo['valid'] && $okToShowErrors) {
         echo "<p class='errormandatory'>" . $clang->gT("One or more questions have not been answered in a valid manner. You cannot proceed until these answers are valid.") . "</p>";
     }
     //Display the "file validation" message on page if necessary
     if (!$showpopups && isset($filenotvalidated) && $filenotvalidated == true && $okToShowErrors) {
         echo "<p class='errormandatory'>" . $clang->gT("One or more uploaded files are not in proper format/size. You cannot proceed until these files are valid.") . "</p>";
     }
     $_gseq = -1;
     foreach ($_SESSION[$LEMsessid]['grouplist'] as $gl) {
         $gid = $gl['gid'];
         ++$_gseq;
         $groupname = $gl['group_name'];
         $groupdescription = $gl['description'];
         if ($surveyMode != 'survey' && $gid != $onlyThisGID) {
             continue;
         }
         $redata = compact(array_keys(get_defined_vars()));
         Yii::app()->setConfig('gid', $gid);
         // To be used in templaterplace in whole group. Attention : it's the actual GID (not the GID of the question)
         echo "\n\n<!-- START THE GROUP -->\n";
         echo "\n\n<div id='group-{$_gseq}'";
         $gnoshow = LimeExpressionManager::GroupIsIrrelevantOrHidden($_gseq);
         if ($gnoshow && !$previewgrp) {
             echo " style='display: none;'";
         }
         echo ">\n";
         echo templatereplace(file_get_contents($sTemplatePath . "startgroup.pstpl"), array(), $redata);
         echo "\n";
         if (!$previewquestion) {
             echo templatereplace(file_get_contents($sTemplatePath . "groupdescription.pstpl"), array(), $redata);
         }
         echo "\n";
         echo "\n\n<!-- PRESENT THE QUESTIONS -->\n";
         foreach ($qanda as $qa) {
             // Test if finalgroup is in this qid (for all in one survey, else we do only qanda for needed question (in one by one or group by goup)
             if ($gid != $qa['finalgroup']) {
                 continue;
             }
             $qid = $qa[4];
             $qinfo = LimeExpressionManager::GetQuestionStatus($qid);
             $lastgrouparray = explode("X", $qa[7]);
             $lastgroup = $lastgrouparray[0] . "X" . $lastgrouparray[1];
             // id of the last group, derived from question id
             $lastanswer = $qa[7];
             $q_class = getQuestionClass($qinfo['info']['type']);
             $man_class = '';
             if ($qinfo['info']['mandatory'] == 'Y') {
                 $man_class .= ' mandatory';
             }
             if ($qinfo['anyUnanswered'] && $_SESSION[$LEMsessid]['maxstep'] != $_SESSION[$LEMsessid]['step']) {
                 $man_class .= ' missing';
             }
             $n_q_display = '';
             if ($qinfo['hidden'] && $qinfo['info']['type'] != '*') {
                 continue;
                 // skip this one
             }
             if (!$qinfo['relevant'] || $qinfo['hidden'] && $qinfo['info']['type'] == '*') {
                 $n_q_display = ' style="display: none;"';
             }
             $question = $qa[0];
             //===================================================================
             // The following four variables offer the templating system the
             // capacity to fully control the HTML output for questions making the
             // above echo redundant if desired.
             $question['essentials'] = 'id="question' . $qa[4] . '"' . $n_q_display;
             $question['class'] = $q_class;
             $question['man_class'] = $man_class;
             $question['code'] = $qa[5];
             $question['sgq'] = $qa[7];
             $question['aid'] = !empty($qinfo['info']['aid']) ? $qinfo['info']['aid'] : 0;
             $question['sqid'] = !empty($qinfo['info']['sqid']) ? $qinfo['info']['sqid'] : 0;
             $question['type'] = $qinfo['info']['type'];
             //===================================================================
             $answer = $qa[1];
             $help = $qinfo['info']['help'];
             // $qa[2];
             $redata = compact(array_keys(get_defined_vars()));
             $question_template = file_get_contents($sTemplatePath . 'question.pstpl');
             if (preg_match('/\\{QUESTION_ESSENTIALS\\}/', $question_template) === false || preg_match('/\\{QUESTION_CLASS\\}/', $question_template) === false) {
                 // if {QUESTION_ESSENTIALS} is present in the template but not {QUESTION_CLASS} remove it because you don't want id="" and display="" duplicated.
                 $question_template = str_replace('{QUESTION_ESSENTIALS}', '', $question_template);
                 $question_template = str_replace('{QUESTION_CLASS}', '', $question_template);
                 echo '
                 <!-- NEW QUESTION -->
                 <div id="question' . $qa[4] . '" class="' . $q_class . $man_class . '"' . $n_q_display . '>';
                 echo templatereplace($question_template, array(), $redata, false, false, $qa[4]);
                 echo '</div>';
             } else {
                 // TMSW - eventually refactor so that only substitutes the QUESTION_** fields - doesn't need full power of template replace
                 // TMSW - also, want to return a string, and call templatereplace once on that result string once all done.
                 echo templatereplace($question_template, array(), $redata, false, false, $qa[4]);
             }
         }
         if ($surveyMode == 'group') {
             echo "<input type='hidden' name='lastgroup' value='{$lastgroup}' id='lastgroup' />\n";
             // for counting the time spent on each group
         }
         if ($surveyMode == 'question') {
             echo "<input type='hidden' name='lastanswer' value='{$lastanswer}' id='lastanswer' />\n";
         }
         echo "\n\n<!-- END THE GROUP -->\n";
         echo templatereplace(file_get_contents($sTemplatePath . "endgroup.pstpl"), array(), $redata);
         echo "\n\n</div>\n";
         Yii::app()->setConfig('gid', '');
     }
     LimeExpressionManager::FinishProcessingGroup($LEMskipReprocessing);
     echo LimeExpressionManager::GetRelevanceAndTailoringJavaScript();
     LimeExpressionManager::FinishProcessingPage();
     if (!$previewgrp && !$previewquestion) {
         $navigator = surveymover();
         //This gets globalised in the templatereplace function
         $redata = compact(array_keys(get_defined_vars()));
         echo "\n\n<!-- PRESENT THE NAVIGATOR -->\n";
         echo templatereplace(file_get_contents($sTemplatePath . "navigator.pstpl"), array(), $redata);
         echo "\n";
         if ($thissurvey['active'] != "Y") {
             echo "<p style='text-align:center' class='error'>" . $clang->gT("This survey is currently not active. You will not be able to save your responses.") . "</p>\n";
         }
         if ($surveyMode != 'survey' && $thissurvey['questionindex'] == 1) {
             $this->createIncrementalQuestionIndex($LEMsessid, $surveyMode);
         } elseif ($surveyMode != 'survey' && $thissurvey['questionindex'] == 2) {
             $this->createFullQuestionIndex($LEMsessid, $surveyMode);
         }
         echo "<input type='hidden' name='thisstep' value='{$_SESSION[$LEMsessid]['step']}' id='thisstep' />\n";
         echo "<input type='hidden' name='sid' value='{$surveyid}' id='sid' />\n";
         echo "<input type='hidden' name='start_time' value='" . time() . "' id='start_time' />\n";
         $_SESSION[$LEMsessid]['LEMpostKey'] = mt_rand();
         echo "<input type='hidden' name='LEMpostKey' value='{$_SESSION[$LEMsessid]['LEMpostKey']}' id='LEMpostKey' />\n";
         if (isset($token) && !empty($token)) {
             echo "\n<input type='hidden' name='token' value='{$token}' id='token' />\n";
         }
     }
     if (($LEMdebugLevel & LEM_DEBUG_TIMING) == LEM_DEBUG_TIMING) {
         echo LimeExpressionManager::GetDebugTimingMessage();
     }
     if (($LEMdebugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY) {
         echo "<table><tr><td align='left'><b>Group/Question Validation Results:</b>" . $moveResult['message'] . "</td></tr></table>\n";
     }
     echo "</form>\n";
     echo templatereplace(file_get_contents($sTemplatePath . "endpage.pstpl"), array(), $redata);
     echo "\n";
     doFooter();
 }
/**
* checkCompletedQuota() returns matched quotas information for the current response
* @param integer $surveyid - Survey identification number
* @param bool $return - set to true to return information, false do the quota
* @return array - nested array, Quotas->Members->Fields, includes quota information matched in session.
*/
function checkCompletedQuota($surveyid, $return = false)
{
    if (!isset($_SESSION['survey_' . $surveyid]['srid'])) {
        return;
    }
    static $aMatchedQuotas;
    // EM call 2 times quotas with 3 lines of php code, then use static.
    if (!$aMatchedQuotas) {
        $aMatchedQuotas = array();
        $quota_info = $aQuotasInfo = getQuotaInformation($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']);
        // $aQuotasInfo have an 'active' key, we don't use it ?
        if (!$aQuotasInfo || empty($aQuotasInfo)) {
            return $aMatchedQuotas;
        }
        // Test only completed quota, other is not needed
        $aQuotasCompleted = array();
        foreach ($aQuotasInfo as $aQuotaInfo) {
            $iCompleted = getQuotaCompletedCount($surveyid, $aQuotaInfo['id']);
            // Return a string
            if (ctype_digit($iCompleted) && (int) $iCompleted >= (int) $aQuotaInfo['qlimit']) {
                // This remove invalid quota and not completed
                $aQuotasCompleted[] = $aQuotaInfo;
            }
        }
        if (empty($aQuotasCompleted)) {
            return $aMatchedQuotas;
        }
        // OK, we have some quota, then find if this $_SESSION have some set
        $aPostedFields = explode("|", Yii::app()->request->getPost('fieldnames', ''));
        // Needed for quota allowing update
        foreach ($aQuotasCompleted as $aQuotaCompleted) {
            $iMatchedAnswers = 0;
            $bPostedField = false;
            // Array of field with quota array value
            $aQuotaFields = array();
            // Array of fieldnames with relevance value : EM fill $_SESSION with default value even is unrelevant (em_manager_helper line 6548)
            $aQuotaRelevantFieldnames = array();
            foreach ($aQuotaCompleted['members'] as $aQuotaMember) {
                $aQuotaFields[$aQuotaMember['fieldname']][] = $aQuotaMember['value'];
                $aQuotaRelevantFieldnames[$aQuotaMember['fieldname']] = isset($_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']]) && $_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']];
            }
            // For each field : test if actual responses is in quota (and is relevant)
            foreach ($aQuotaFields as $sFieldName => $aValues) {
                $bInQuota = isset($_SESSION['survey_' . $surveyid][$sFieldName]) && in_array($_SESSION['survey_' . $surveyid][$sFieldName], $aValues);
                if ($bInQuota && $aQuotaRelevantFieldnames[$sFieldName]) {
                    $iMatchedAnswers++;
                }
                if (in_array($sFieldName, $aPostedFields)) {
                    $bPostedField = true;
                }
            }
            if ($iMatchedAnswers == count($aQuotaFields)) {
                switch ($aQuotaCompleted['action']) {
                    case '1':
                    default:
                        $aMatchedQuotas[] = $aQuotaCompleted;
                        break;
                    case '2':
                        if ($bPostedField) {
                            // Action 2 allow to correct last answers, then need to be posted
                            $aMatchedQuotas[] = $aQuotaCompleted;
                        }
                        break;
                }
            }
        }
    }
    if ($return) {
        return $aMatchedQuotas;
    }
    if (empty($aMatchedQuotas)) {
        return;
    }
    // Now we have all the information we need about the quotas and their status.
    // We need to construct the page and do all needed action
    $aSurveyInfo = getSurveyInfo($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']);
    $sTemplatePath = getTemplatePath($aSurveyInfo['templatedir']);
    $sClientToken = isset($_SESSION['survey_' . $surveyid]['token']) ? $_SESSION['survey_' . $surveyid]['token'] : "";
    // {TOKEN} is take by $redata ...
    // $redata for templatereplace
    $aDataReplacement = array('thissurvey' => $aSurveyInfo, 'clienttoken' => $sClientToken, 'token' => $sClientToken);
    // We take only the first matched quota, no need for each
    $aMatchedQuota = $aMatchedQuotas[0];
    // If a token is used then mark the token as completed, do it before event : this allow plugin to update token information
    $event = new PluginEvent('afterSurveyQuota');
    $event->set('surveyId', $surveyid);
    $event->set('responseId', $_SESSION['survey_' . $surveyid]['srid']);
    // We allways have a responseId
    $event->set('aMatchedQuotas', $aMatchedQuotas);
    // Give all the matched quota : the first is the active
    App()->getPluginManager()->dispatchEvent($event);
    $blocks = array();
    foreach ($event->getAllContent() as $blockData) {
        /* @var $blockData PluginEventContent */
        $blocks[] = CHtml::tag('div', array('id' => $blockData->getCssId(), 'class' => $blockData->getCssClass()), $blockData->getContent());
    }
    // Allow plugin to update message, url, url description and action
    $sMessage = $event->get('message', $aMatchedQuota['quotals_message']);
    $sUrl = $event->get('url', $aMatchedQuota['quotals_url']);
    $sUrlDescription = $event->get('urldescrip', $aMatchedQuota['quotals_urldescrip']);
    $sAction = $event->get('action', $aMatchedQuota['action']);
    $sAutoloadUrl = $event->get('autoloadurl', $aMatchedQuota['autoload_url']);
    // Construct the default message
    $sMessage = templatereplace($sMessage, array(), $aDataReplacement, 'QuotaMessage', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true);
    $sUrl = passthruReplace($sUrl, $aSurveyInfo);
    $sUrl = templatereplace($sUrl, array(), $aDataReplacement, 'QuotaUrl', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true);
    $sUrlDescription = templatereplace($sUrlDescription, array(), $aDataReplacement, 'QuotaUrldescription', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true);
    // Doing the action and show the page
    if ($sAction == "1" && $sClientToken) {
        submittokens(true);
    }
    // Construction of default message inside quotamessage class
    $quotaMessage = "<div class='quotamessage limesurveycore'>\n";
    $quotaMessage .= "\t" . $sMessage . "\n";
    if ($sUrl) {
        $quotaMessage .= "<br /><br />\t<a href='" . $sUrl . "'>" . $sUrlDescription . "</a><br />\n";
    }
    // Add the navigator with Previous button if quota allow modification.
    if ($sAction == "2") {
        $sQuotaStep = isset($_SESSION['survey_' . $surveyid]['step']) ? $_SESSION['survey_' . $surveyid]['step'] : 0;
        // Surely not needed
        $sNavigator = CHtml::htmlButton(gT("Previous"), array('type' => 'submit', 'id' => "moveprevbtn", 'value' => $sQuotaStep, 'name' => 'move', 'accesskey' => 'p', 'class' => "submit button"));
        $quotaMessage .= CHtml::form(array("/survey/index"), 'post', array('id' => 'limesurvey', 'name' => 'limesurvey'));
        $quotaMessage .= templatereplace(file_get_contents($sTemplatePath . "/navigator.pstpl"), array('NAVIGATOR' => $sNavigator, 'SAVE' => ''), $aDataReplacement);
        $quotaMessage .= CHtml::hiddenField('sid', $surveyid);
        $quotaMessage .= CHtml::hiddenField('token', $sClientToken);
        // Did we really need it ?
        $quotaMessage .= CHtml::endForm();
    }
    $quotaMessage .= "</div>\n";
    // Add the plugin message before default message
    $quotaMessage = implode("\n", $blocks) . "\n" . $quotaMessage;
    // Send page to user and end.
    sendCacheHeaders();
    if ($sAutoloadUrl == 1 && $sUrl != "") {
        if ($sAction == "1") {
            killSurveySession($surveyid);
        }
        header("Location: " . $sUrl);
    }
    doHeader();
    echo templatereplace(file_get_contents($sTemplatePath . "/startpage.pstpl"), array(), $aDataReplacement);
    echo $quotaMessage;
    echo templatereplace(file_get_contents($sTemplatePath . "/endpage.pstpl"), array(), $aDataReplacement);
    doFooter();
    if ($sAction == "1") {
        killSurveySession($surveyid);
    }
    Yii::app()->end();
}
Exemplo n.º 24
0
 public function exportresults()
 {
     $iSurveyID = sanitize_int(Yii::app()->request->getParam('surveyid'));
     if (!isset($imageurl)) {
         $imageurl = "./images";
     }
     if (!isset($iSurveyID)) {
         $iSurveyID = returnGlobal('sid');
     }
     if (!isset($convertyto1)) {
         $convertyto1 = returnGlobal('convertyto1');
     }
     if (!isset($convertnto2)) {
         $convertnto2 = returnGlobal('convertnto2');
     }
     if (!isset($convertyto)) {
         $convertyto = returnGlobal('convertyto');
     }
     if (!isset($convertnto)) {
         $convertnto = returnGlobal('convertnto');
     }
     if (!Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'export')) {
         $this->getController()->error('Access denied!');
     }
     Yii::app()->loadHelper("admin/exportresults");
     App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts') . "expressions/em_javascript.js");
     App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . '/exportresults.js');
     $sExportType = Yii::app()->request->getPost('type');
     $sHeadingFormat = Yii::app()->request->getPost('headstyle');
     $sAnswerFormat = Yii::app()->request->getPost('answers');
     $bHeaderSpacesToUnderscores = Yii::app()->request->getPost('headspacetounderscores');
     $bConvertY = Yii::app()->request->getPost('converty');
     $bConvertN = Yii::app()->request->getPost('convertn');
     $sYValue = Yii::app()->request->getPost('convertyto');
     $sNValue = Yii::app()->request->getPost('convertnto');
     $surveybaselang = Survey::model()->findByPk($iSurveyID)->language;
     $exportoutput = "";
     // Get info about the survey
     $thissurvey = getSurveyInfo($iSurveyID);
     // Load ExportSurveyResultsService so we know what exports are available
     $resultsService = new ExportSurveyResultsService();
     $exports = $resultsService->getExports();
     if (!$sExportType) {
         //FIND OUT HOW MANY FIELDS WILL BE NEEDED - FOR 255 COLUMN LIMIT
         $aFieldMap = createFieldMap($iSurveyID, 'full', false, false, getBaseLanguageFromSurveyID($iSurveyID));
         if ($thissurvey['savetimings'] === "Y") {
             //Append survey timings to the fieldmap array
             $aFieldMap = $aFieldMap + createTimingsFieldMap($iSurveyID, 'full', false, false, getBaseLanguageFromSurveyID($iSurveyID));
         }
         $iFieldCount = count($aFieldMap);
         $selecthide = "";
         $selectshow = "";
         $selectinc = "";
         if (incompleteAnsFilterState() == "complete") {
             $selecthide = "selected='selected'";
         } elseif (incompleteAnsFilterState() == "incomplete") {
             $selectinc = "selected='selected'";
         } else {
             $selectshow = "selected='selected'";
         }
         $aFields = array();
         foreach ($aFieldMap as $sFieldName => $fieldinfo) {
             $sCode = viewHelper::getFieldCode($fieldinfo);
             $aFields[$sFieldName] = $sCode . ' - ' . htmlspecialchars(ellipsize(html_entity_decode(viewHelper::getFieldText($fieldinfo)), 30, 0.6, '...'));
             $aFieldsOptions[$sFieldName] = array('title' => viewHelper::getFieldText($fieldinfo), 'data-fieldname' => $fieldinfo['fieldname'], 'data-emcode' => viewHelper::getFieldCode($fieldinfo, array('LEMcompat' => true)));
             // No need to filter title : Yii do it (remove all tag)
         }
         $data['SingleResponse'] = (int) returnGlobal('id');
         $data['selecthide'] = $selecthide;
         $data['selectshow'] = $selectshow;
         $data['selectinc'] = $selectinc;
         $data['afieldcount'] = $iFieldCount;
         $data['aFields'] = $aFields;
         $data['aFieldsOptions'] = $aFieldsOptions;
         //get max number of datasets
         $iMaximum = SurveyDynamic::model($iSurveyID)->getMaxId();
         $data['max_datasets'] = $iMaximum;
         $data['surveyid'] = $iSurveyID;
         $data['imageurl'] = Yii::app()->getConfig('imageurl');
         $data['thissurvey'] = $thissurvey;
         $data['display']['menu_bars']['browse'] = gT("Export results");
         // Export plugins, leave out all entries that are not plugin
         $exports = array_filter($exports);
         $exportData = array();
         foreach ($exports as $key => $plugin) {
             $event = new PluginEvent('listExportOptions');
             $event->set('type', $key);
             $oPluginManager = App()->getPluginManager();
             $oPluginManager->dispatchEvent($event, $plugin);
             $exportData[$key] = array('onclick' => $event->get('onclick'), 'label' => $event->get('label'), 'checked' => $event->get('default', false), 'tooltip' => $event->get('tooltip', null));
         }
         $data['exports'] = $exportData;
         // Pass available exports
         $data['headexports'] = array('code' => array('label' => gT("Question code"), 'help' => null, 'checked' => false), 'abbreviated' => array('label' => gT("Abbreviated question text"), 'help' => null, 'checked' => false), 'full' => array('label' => gT("Full question text"), 'help' => null, 'checked' => true), 'codetext' => array('label' => gT("Question code and question text"), 'help' => null, 'checked' => false));
         // Add a plugin for adding headexports : a public function getRegistereddPlugins($event) can help here.
         $aLanguagesCode = Survey::model()->findByPk($iSurveyID)->getAllLanguages();
         $aLanguages = array();
         foreach ($aLanguagesCode as $sLanguage) {
             $aLanguages[$sLanguage] = getLanguageNameFromCode($sLanguage, false);
         }
         $data['aLanguages'] = $aLanguages;
         // Pass available exports
         $this->_renderWrappedTemplate('export', 'exportresults_view', $data);
         return;
     }
     // Export Language is set by default to surveybaselang
     // * the explang language code is used in SQL queries
     // * the alang object is used to translate headers and hardcoded answers
     // In the future it might be possible to 'post' the 'export language' from
     // the exportresults form
     $explang = Yii::app()->request->getPost('exportlang', $surveybaselang);
     //Get together our FormattingOptions and then call into the exportSurvey
     //function.
     $options = new FormattingOptions();
     $options->selectedColumns = Yii::app()->request->getPost('colselect');
     $options->responseMinRecord = sanitize_int(Yii::app()->request->getPost('export_from'));
     $options->responseMaxRecord = sanitize_int(Yii::app()->request->getPost('export_to'));
     $options->answerFormat = $sAnswerFormat;
     $options->convertY = $bConvertY;
     $options->yValue = $bConvertY ? $sYValue : null;
     $options->convertN = $bConvertN;
     $options->nValue = $bConvertN ? $sNValue : null;
     $options->headingTextLength = Yii::app()->request->getPost('abbreviatedtext') ? (int) Yii::app()->request->getPost('abbreviatedtextto') : null;
     $options->useEMCode = Yii::app()->request->getPost('emcode');
     $options->headCodeTextSeparator = Yii::app()->request->getPost('codetextseparator');
     $options->headerSpacesToUnderscores = $bHeaderSpacesToUnderscores;
     $options->headingFormat = $sHeadingFormat;
     $options->responseCompletionState = incompleteAnsFilterState();
     $options->output = 'display';
     // Replace token information by the column name
     if (in_array('first_name', Yii::app()->request->getPost('attribute_select', array()))) {
         $options->selectedColumns[] = "firstname";
     }
     if (in_array('last_name', Yii::app()->request->getPost('attribute_select', array()))) {
         $options->selectedColumns[] = "lastname";
     }
     if (in_array('email_address', Yii::app()->request->getPost('attribute_select', array()))) {
         $options->selectedColumns[] = "email";
     }
     $attributeFields = array_keys(getTokenFieldsAndNames($iSurveyID, TRUE));
     foreach ($attributeFields as $attr_name) {
         if (in_array($attr_name, Yii::app()->request->getPost('attribute_select', array()))) {
             $options->selectedColumns[] = $attr_name;
         }
     }
     if (Yii::app()->request->getPost('response_id')) {
         $sFilter = "{{survey_{$iSurveyID}}}.id=" . (int) Yii::app()->request->getPost('response_id');
     } else {
         $sFilter = '';
     }
     viewHelper::disableHtmlLogging();
     $resultsService->exportSurvey($iSurveyID, $explang, $sExportType, $options, $sFilter);
     exit;
 }
Exemplo n.º 25
0
 /**
  * Show login screen and parse login data
  */
 public function index()
 {
     $this->_redirectIfLoggedIn();
     $aData = array();
     // Make sure after first run / update the authdb plugin is registered and active
     // it can not be deactivated
     if (!class_exists('Authdb', false)) {
         $plugin = Plugin::model()->findByAttributes(array('name' => 'Authdb'));
         if (!$plugin) {
             $plugin = new Plugin();
             $plugin->name = 'Authdb';
             $plugin->active = 1;
             $plugin->save();
             App()->getPluginManager()->loadPlugin('Authdb', $plugin->id);
         } else {
             $plugin->active = 1;
             $plugin->save();
         }
     }
     $beforeLogin = new PluginEvent('beforeLogin');
     $beforeLogin->set('identity', new LSUserIdentity('', ''));
     App()->getPluginManager()->dispatchEvent($beforeLogin);
     /* @var $identity LSUserIdentity */
     $identity = $beforeLogin->get('identity');
     if (!$beforeLogin->isStopped() && is_null(App()->getRequest()->getPost('login_submit'))) {
         if (!is_null($beforeLogin->get('default'))) {
             $aData['defaultAuth'] = $beforeLogin->get('default');
         } else {
             if (App()->getPluginManager()->isPluginActive(Yii::app()->getConfig('default_displayed_auth_method'))) {
                 $aData['defaultAuth'] = Yii::app()->getConfig('default_displayed_auth_method');
             } else {
                 $aData['defaultAuth'] = 'Authdb';
             }
         }
         $newLoginForm = new PluginEvent('newLoginForm');
         App()->getPluginManager()->dispatchEvent($newLoginForm);
         $aData['summary'] = $this->_getSummary('logout');
         $aData['pluginContent'] = $newLoginForm->getAllContent();
     } else {
         // Handle getting the post and populating the identity there
         $authMethod = App()->getRequest()->getPost('authMethod', $identity->plugin);
         $identity->plugin = $authMethod;
         $event = new PluginEvent('afterLoginFormSubmit');
         $event->set('identity', $identity);
         App()->getPluginManager()->dispatchEvent($event, array($authMethod));
         $identity = $event->get('identity');
         // Now authenticate
         if ($identity->authenticate()) {
             FailedLoginAttempt::model()->deleteAttempts();
             App()->user->setState('plugin', $authMethod);
             $this->getController()->_GetSessionUserRights(Yii::app()->session['loginID']);
             Yii::app()->session['just_logged_in'] = true;
             Yii::app()->session['loginsummary'] = $this->_getSummary();
             $event = new PluginEvent('afterSuccessfulLogin');
             App()->getPluginManager()->dispatchEvent($event);
             $this->_doRedirect();
         } else {
             // Failed
             $event = new PluginEvent('afterFailedLoginAttempt');
             $event->set('identity', $identity);
             App()->getPluginManager()->dispatchEvent($event);
             $message = $identity->errorMessage;
             if (empty($message)) {
                 // If no message, return a default message
                 $message = gT('Incorrect username and/or password!');
             }
             App()->user->setFlash('loginError', $message);
             $this->getController()->redirect(array('/admin/authentication/sa/login'));
         }
     }
     // If for any reason, the plugin bugs, we can't let the user with a blank screen.
     $this->_renderWrappedTemplate('authentication', 'login', $aData);
 }
Exemplo n.º 26
0
 /**
  * survey::_generalTabEditSurvey()
  * Load "General" tab of edit survey screen.
  * @param mixed $iSurveyID
  * @param mixed $esrow
  * @return
  */
 private function _generalTabEditSurvey($iSurveyID, $esrow)
 {
     $clang = $this->getController()->lang;
     $aData['action'] = "editsurveysettings";
     $aData['clang'] = $clang;
     $aData['esrow'] = $esrow;
     $aData['surveyid'] = $iSurveyID;
     $beforeSurveySettings = new PluginEvent('beforeSurveySettings');
     $beforeSurveySettings->set('survey', $iSurveyID);
     App()->getPluginManager()->dispatchEvent($beforeSurveySettings);
     $aData['pluginSettings'] = $beforeSurveySettings->get('surveysettings');
     return $aData;
 }
Exemplo n.º 27
0
 /**
  * Update survey settings with post value
  *
  * @param $iSurveyId  The survey id
  */
 function update($iSurveyId)
 {
     if (!Yii::app()->request->isPostRequest) {
         throw new CHttpException(500);
     }
     if (!Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'update')) {
         throw new CHttpException(401, "401 Unauthorized");
     }
     // Preload survey
     $oSurvey = Survey::model()->findByPk($iSurveyId);
     // Save plugin settings.
     $pluginSettings = App()->request->getPost('plugin', array());
     foreach ($pluginSettings as $plugin => $settings) {
         $settingsEvent = new PluginEvent('newSurveySettings');
         $settingsEvent->set('settings', $settings);
         $settingsEvent->set('survey', $iSurveyId);
         App()->getPluginManager()->dispatchEvent($settingsEvent, $plugin);
     }
     /* Start to fix some param before save (TODO : use models directly ?) */
     /* Date management */
     Yii::app()->loadHelper('surveytranslator');
     $formatdata = getDateFormatData(Yii::app()->session['dateformat']);
     Yii::app()->loadLibrary('Date_Time_Converter');
     $startdate = App()->request->getPost('startdate');
     if (trim($startdate) == "") {
         $startdate = null;
     } else {
         Yii::app()->loadLibrary('Date_Time_Converter');
         $datetimeobj = new date_time_converter($startdate, $formatdata['phpdate'] . ' H:i');
         //new Date_Time_Converter($startdate,$formatdata['phpdate'].' H:i');
         $startdate = $datetimeobj->convert("Y-m-d H:i:s");
     }
     $expires = App()->request->getPost('expires');
     if (trim($expires) == "") {
         $expires = null;
     } else {
         $datetimeobj = new date_time_converter($expires, $formatdata['phpdate'] . ' H:i');
         //new Date_Time_Converter($expires, $formatdata['phpdate'].' H:i');
         $expires = $datetimeobj->convert("Y-m-d H:i:s");
     }
     // We have $oSurvey : update and save it
     $oSurvey->admin = Yii::app()->request->getPost('admin');
     $oSurvey->expires = $expires;
     $oSurvey->startdate = $startdate;
     $oSurvey->faxto = App()->request->getPost('faxto');
     $oSurvey->format = App()->request->getPost('format');
     $oSurvey->template = Yii::app()->request->getPost('template');
     $oSurvey->assessments = App()->request->getPost('assessments');
     $oSurvey->additional_languages = implode(' ', Yii::app()->request->getPost('additional_languages', array()));
     if ($oSurvey->active != 'Y') {
         $oSurvey->anonymized = App()->request->getPost('anonymized');
         $oSurvey->savetimings = App()->request->getPost('savetimings');
         $oSurvey->datestamp = App()->request->getPost('datestamp');
         $oSurvey->ipaddr = App()->request->getPost('ipaddr');
         $oSurvey->refurl = App()->request->getPost('refurl');
     }
     $oSurvey->publicgraphs = App()->request->getPost('publicgraphs');
     $oSurvey->usecookie = App()->request->getPost('usecookie');
     $oSurvey->allowregister = App()->request->getPost('allowregister');
     $oSurvey->allowsave = App()->request->getPost('allowsave');
     $oSurvey->navigationdelay = App()->request->getPost('navigationdelay');
     $oSurvey->printanswers = App()->request->getPost('printanswers');
     $oSurvey->publicstatistics = App()->request->getPost('publicstatistics');
     $oSurvey->autoredirect = App()->request->getPost('autoredirect');
     $oSurvey->showxquestions = App()->request->getPost('showxquestions');
     $oSurvey->showgroupinfo = App()->request->getPost('showgroupinfo');
     $oSurvey->showqnumcode = App()->request->getPost('showqnumcode');
     $oSurvey->shownoanswer = App()->request->getPost('shownoanswer');
     $oSurvey->showwelcome = App()->request->getPost('showwelcome');
     $oSurvey->allowprev = App()->request->getPost('allowprev');
     $oSurvey->questionindex = App()->request->getPost('questionindex');
     $oSurvey->nokeyboard = App()->request->getPost('nokeyboard');
     $oSurvey->showprogress = App()->request->getPost('showprogress');
     $oSurvey->listpublic = App()->request->getPost('public');
     $oSurvey->htmlemail = App()->request->getPost('htmlemail');
     $oSurvey->sendconfirmation = App()->request->getPost('sendconfirmation');
     $oSurvey->tokenanswerspersistence = App()->request->getPost('tokenanswerspersistence');
     $oSurvey->alloweditaftercompletion = App()->request->getPost('alloweditaftercompletion');
     $oSurvey->usecaptcha = App()->request->getPost('usecaptcha');
     $oSurvey->emailresponseto = App()->request->getPost('emailresponseto');
     $oSurvey->emailnotificationto = App()->request->getPost('emailnotificationto');
     $oSurvey->googleanalyticsapikey = App()->request->getPost('googleanalyticsapikey');
     $oSurvey->googleanalyticsstyle = App()->request->getPost('googleanalyticsstyle');
     $oSurvey->tokenlength = App()->request->getPost('tokenlength');
     $oSurvey->adminemail = App()->request->getPost('adminemail');
     $oSurvey->bounce_email = App()->request->getPost('bounce_email');
     if ($oSurvey->save()) {
         Yii::app()->setFlashMessage(gT("Survey settings were successfully saved."));
     } else {
         Yii::app()->setFlashMessage(gT("Survey could not be updated."), "error");
         tracevar($oSurvey->getErrors());
     }
     /* Reload $oSurvey (language are fixed : need it ?) */
     $oSurvey = Survey::model()->findByPk($iSurveyId);
     /* Delete removed language cleanLanguagesFromSurvey do it already why redo it (cleanLanguagesFromSurvey must be moved to model) ?*/
     $aAvailableLanguage = $oSurvey->getAllLanguages();
     $oCriteria = new CDbCriteria();
     $oCriteria->compare('surveyls_survey_id', $iSurveyId);
     $oCriteria->addNotInCondition('surveyls_language', $aAvailableLanguage);
     SurveyLanguageSetting::model()->deleteAll($oCriteria);
     /* Add new language fixLanguageConsistency do it ?*/
     foreach ($oSurvey->additionalLanguages as $sLang) {
         if ($sLang) {
             $oLanguageSettings = SurveyLanguageSetting::model()->find('surveyls_survey_id=:surveyid AND surveyls_language=:langname', array(':surveyid' => $iSurveyId, ':langname' => $sLang));
             if (!$oLanguageSettings) {
                 $oLanguageSettings = new SurveyLanguageSetting();
                 $languagedetails = getLanguageDetails($sLang);
                 $oLanguageSettings->surveyls_survey_id = $iSurveyId;
                 $oLanguageSettings->surveyls_language = $sLang;
                 $oLanguageSettings->surveyls_title = '';
                 // Not in default model ?
                 $oLanguageSettings->surveyls_dateformat = $languagedetails['dateformat'];
                 if (!$oLanguageSettings->save()) {
                     Yii::app()->setFlashMessage(gT("Survey language could not be created."), "error");
                     tracevar($oLanguageSettings->getErrors());
                 }
             }
         }
     }
     /* Language fix : remove and add question/group */
     cleanLanguagesFromSurvey($iSurveyId, implode(" ", $oSurvey->additionalLanguages));
     fixLanguageConsistency($iSurveyId, implode(" ", $oSurvey->additionalLanguages));
     // Url params in json
     $aURLParams = json_decode(Yii::app()->request->getPost('allurlparams'), true);
     SurveyURLParameter::model()->deleteAllByAttributes(array('sid' => $iSurveyId));
     if (isset($aURLParams)) {
         foreach ($aURLParams as $aURLParam) {
             $aURLParam['parameter'] = trim($aURLParam['parameter']);
             if ($aURLParam['parameter'] == '' || !preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $aURLParam['parameter']) || $aURLParam['parameter'] == 'sid' || $aURLParam['parameter'] == 'newtest' || $aURLParam['parameter'] == 'token' || $aURLParam['parameter'] == 'lang') {
                 continue;
                 // this parameter name seems to be invalid - just ignore it
             }
             unset($aURLParam['act']);
             unset($aURLParam['title']);
             unset($aURLParam['id']);
             if ($aURLParam['targetqid'] == '') {
                 $aURLParam['targetqid'] = NULL;
             }
             if ($aURLParam['targetsqid'] == '') {
                 $aURLParam['targetsqid'] = NULL;
             }
             $aURLParam['sid'] = $iSurveyId;
             $param = new SurveyURLParameter();
             foreach ($aURLParam as $k => $v) {
                 $param->{$k} = $v;
             }
             $param->save();
         }
     }
     if (Yii::app()->request->getPost('redirect')) {
         $this->getController()->redirect(Yii::app()->request->getPost('redirect'));
         App()->end();
     }
 }
Exemplo n.º 28
0
 /**
  * Checks if a user has a certain permission
  *
  * @param $iEntityID integer The entity ID
  * @param $sEntityName string The entity name
  * @param $sPermission string Name of the permission
  * @param $sCRUD string The permission detail you want to check on: 'create','read','update','delete','import' or 'export'
  * @param $iUserID integer User ID - if not given the one of the current user is used
  * @return bool True if user has the permission
  */
 public function hasPermission($iEntityID, $sEntityName, $sPermission, $sCRUD = 'read', $iUserID = null)
 {
     if (is_null($iUserID) && Yii::app() instanceof CConsoleApplication) {
         return true;
     }
     static $aPermissionStatic;
     /* Allow plugin to set own permission */
     $oEvent = new PluginEvent('beforeHasPermission');
     $oEvent->set('iEntityID', $iEntityID);
     $oEvent->set('sEntityName', $sEntityName);
     $oEvent->set('sPermission', $sPermission);
     $oEvent->set('sCRUD', $sCRUD);
     $oEvent->set('iUserID', $iUserID);
     App()->getPluginManager()->dispatchEvent($oEvent);
     $pluginbPermission = $oEvent->get('bPermission');
     if (isset($pluginbPermission)) {
         return $pluginbPermission;
     }
     /* Always return true for CConsoleApplication (before or after plugin ? All other seems better after plugin) */
     if (is_null($iUserID) && Yii::app() instanceof CConsoleApplication) {
         return true;
     }
     /* Always return false for unknow sCRUD */
     if (!in_array($sCRUD, array('create', 'read', 'update', 'delete', 'import', 'export'))) {
         return false;
     }
     $sCRUD = $sCRUD . '_p';
     /* Always return false for guests */
     if (!$this->getUserId($iUserID)) {
         return false;
     } else {
         $iUserID = $this->getUserId($iUserID);
     }
     /* Always return true if you are the owner : this can be done in core plugin ? */
     if ($iUserID == $this->getOwnerId($iEntityID, $sEntityName)) {
         return true;
     }
     /* Check if superadmin and static it */
     if (!isset($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'])) {
         $aPermission = $this->findByAttributes(array("entity_id" => 0, 'entity' => 'global', "uid" => $iUserID, "permission" => 'superadmin'));
         $bPermission = is_null($aPermission) ? array() : $aPermission->attributes;
         if (!isset($bPermission['read_p']) || $bPermission['read_p'] == 0) {
             $bPermission = false;
         } else {
             $bPermission = true;
         }
         $aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'] = $bPermission;
     }
     if ($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p']) {
         return true;
     }
     /* Check in permission DB and static it */
     if (!isset($aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD])) {
         $query = $this->findByAttributes(array("entity_id" => $iEntityID, "uid" => $iUserID, "entity" => $sEntityName, "permission" => $sPermission));
         $bPermission = is_null($query) ? array() : $query->attributes;
         if (!isset($bPermission[$sCRUD]) || $bPermission[$sCRUD] == 0) {
             $bPermission = false;
         } else {
             $bPermission = true;
         }
         $aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD] = $bPermission;
     }
     return $aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD];
 }
Exemplo n.º 29
0
 /**
  * Construction of replacement array, actually doing it with redata
  *
  * @param $aQuestionQanda : array from qanda helper
  * @return aray of replacement for question.psptl
  **/
 public static function getQuestionReplacement($aQuestionQanda)
 {
     // Get the default replacement and set empty value by default
     $aReplacement = array("QID" => "", "SGQ" => "", "AID" => "", "QUESTION_CODE" => "", "QUESTION_NUMBER" => "", "QUESTION" => "", "QUESTION_TEXT" => "", "QUESTIONHELP" => "", "QUESTIONHELPPLAINTEXT" => "", "QUESTION_CLASS" => "", "QUESTION_MAN_CLASS" => "", "QUESTION_INPUT_ERROR_CLASS" => "", "ANSWER" => "", "QUESTION_HELP" => "", "QUESTION_VALID_MESSAGE" => "", "QUESTION_FILE_VALID_MESSAGE" => "", "QUESTION_MAN_MESSAGE" => "", "QUESTION_MANDATORY" => "", "QUESTION_ESSENTIALS" => "");
     if (!is_array($aQuestionQanda) || empty($aQuestionQanda[0])) {
         return $aReplacement;
     }
     $iQid = $aQuestionQanda[4];
     $lemQuestionInfo = LimeExpressionManager::GetQuestionStatus($iQid);
     $iSurveyId = Yii::app()->getConfig('surveyID');
     // Or : by SGQA of question ? by Question::model($iQid)->sid;
     $oSurveyId = Survey::model()->findByPk($iSurveyId);
     $sType = $lemQuestionInfo['info']['type'];
     // Core value : not replaced
     $aReplacement['QID'] = $iQid;
     $aReplacement['GID'] = $aQuestionQanda[6];
     // Not sure for aleatory : it's the real gid or the updated gid ? We need original gid or updated gid ?
     $aReplacement['SGQ'] = $aQuestionQanda[7];
     $aReplacement['AID'] = isset($aQuestionQanda[0]['aid']) ? $aQuestionQanda[0]['aid'] : "";
     $aReplacement['QUESTION_CODE'] = $aReplacement['QUESTION_NUMBER'] = "";
     $sCode = $aQuestionQanda[5];
     $iNumber = $aQuestionQanda[0]['number'];
     switch (Yii::app()->getConfig('showqnumcode')) {
         case 'both':
             $aReplacement['QUESTION_CODE'] = $sCode;
             $aReplacement['QUESTION_NUMBER'] = $iNumber;
             break;
         case 'number':
             $aReplacement['QUESTION_NUMBER'] = $iNumber;
             break;
         case 'number':
             $aReplacement['QUESTION_CODE'] = $sCode;
             break;
         case 'choose':
         default:
             switch ($oSurveyId->showqnumcode) {
                 case 'B':
                     // Both
                     $aReplacement['QUESTION_CODE'] = $sCode;
                     $aReplacement['QUESTION_NUMBER'] = $iNumber;
                     break;
                 case 'N':
                     $aReplacement['QUESTION_NUMBER'] = $iNumber;
                     break;
                 case 'C':
                     $aReplacement['QUESTION_CODE'] = $sCode;
                     break;
                 case 'X':
                 default:
                     break;
             }
             break;
     }
     $aReplacement['QUESTION'] = $aQuestionQanda[0]['all'];
     // Deprecated : only used in old template (very old)
     // Core value : user text
     $aReplacement['QUESTION_TEXT'] = $aQuestionQanda[0]['text'];
     $aReplacement['QUESTIONHELP'] = $lemQuestionInfo['info']['help'];
     // User help
     // To be moved in a extra plugin : QUESTIONHELP img adding
     $sTemplateDir = Template::model()->getTemplatePath($oSurveyId->template);
     $sTemplateUrl = Template::model()->getTemplateURL($oSurveyId->template);
     if (flattenText($aReplacement['QUESTIONHELP'], true, true) != '') {
         $aReplacement['QUESTIONHELP'] = Yii::app()->getController()->renderPartial('/survey/system/questionhelp/questionhelp', array('questionHelp' => $aReplacement['QUESTIONHELP']), true);
     }
     // Core value :the classes
     $aReplacement['QUESTION_CLASS'] = Question::getQuestionClass($sType);
     //get additional question classes from question attribute
     $aQuestionAttributes = getQuestionAttributeValues($aQuestionQanda[4]);
     //add additional classes
     if (isset($aQuestionAttributes['cssclass'])) {
         $aReplacement['QUESTION_CLASS'] .= " " . $aQuestionAttributes['cssclass'];
     }
     $aMandatoryClass = array();
     if ($lemQuestionInfo['info']['mandatory'] == 'Y') {
         $aMandatoryClass[] = 'mandatory';
     }
     if ($lemQuestionInfo['anyUnanswered'] && $_SESSION['survey_' . $iSurveyId]['maxstep'] != $_SESSION['survey_' . $iSurveyId]['step']) {
         $aMandatoryClass[] = 'missing';
     }
     $aReplacement['QUESTION_MAN_CLASS'] = !empty($aMandatoryClass) ? " " . implode(" ", $aMandatoryClass) : "";
     $aReplacement['QUESTION_INPUT_ERROR_CLASS'] = $aQuestionQanda[0]['input_error_class'];
     // Core value : LS text : EM and not
     $aReplacement['ANSWER'] = $aQuestionQanda[1];
     $aReplacement['QUESTION_HELP'] = $aQuestionQanda[0]['help'];
     // Core help only, not EM
     $aReplacement['QUESTION_VALID_MESSAGE'] = $aQuestionQanda[0]['valid_message'];
     // $lemQuestionInfo['validTip']
     $aReplacement['QUESTION_FILE_VALID_MESSAGE'] = $aQuestionQanda[0]['file_valid_message'];
     // $lemQuestionInfo['??']
     $aReplacement['QUESTION_MAN_MESSAGE'] = $aQuestionQanda[0]['man_message'];
     $aReplacement['QUESTION_MANDATORY'] = $aQuestionQanda[0]['mandatory'];
     // For QUESTION_ESSENTIALS
     $aHtmlOptions = array();
     if (!$lemQuestionInfo['relevant'] || $lemQuestionInfo['hidden']) {
         $aHtmlOptions['style'] = 'display: none;';
     }
     // Launch the event
     $event = new PluginEvent('beforeQuestionRender');
     // Some helper
     $event->set('surveyId', $iSurveyId);
     $event->set('type', $sType);
     $event->set('code', $sCode);
     $event->set('qid', $iQid);
     $event->set('gid', $aReplacement['GID']);
     // User text
     $event->set('text', $aReplacement['QUESTION_TEXT']);
     $event->set('questionhelp', $aReplacement['QUESTIONHELP']);
     // The classes
     $event->set('class', $aReplacement['QUESTION_CLASS']);
     $event->set('man_class', $aReplacement['QUESTION_MAN_CLASS']);
     $event->set('input_error_class', $aReplacement['QUESTION_INPUT_ERROR_CLASS']);
     // LS core text
     $event->set('answers', $aReplacement['ANSWER']);
     $event->set('help', $aReplacement['QUESTION_HELP']);
     $event->set('man_message', $aReplacement['QUESTION_MAN_MESSAGE']);
     $event->set('valid_message', $aReplacement['QUESTION_VALID_MESSAGE']);
     $event->set('file_valid_message', $aReplacement['QUESTION_FILE_VALID_MESSAGE']);
     // htmlOptions for container
     $event->set('aHtmlOptions', $aHtmlOptions);
     App()->getPluginManager()->dispatchEvent($event);
     // User text
     $aReplacement['QUESTION_TEXT'] = $event->get('text');
     $aReplacement['QUESTIONHELP'] = $event->get('questionhelp');
     $aReplacement['QUESTIONHELPPLAINTEXT'] = strip_tags(addslashes($aReplacement['QUESTIONHELP']));
     // The classes
     $aReplacement['QUESTION_CLASS'] = $event->get('class');
     $aReplacement['QUESTION_MAN_CLASS'] = $event->get('man_class');
     $aReplacement['QUESTION_INPUT_ERROR_CLASS'] = $event->get('input_error_class');
     // LS core text
     $aReplacement['ANSWER'] = $event->get('answers');
     $aReplacement['QUESTION_HELP'] = $event->get('help');
     $aReplacement['QUESTION_MAN_MESSAGE'] = $event->get('man_message');
     $aReplacement['QUESTION_VALID_MESSAGE'] = $event->get('valid_message');
     $aReplacement['QUESTION_FILE_VALID_MESSAGE'] = $event->get('file_valid_message');
     $aReplacement['QUESTION_MANDATORY'] = $event->get('mandatory', $aReplacement['QUESTION_MANDATORY']);
     // Always add id for QUESTION_ESSENTIALS
     $aHtmlOptions['id'] = "question{$iQid}";
     $aReplacement['QUESTION_ESSENTIALS'] = CHtml::renderAttributes($aHtmlOptions);
     return $aReplacement;
 }
    function run($actionID)
    {
        $surveyid = Yii::app()->session['LEMsid'];
        $oSurvey = Survey::model()->findByPk($surveyid);
        if (!$oSurvey) {
            throw new CHttpException(400);
        }
        // See for debug > 1
        $sLanguage = isset(Yii::app()->session['survey_' . $surveyid]['s_lang']) ? Yii::app()->session['survey_' . $surveyid]['s_lang'] : "";
        $uploaddir = Yii::app()->getConfig("uploaddir");
        $tempdir = Yii::app()->getConfig("tempdir");
        Yii::app()->loadHelper("database");
        // Fill needed var
        $sFileGetContent = Yii::app()->request->getParam('filegetcontents', '');
        // The file to view fu_ or fu_tmp
        $bDelete = Yii::app()->request->getParam('delete');
        $sFieldName = Yii::app()->request->getParam('fieldname');
        $sFileName = Yii::app()->request->getParam('filename', '');
        // The file to delete fu_ or fu_tmp
        $sOriginalFileName = Yii::app()->request->getParam('name', '');
        // Used for javascript return only
        $sMode = Yii::app()->request->getParam('mode');
        $sPreview = Yii::app()->request->getParam('preview', 0);
        // Validate and filter and throw error if problems
        // Using 'futmp_'.randomChars(15).'_'.$pathinfo['extension'] for filename, then remove all other characters
        $sFileGetContentFiltered = preg_replace('/[^a-zA-Z0-9_]/', '', $sFileGetContent);
        $sFileNameFiltered = preg_replace('/[^a-zA-Z0-9_]/', '', $sFileName);
        $sFieldNameFiltered = preg_replace('/[^X0-9]/', '', $sFieldName);
        if ($sFileGetContent != $sFileGetContentFiltered || $sFileName != $sFileNameFiltered || $sFieldName != $sFieldNameFiltered) {
            // If one seems to be a hack: Bad request
            throw new CHttpException(400);
            // See for debug > 1
        }
        if ($sFileGetContent) {
            if (substr($sFileGetContent, 0, 6) == 'futmp_') {
                $sFileDir = $tempdir . '/upload/';
            } elseif (substr($sFileGetContent, 0, 3) == 'fu_') {
                // Need to validate $_SESSION['srid'], and this file is from this srid !
                $sFileDir = "{$uploaddir}/surveys/{$surveyid}/files/";
            } else {
                throw new CHttpException(400);
                // See for debug > 1
            }
            if (is_file($sFileDir . $sFileGetContent)) {
                header('Content-Type: ' . CFileHelper::getMimeType($sFileDir . $sFileGetContent));
                readfile($sFileDir . $sFileGetContent);
                Yii::app()->end();
            } else {
                Yii::app()->end();
            }
        } elseif ($bDelete) {
            if (substr($sFileName, 0, 6) == 'futmp_') {
                $sFileDir = $tempdir . '/upload/';
            } elseif (substr($sFileName, 0, 3) == 'fu_') {
                // Need to validate $_SESSION['srid'], and this file is from this srid !
                $sFileDir = "{$uploaddir}/surveys/{$surveyid}/files/";
            } else {
                throw new CHttpException(400);
                // See for debug > 1
            }
            if (isset($_SESSION[$sFieldName])) {
                // We already have $sFieldName ?
                $sJSON = $_SESSION[$sFieldName];
                $aFiles = json_decode(stripslashes($sJSON), true);
                if (substr($sFileName, 0, 3) == 'fu_') {
                    $iFileIndex = 0;
                    $found = false;
                    foreach ($aFiles as $aFile) {
                        if ($aFile['filename'] == $sFileName) {
                            $found = true;
                            break;
                        }
                        $iFileIndex++;
                    }
                    if ($found == true) {
                        unset($aFiles[$iFileIndex]);
                    }
                    $_SESSION[$sFieldName] = ls_json_encode($aFiles);
                }
            }
            //var_dump($sFileDir.$sFilename);
            // Return some json to do a beautiful text
            if (@unlink($sFileDir . $sFileName)) {
                echo sprintf(gT('File %s deleted'), $sOriginalFileName);
            } else {
                echo gT('Oops, There was an error deleting the file');
            }
            Yii::app()->end();
        }
        if ($sMode == "upload") {
            $sTempUploadDir = $tempdir . '/upload/';
            // Check if exists and is writable
            if (!file_exists($sTempUploadDir)) {
                // Try to create
                mkdir($sTempUploadDir);
            }
            $filename = $_FILES['uploadfile']['name'];
            // Do we filter file name ? It's used on displaying only , but not save like that.
            //$filename = sanitize_filename($_FILES['uploadfile']['name']);// This remove all non alpha numeric characters and replaced by _ . Leave only one dot .
            $size = 0.001 * $_FILES['uploadfile']['size'];
            $preview = Yii::app()->session['preview'];
            $aFieldMap = createFieldMap($surveyid, 'short', false, false, $sLanguage);
            if (!isset($aFieldMap[$sFieldName])) {
                throw new CHttpException(400);
                // See for debug > 1
            }
            $aAttributes = getQuestionAttributeValues($aFieldMap[$sFieldName]['qid']);
            $maxfilesize = (int) $aAttributes['max_filesize'];
            $valid_extensions_array = explode(",", $aAttributes['allowed_filetypes']);
            $valid_extensions_array = array_map('trim', $valid_extensions_array);
            $pathinfo = pathinfo($_FILES['uploadfile']['name']);
            $ext = strtolower($pathinfo['extension']);
            $randfilename = 'futmp_' . randomChars(15) . '_' . $pathinfo['extension'];
            $randfileloc = $sTempUploadDir . $randfilename;
            // check to see that this file type is allowed
            // it is also  checked at the client side, but jst double checking
            if (!in_array($ext, $valid_extensions_array)) {
                $return = array("success" => false, "msg" => sprintf(gT("Sorry, this file extension (%s) is not allowed!"), $ext));
                //header('Content-Type: application/json');
                echo ls_json_encode($return);
                Yii::app()->end();
            }
            // If this is just a preview, don't save the file
            if ($preview) {
                if ($size > $maxfilesize) {
                    $return = array("success" => false, "msg" => sprintf(gT("Sorry, this file is too large. Only files upto %s KB are allowed."), $maxfilesize));
                    //header('Content-Type: application/json');
                    echo ls_json_encode($return);
                    Yii::app()->end();
                } else {
                    if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $randfileloc)) {
                        $return = array("success" => true, "file_index" => $filecount, "size" => $size, "name" => rawurlencode(basename($filename)), "ext" => $ext, "filename" => $randfilename, "msg" => gT("The file has been successfuly uploaded."));
                        // TODO : unlink this file since this is just a preview. But we can do it only if it's not needed, and still needed to have the file content
                        // Maybe use a javascript 'onunload' on preview question/group
                        // unlink($randfileloc)
                        //header('Content-Type: application/json');
                        echo ls_json_encode($return);
                        Yii::app()->end();
                    }
                }
            } else {
                // if everything went fine and the file was uploaded successfuly,
                // send the file related info back to the client
                $iFileUploadTotalSpaceMB = Yii::app()->getConfig("iFileUploadTotalSpaceMB");
                if ($size > $maxfilesize) {
                    $return = array("success" => false, "msg" => sprintf(gT("Sorry, this file is too large. Only files up to %s KB are allowed.", 'unescaped'), $maxfilesize));
                    //header('Content-Type: application/json');
                    echo ls_json_encode($return);
                    Yii::app()->end();
                } elseif ($iFileUploadTotalSpaceMB > 0 && calculateTotalFileUploadUsage() + $size / 1024 / 1024 > $iFileUploadTotalSpaceMB) {
                    $return = array("success" => false, "msg" => gT("We are sorry but there was a system error and your file was not saved. An email has been dispatched to notify the survey administrator.", 'unescaped'));
                    //header('Content-Type: application/json');
                    echo ls_json_encode($return);
                    Yii::app()->end();
                } elseif (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $randfileloc)) {
                    $return = array("success" => true, "size" => $size, "name" => rawurlencode(basename($filename)), "ext" => $ext, "filename" => $randfilename, "msg" => gT("The file has been successfuly uploaded."));
                    //header('Content-Type: application/json');
                    echo ls_json_encode($return);
                    Yii::app()->end();
                } else {
                    // check for upload error
                    if ($_FILES['uploadfile']['error'] > 2) {
                        $return = array("success" => false, "msg" => gT("Sorry, there was an error uploading your file"));
                        //header('Content-Type: application/json');
                        echo ls_json_encode($return);
                        Yii::app()->end();
                    } else {
                        if ($_FILES['uploadfile']['error'] == 1 || $_FILES['uploadfile']['error'] == 2 || $size > $maxfilesize) {
                            $return = array("success" => false, "msg" => sprintf(gT("Sorry, this file is too large. Only files upto %s KB are allowed."), $maxfilesize));
                            //header('Content-Type: application/json');
                            echo ls_json_encode($return);
                            Yii::app()->end();
                        } else {
                            $return = array("success" => false, "msg" => gT("Unknown error"));
                            //header('Content-Type: application/json');
                            echo ls_json_encode($return);
                            Yii::app()->end();
                        }
                    }
                }
            }
            return;
        }
        $meta = '';
        App()->getClientScript()->registerPackage('jqueryui');
        App()->getClientScript()->registerPackage('jquery-superfish');
        $sNeededScriptVar = '
            var uploadurl = "' . $this->createUrl('/uploader/index/mode/upload/') . '";
            var imageurl = "' . Yii::app()->getConfig('imageurl') . '/";
            var surveyid = "' . $surveyid . '";
            var fieldname = "' . $sFieldName . '";
            var questgrppreview  = ' . $sPreview . ';
            csrfToken = ' . ls_json_encode(Yii::app()->request->csrfToken) . ';
            showpopups="' . Yii::app()->getConfig("showpopups") . '";
        ';
        $sLangScriptVar = "\n                uploadLang = {\n                     titleFld: '" . gT('Title', 'js') . "',\n                     commentFld: '" . gT('Comment', 'js') . "',\n                     errorNoMoreFiles: '" . gT('Sorry, no more files can be uploaded!', 'js') . "',\n                     errorOnlyAllowed: '" . gT('Sorry, only %s files can be uploaded for this question!', 'js') . "',\n                     uploading: '" . gT('Uploading', 'js') . "',\n                     selectfile: '" . gT('Select file', 'js') . "',\n                     errorNeedMore: '" . gT('Please upload %s more file(s).', 'js') . "',\n                     errorMoreAllowed: '" . gT('If you wish, you may upload %s more file(s); else you may return back to survey.', 'js') . "',\n                     errorMaxReached: '" . gT('The maximum number of files has been uploaded. You may return back to survey.', 'js') . "',\n                     errorTooMuch: '" . gT('The maximum number of files has been uploaded. You may return back to survey.', 'js') . "',\n                     errorNeedMoreConfirm: '" . gT("You need to upload %s more files for this question.\nAre you sure you want to exit?", 'js') . "',\n                     deleteFile : '" . gt('Delete', 'js') . "',\n                     editFile : '" . gt('Edit', 'js') . "',\n                    };\n        ";
        $aSurveyInfo = getSurveyInfo($surveyid, $sLanguage);
        $oEvent = new PluginEvent('beforeSurveyPage');
        $oEvent->set('surveyId', $surveyid);
        App()->getPluginManager()->dispatchEvent($oEvent);
        if (!is_null($oEvent->get('template'))) {
            $aSurveyInfo['templatedir'] = $event->get('template');
        }
        $sTemplateDir = getTemplatePath($aSurveyInfo['template']);
        $sTemplateUrl = getTemplateURL($aSurveyInfo['template']) . "/";
        App()->clientScript->registerScript('sNeededScriptVar', $sNeededScriptVar, CClientScript::POS_HEAD);
        App()->clientScript->registerScript('sLangScriptVar', $sLangScriptVar, CClientScript::POS_HEAD);
        App()->getClientScript()->registerScriptFile(Yii::app()->getConfig("generalscripts") . 'ajaxupload.js');
        App()->getClientScript()->registerScriptFile(Yii::app()->getConfig("generalscripts") . 'uploader.js');
        App()->getClientScript()->registerScriptFile("{$sTemplateUrl}template.js");
        App()->clientScript->registerCssFile(Yii::app()->getConfig("publicstyleurl") . "uploader.css");
        App()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl') . "uploader-files.css");
        if (file_exists($sTemplateDir . DIRECTORY_SEPARATOR . 'jquery-ui-custom.css')) {
            Yii::app()->getClientScript()->registerCssFile("{$sTemplateUrl}jquery-ui-custom.css");
        } elseif (file_exists($sTemplateDir . DIRECTORY_SEPARATOR . 'jquery-ui.css')) {
            Yii::app()->getClientScript()->registerCssFile("{$sTemplateUrl}jquery-ui.css");
        } else {
            Yii::app()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl') . "jquery-ui.css");
        }
        App()->clientScript->registerCssFile("{$sTemplateUrl}template.css");
        $header = getHeader($meta);
        echo $header;
        $fn = $sFieldName;
        $qid = (int) Yii::app()->request->getParam('qid');
        $minfiles = (int) Yii::app()->request->getParam('minfiles');
        $maxfiles = (int) Yii::app()->request->getParam('maxfiles');
        $qidattributes = getQuestionAttributeValues($qid);
        $qidattributes['max_filesize'] = floor(min($qidattributes['max_filesize'] * 1024, getMaximumFileUploadSize()) / 1024);
        $body = '</head><body class="uploader">
                <div id="notice"></div>
                <input type="hidden" id="ia"                value="' . $fn . '" />
                <input type="hidden" id="' . $fn . '_minfiles"          value="' . $minfiles . '" />
                <input type="hidden" id="' . $fn . '_maxfiles"          value="' . $maxfiles . '" />
                <input type="hidden" id="' . $fn . '_maxfilesize"       value="' . $qidattributes['max_filesize'] . '" />
                <input type="hidden" id="' . $fn . '_allowed_filetypes" value="' . $qidattributes['allowed_filetypes'] . '" />
                <input type="hidden" id="preview"                   value="' . Yii::app()->session['preview'] . '" />
                <input type="hidden" id="' . $fn . '_show_comment"      value="' . $qidattributes['show_comment'] . '" />
                <input type="hidden" id="' . $fn . '_show_title"        value="' . $qidattributes['show_title'] . '" />
                <input type="hidden" id="' . $fn . '_licount"           value="0" />
                <input type="hidden" id="' . $fn . '_filecount"         value="0" />

                <!-- The upload button -->
                <div class="upload-div">
                    <button id="button1" class="button upload-button" type="button" >' . gT("Select file") . '</button>
                </div>

                <p class="uploadmsg">' . sprintf(gT("You can upload %s under %s KB each."), $qidattributes['allowed_filetypes'], $qidattributes['max_filesize']) . '</p>
                <div class="uploadstatus" id="uploadstatus"></div>

                <!-- The list of uploaded files -->

            </body>
        </html>';
        App()->getClientScript()->render($body);
        echo $body;
    }