/** * This function import CSV file to responses table * * @param string $sFullFilePath * @param integer $iSurveyId * @param array $aOptions * Return array $result ("errors","warnings","success") */ function CSVImportResponses($sFullFilePath, $iSurveyId, $aOptions = array()) { $clang = Yii::app()->lang; // Default optional if (!isset($aOptions['bDeleteFistLine'])) { $aOptions['bDeleteFistLine'] = true; } // By default delete first line (vvimport) if (!isset($aOptions['sExistingId'])) { $aOptions['sExistingId'] = "ignore"; } // By default exclude existing id if (!isset($aOptions['bNotFinalized'])) { $aOptions['bNotFinalized'] = false; } // By default don't change finalized part if (!isset($aOptions['sCharset']) || !$aOptions['sCharset']) { $aOptions['sCharset'] = "utf8"; } if (!isset($aOptions['sSeparator'])) { $aOptions['sSeparator'] = "\t"; } if (!isset($aOptions['sQuoted'])) { $aOptions['sQuoted'] = "\""; } // Fix some part if (!array_key_exists($aOptions['sCharset'], aEncodingsArray())) { $aOptions['sCharset'] = "utf8"; } // Prepare an array of sentence for result $CSVImportResult = array(); // Read the file $handle = fopen($sFullFilePath, "r"); // Need to be adapted for Mac ? in options ? while (!feof($handle)) { $buffer = fgets($handle); //To allow for very long lines . Another option is fgetcsv (0 to length), but need mb_convert_encoding $aFileResponses[] = mb_convert_encoding($buffer, "UTF-8", $aOptions['sCharset']); } // Close the file fclose($handle); if ($aOptions['bDeleteFistLine']) { array_shift($aFileResponses); } $aRealFieldNames = Yii::app()->db->getSchema()->getTable(SurveyDynamic::model($iSurveyId)->tableName())->getColumnNames(); //$aCsvHeader=array_map("trim",explode($aOptions['sSeparator'], trim(array_shift($aFileResponses)))); $aCsvHeader = str_getcsv(array_shift($aFileResponses), $aOptions['sSeparator'], $aOptions['sQuoted']); $aLemFieldNames = LimeExpressionManager::getLEMqcode2sgqa($iSurveyId); $aKeyForFieldNames = array(); // An array assicated each fieldname with corresponding responses key if (!$aCsvHeader) { $CSVImportResult['errors'][] = $clang->gT("File seems empty or has only one line"); return $CSVImportResult; } // Assign fieldname with $aFileResponses[] key foreach ($aRealFieldNames as $sFieldName) { if (in_array($sFieldName, $aCsvHeader)) { // First pass : simple associated $aKeyForFieldNames[$sFieldName] = array_search($sFieldName, $aCsvHeader); } elseif (in_array($sFieldName, $aLemFieldNames)) { // Second pass : LEM associated $sLemFieldName = array_search($sFieldName, $aLemFieldNames); if (in_array($sLemFieldName, $aCsvHeader)) { $aKeyForFieldNames[$sFieldName] = array_search($sLemFieldName, $aCsvHeader); } elseif ($aOptions['bForceImport']) { // as fallback just map questions in order of apperance // find out where the answer data columns start in CSV if (!isset($csv_ans_start_index)) { foreach ($aCsvHeader as $i => $name) { if (preg_match('/^\\d+X\\d+X\\d+/', $name)) { $csv_ans_start_index = $i; break; } } } // find out where the answer data columns start in destination table if (!isset($table_ans_start_index)) { foreach ($aRealFieldNames as $i => $name) { if (preg_match('/^\\d+X\\d+X\\d+/', $name)) { $table_ans_start_index = $i; break; } } } // map answers in order if (isset($table_ans_start_index, $csv_ans_start_index)) { $csv_index = array_search($sFieldName, $aRealFieldNames) - $table_ans_start_index + $csv_ans_start_index; if ($csv_index < sizeof($aCsvHeader)) { $aKeyForFieldNames[$sFieldName] = $csv_index; } else { $force_import_failed = true; break; } } } } } // check if forced error failed if (isset($force_import_failed)) { $CSVImportResult['errors'][] = $clang->gT("Import failed: Forced import was requested but the input file doesn't contain enough columns to fill the survey."); return $CSVImportResult; } // make sure at least one answer was imported before commiting foreach ($aKeyForFieldNames as $field => $index) { if (preg_match('/^\\d+X\\d+X\\d+/', $field)) { $import_ok = true; break; } } if (!isset($import_ok)) { $CSVImportResult['errors'][] = $clang->gT("Import failed: No answers could be mapped."); return $CSVImportResult; } // Now it's time to import // Some var to return $iNbResponseLine = 0; $iNbResponseExisting = 0; $aResponsesInserted = array(); $aResponsesUpdated = array(); $aResponsesError = array(); $aExistingsId = array(); $iMaxId = 0; // If we set the id, keep the max // Some specific header (with options) $iIdKey = array_search('id', $aCsvHeader); // the id is allways needed and used a lot if (is_int($iIdKey)) { unset($aKeyForFieldNames['id']); } $iSubmitdateKey = array_search('submitdate', $aCsvHeader); // submitdate can be forced to null if (is_int($iSubmitdateKey)) { unset($aKeyForFieldNames['submitdate']); } $iIdReponsesKey = is_int($iIdKey) ? $iIdKey : 0; // The key for reponses id: id column or first column if not exist // Import each responses line here while ($sResponses = array_shift($aFileResponses)) { $iNbResponseLine++; $bExistingsId = false; $aResponses = str_getcsv($sResponses, $aOptions['sSeparator'], $aOptions['sQuoted']); if ($iIdKey !== false) { $oSurvey = SurveyDynamic::model($iSurveyId)->findByPk($aResponses[$iIdKey]); if ($oSurvey) { $bExistingsId = true; $aExistingsId[] = $aResponses[$iIdKey]; // Do according to option switch ($aOptions['sExistingId']) { case 'replace': SurveyDynamic::model($iSurveyId)->deleteByPk($aResponses[$iIdKey]); SurveyDynamic::sid($iSurveyId); $oSurvey = new SurveyDynamic(); break; case 'replaceanswers': break; case 'renumber': SurveyDynamic::sid($iSurveyId); $oSurvey = new SurveyDynamic(); break; case 'skip': case 'ignore': default: $oSurvey = false; // Remove existing survey : don't import again break; } } else { SurveyDynamic::sid($iSurveyId); $oSurvey = new SurveyDynamic(); } } else { SurveyDynamic::sid($iSurveyId); $oSurvey = new SurveyDynamic(); } if ($oSurvey) { // First rule for id and submitdate if (is_int($iIdKey)) { if (!$bExistingsId) { $oSurvey->id = $aResponses[$iIdKey]; $iMaxId = $aResponses[$iIdKey] > $iMaxId ? $aResponses[$iIdKey] : $iMaxId; } elseif ($aOptions['sExistingId'] == 'replace' || $aOptions['sExistingId'] == 'replaceanswers') { $oSurvey->id = $aResponses[$iIdKey]; } } if ($aOptions['bNotFinalized']) { $oSurvey->submitdate = new CDbExpression('NULL'); } elseif (is_int($iSubmitdateKey)) { if ($aResponses[$iSubmitdateKey] == '{question_not_shown}' || trim($aResponses[$iSubmitdateKey] == '')) { $oSurvey->submitdate = new CDbExpression('NULL'); } else { // Maybe control valid date : see http://php.net/manual/en/function.checkdate.php#78362 for example $oSurvey->submitdate = $aResponses[$iSubmitdateKey]; } } foreach ($aKeyForFieldNames as $sFieldName => $iFieldKey) { if ($aResponses[$iFieldKey] == '{question_not_shown}') { $oSurvey->{$sFieldName} = new CDbExpression('NULL'); } else { $sResponse = str_replace(array("{quote}", "{tab}", "{cr}", "{newline}", "{lbrace}"), array("\"", "\t", "\r", "\n", "{"), $aResponses[$iFieldKey]); $oSurvey->{$sFieldName} = $sResponse; } } // We use transaction to prevent DB error $oTransaction = Yii::app()->db->beginTransaction(); try { if (isset($oSurvey->id) && !is_null($oSurvey->id)) { switchMSSQLIdentityInsert('survey_' . $iSurveyId, true); $bSwitched = true; } if ($oSurvey->save()) { $oTransaction->commit(); if ($bExistingsId && $aOptions['sExistingId'] != 'renumber') { $aResponsesUpdated[] = $aResponses[$iIdReponsesKey]; } else { $aResponsesInserted[] = $aResponses[$iIdReponsesKey]; } } else { $oTransaction->rollBack(); $aResponsesError[] = $aResponses[$iIdReponsesKey]; } if (isset($bSwitched) && $bSwitched == true) { switchMSSQLIdentityInsert('survey_' . $iSurveyId, false); $bSwitched = false; } } catch (Exception $oException) { $oTransaction->rollBack(); $aResponsesError[] = $aResponses[$iIdReponsesKey]; // Show some error to user ? // $CSVImportResult['errors'][]=$oException->getMessage(); // Show it in view // tracevar($oException->getMessage());// Show it in console (if debug is set) } } } // Fix max next id (for pgsql) // mysql dot need fix, but what for mssql ? // Do a model function for this can be a good idea (see activate_helper/activateSurvey) if (Yii::app()->db->driverName == 'pgsql') { $sSequenceName = Yii::app()->db->getSchema()->getTable("{{survey_{$iSurveyId}}}")->sequenceName; $iActualSerial = Yii::app()->db->createCommand("SELECT last_value FROM {$sSequenceName}")->queryScalar(); if ($iActualSerial < $iMaxId) { $sQuery = "SELECT setval(pg_get_serial_sequence('{{survey_{$iSurveyId}}}', 'id'),{$iMaxId},false);"; $result = @Yii::app()->db->createCommand($sQuery)->execute(); } } // End of import // Construction of returned information if ($iNbResponseLine) { $CSVImportResult['success'][] = sprintf($clang->gT("%s response lines in your file."), $iNbResponseLine); } else { $CSVImportResult['errors'][] = $clang->gT("No response lines in your file."); } if (count($aResponsesInserted)) { $CSVImportResult['success'][] = sprintf($clang->gT("%s responses were inserted."), count($aResponsesInserted)); // Maybe add implode aResponsesInserted array } if (count($aResponsesUpdated)) { $CSVImportResult['success'][] = sprintf($clang->gT("%s responses were updated."), count($aResponsesUpdated)); } if (count($aResponsesError)) { $CSVImportResult['errors'][] = sprintf($clang->gT("%s responses cannot be inserted or updated."), count($aResponsesError)); } if (count($aExistingsId) && ($aOptions['sExistingId'] == 'skip' || $aOptions['sExistingId'] == 'ignore')) { $CSVImportResult['warnings'][] = sprintf($clang->gT("%s responses already exist."), count($aExistingsId)); } return $CSVImportResult; }
/** * Gets a survey response from the database. * * @param int $surveyId * @param int $responseId */ public function getResponse($surveyId, $responseId) { $response = SurveyDynamic::model($surveyId)->findByPk($responseId)->attributes; // Now map the response to the question codes if possible, duplicate question codes will result in the // old sidXgidXqid code for the second time the code is found $fieldmap = createFieldMap($surveyId, 'full', null, false, $response['startlanguage']); $output = array(); foreach ($response as $key => $value) { $newKey = $key; if (array_key_exists($key, $fieldmap)) { if (array_key_exists('title', $fieldmap[$key])) { $code = $fieldmap[$key]['title']; // Add subquestion code if needed if (array_key_exists('aid', $fieldmap[$key]) && isset($fieldmap[$key]['aid']) && $fieldmap[$key]['aid'] != '') { $code .= '_' . $fieldmap[$key]['aid']; } // Only add if the code does not exist yet and is not empty if (!empty($code) && !array_key_exists($code, $output)) { $newKey = $code; } } } $output[$newKey] = $value; } // And return the mapped response, to further enhance we could add a method to the api that provides a // simple sort of fieldmap that returns qcode index array with group, question, subquestion, // possible answers, maybe even combined with relevance info so a plugin can handle display of the response return $output; }
/** * Make sure all active tables have the right sized token field * * During a small period in the 2.0 cycle some survey tables got no * token field or a token field that was too small. This patch makes * sure all surveys that are not anonymous have a token field with the * right size * * @return void */ function upgradeSurveyTables164() { $sQuery = "SELECT sid FROM {{surveys}} WHERE active='Y' and anonymized='N'"; $aResult = Yii::app()->getDb()->createCommand($sQuery)->queryAll(); if (!$aResult) { return "Database Error"; } else { foreach ($aResult as $sv) { $token = SurveyDynamic::model($sv['sid'])->getTableSchema()->getColumn('token'); if (is_null($token)) { addColumn('{{survey_' . $sv['sid'] . '}}', 'token', 'string(36)'); } elseif ($token->size < 36) { alterColumn('{{survey_' . $sv['sid'] . '}}', 'token', 'string(36)'); } } } }
/** * This function replaces keywords in a text and is mainly intended for templates * If you use this functions put your replacement strings into the $replacements variable * instead of using global variables * NOTE - Don't do any embedded replacements in this function. Create the array of replacement values and * they will be done in batch at the end * * @param mixed $line Text to search in * @param mixed $replacements Array of replacements: Array( <stringtosearch>=><stringtoreplacewith> * @param boolean $anonymized Determines if token data is being used or just replaced with blanks * @param questionNum - needed to support dynamic JavaScript-based tailoring within questions * @param bStaticReplacement - Default off, forces non-dynamic replacements without <SPAN> tags (e.g. for the Completed page) * @return string Text with replaced strings */ function templatereplace($line, $replacements = array(), &$redata = array(), $debugSrc = 'Unspecified', $anonymized = false, $questionNum = NULL, $registerdata = array(), $bStaticReplacement = false, $oTemplate = '') { /* global $clienttoken,$token,$sitename,$move,$showxquestions,$showqnumcode,$questioncode; global $s_lang,$errormsg,$saved_id, $languagechanger,$captchapath,$loadname; */ /* $allowedvars = array('surveylist', 'sitename', 'clienttoken', 'rooturl', 'thissurvey', 'imageurl', 'defaulttemplate', 'percentcomplete', 'move', 'groupname', 'groupdescription', 'question', 'showxquestions', 'showgroupinfo', 'showqnumcode', 'questioncode', 'answer', 'navigator', 'help', 'totalquestions', 'surveyformat', 'completed', 'notanswered', 'privacy', 'surveyid', 'publicurl', 'templatedir', 'token', 'assessments', 's_lang', 'errormsg', 'saved_id', 'usertemplaterootdir', 'languagechanger', 'printoutput', 'captchapath', 'loadname'); */ $allowedvars = array('assessments', 'captchapath', 'clienttoken', 'completed', 'errormsg', 'groupdescription', 'groupname', 'imageurl', 'languagechanger', 'loadname', 'move', 'navigator', 'moveprevbutton', 'movenextbutton', 'percentcomplete', 'privacy', 's_lang', 'saved_id', 'showgroupinfo', 'showqnumcode', 'showxquestions', 'sitename', 'sitelogo', 'surveylist', 'templatedir', 'thissurvey', 'token', 'totalBoilerplatequestions', 'totalquestions', 'questionindex', 'questionindexmenu'); $varsPassed = array(); foreach ($allowedvars as $var) { if (isset($redata[$var])) { ${$var} = $redata[$var]; $varsPassed[] = $var; } } // if (count($varsPassed) > 0) { // log_message('debug', 'templatereplace() called from ' . $debugSrc . ' contains: ' . implode(', ', $varsPassed)); // } // if (isset($redata['question'])) { // LimeExpressionManager::ShowStackTrace('has QID and/or SGA',$allowedvars); // } // extract($redata); // creates variables for each of the keys in the array // Local over-rides in case not set above if (!isset($showgroupinfo)) { $showgroupinfo = Yii::app()->getConfig('showgroupinfo'); } if (!isset($showqnumcode)) { $showqnumcode = Yii::app()->getConfig('showqnumcode'); } $_surveyid = Yii::app()->getConfig('surveyID'); if (!isset($showxquestions)) { $showxquestions = Yii::app()->getConfig('showxquestions'); } if (!isset($s_lang)) { $s_lang = isset(Yii::app()->session['survey_' . $_surveyid]['s_lang']) ? Yii::app()->session['survey_' . $_surveyid]['s_lang'] : 'en'; } if ($_surveyid && !isset($thissurvey)) { $thissurvey = getSurveyInfo($_surveyid, $s_lang); } if (!isset($captchapath)) { $captchapath = ''; } if (!isset($sitename)) { $sitename = Yii::app()->getConfig('sitename'); } if (!isset($saved_id) && isset(Yii::app()->session['survey_' . $_surveyid]['srid'])) { $saved_id = Yii::app()->session['survey_' . $_surveyid]['srid']; } Yii::app()->loadHelper('surveytranslator'); if (isset($thissurvey['sid'])) { $surveyid = $thissurvey['sid']; } // lets sanitize the survey template if (isset($thissurvey['templatedir'])) { $templatename = $thissurvey['templatedir']; } else { $templatename = Yii::app()->getConfig('defaulttemplate'); } if (!isset($templatedir)) { $templatedir = getTemplatePath($templatename); } if (!isset($templateurl)) { $templateurl = getTemplateURL($templatename) . "/"; } if (!$anonymized && isset($thissurvey['anonymized'])) { $anonymized = $thissurvey['anonymized'] == "Y"; } // TEMPLATECSS $_templatecss = ""; $_templatejs = ""; /** * Template css/js files from the template config files are loaded. * It use the asset manager (so user never need to empty the cache, even if template is updated) * If debug mode is on, no asset manager is used. * * oTemplate is defined in controller/survey/index * * If templatereplace is called from the template editor, a $oTemplate is provided. */ $oTemplate = Template::model()->getInstance($templatename); $aCssFiles = $oTemplate->config->files->css->filename; $aJsFiles = $oTemplate->config->files->js->filename; $aOtherFiles = $oTemplate->otherFiles; //var_dump($aOtherFiles); die(); if (stripos($line, "{TEMPLATECSS}")) { // If the template has files for css, we can't publish the files one by one, but we must publish them as a whole directory // TODO : extend asset manager so it check for file modification even in directory mode if (!YII_DEBUG || count($aOtherFiles) < 0) { foreach ($aCssFiles as $sCssFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $sCssFile)) { Yii::app()->getClientScript()->registerCssFile(App()->getAssetManager()->publish($oTemplate->path . DIRECTORY_SEPARATOR . $sCssFile), $sCssFile['media']); } } } else { foreach ($aCssFiles as $sCssFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $sCssFile)) { Yii::app()->getClientScript()->registerCssFile("{$templateurl}{$sCssFile}", $sCssFile['media']); } } } /* RTL CSS */ if (getLanguageRTL(App()->language)) { $aCssFiles = (array) $oTemplate->config->files->rtl->css->filename; if (!YII_DEBUG) { foreach ($aCssFiles as $sCssFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $sCssFile)) { Yii::app()->getClientScript()->registerCssFile(App()->getAssetManager()->publish($oTemplate->path . DIRECTORY_SEPARATOR . $sCssFile), $sCssFile['media']); } } } else { foreach ($aCssFiles as $sCssFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $sCssFile)) { Yii::app()->getClientScript()->registerCssFile("{$templateurl}{$sCssFile}", $sCssFile['media']); } } } } } if (stripos($line, "{TEMPLATEJS}")) { if (!YII_DEBUG) { foreach ($aJsFiles as $sJsFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $sJsFile)) { App()->getClientScript()->registerScriptFile(App()->getAssetManager()->publish($oTemplate->path . DIRECTORY_SEPARATOR . $sJsFile)); } } } else { foreach ($aJsFiles as $sJsFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $sJsFile)) { Yii::app()->getClientScript()->registerScriptFile("{$templateurl}{$sJsFile}"); } } } /* RTL JS */ if (getLanguageRTL(App()->language)) { $aJsFiles = (array) $oTemplate->config->files->rtl->js->filename; if (!YII_DEBUG) { foreach ($aJsFiles as $aJsFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $aJsFile)) { App()->getClientScript()->registerScriptFile(App()->getAssetManager()->publish($oTemplate->path . DIRECTORY_SEPARATOR . $aJsFile)); } } } else { foreach ($aJsFiles as $sJsFile) { if (file_exists($oTemplate->path . DIRECTORY_SEPARATOR . $sJsFile)) { Yii::app()->getClientScript()->registerScriptFile("{$templateurl}{$sJsFile}"); } } } } } // surveyformat if (isset($thissurvey['format'])) { $surveyformat = str_replace(array("A", "S", "G"), array("allinone", "questionbyquestion", "groupbygroup"), $thissurvey['format']); } else { $surveyformat = ""; } if ($oTemplate->config->engine->cssframework) { $surveyformat .= " " . $oTemplate->config->engine->cssframework . "-engine "; } if (isset(Yii::app()->session['step']) && Yii::app()->session['step'] % 2 && $surveyformat != "allinone") { $surveyformat .= " page-odd"; } if (isset($thissurvey['questionindex']) && $thissurvey['questionindex'] > 0 && $surveyformat != "allinone" && (isset(Yii::app()->session['step']) && Yii::app()->session['step'] > 0)) { $surveyformat .= " withindex"; } if (isset($thissurvey['showprogress']) && $thissurvey['showprogress'] == "Y") { $surveyformat .= " showprogress"; } if (isset($thissurvey['showqnumcode'])) { $surveyformat .= " showqnumcode-" . $thissurvey['showqnumcode']; } // real survey contact if (isset($surveylist) && isset($surveylist['contact'])) { $surveycontact = $surveylist['contact']; } elseif (isset($surveylist) && isset($thissurvey['admin']) && $thissurvey['admin'] != "") { $surveycontact = sprintf(gT("Please contact %s ( %s ) for further assistance."), $thissurvey['admin'], $thissurvey['adminemail']); } else { $surveycontact = ""; } // If there are non-bracketed replacements to be made do so above this line. // Only continue in this routine if there are bracketed items to replace {} if (strpos($line, "{") === false) { // process string anyway so that it can be pretty-printed return LimeExpressionManager::ProcessString($line, $questionNum, NULL, false, 1, 1, true); } if ($showgroupinfo == 'both' || $showgroupinfo == 'name' || $showgroupinfo == 'choose' && !isset($thissurvey['showgroupinfo']) || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'B' || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'N') { $_groupname = isset($groupname) ? $groupname : ''; } else { $_groupname = ''; } if ($showgroupinfo == 'both' || $showgroupinfo == 'description' || $showgroupinfo == 'choose' && !isset($thissurvey['showgroupinfo']) || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'B' || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'D') { $_groupdescription = isset($groupdescription) ? $groupdescription : ''; } else { $_groupdescription = ''; } if (!isset($totalquestions)) { $totalquestions = 0; } $_totalquestionsAsked = $totalquestions; if ($showxquestions == 'show' || $showxquestions == 'choose' && !isset($thissurvey['showxquestions']) || $showxquestions == 'choose' && $thissurvey['showxquestions'] == 'Y') { if ($_totalquestionsAsked < 1) { $_therearexquestions = gT("There are no questions in this survey"); // Singular } elseif ($_totalquestionsAsked == 1) { $_therearexquestions = gT("There is 1 question in this survey"); //Singular } else { $_therearexquestions = gT("There are {NUMBEROFQUESTIONS} questions in this survey."); //Note this line MUST be before {NUMBEROFQUESTIONS} } } else { $_therearexquestions = ''; } if (isset($token)) { $_token = $token; } elseif (isset($clienttoken)) { $_token = htmlentities($clienttoken, ENT_QUOTES, 'UTF-8'); // or should it be URL-encoded? } else { $_token = ''; } // Expiry if (isset($thissurvey['expiry'])) { $dateformatdetails = getDateFormatData($thissurvey['surveyls_dateformat']); Yii::import('application.libraries.Date_Time_Converter', true); $datetimeobj = new Date_Time_Converter($thissurvey['expiry'], "Y-m-d"); $_dateoutput = $datetimeobj->convert($dateformatdetails['phpdate']); } else { $_dateoutput = '-'; } $_submitbutton = "<input class='submit btn btn-default' type='submit' value=' " . gT("Submit") . " ' name='move2' onclick=\"javascript:document.limesurvey.move.value = 'movesubmit';\" />"; if (isset($thissurvey['surveyls_url']) and $thissurvey['surveyls_url'] != "") { if (trim($thissurvey['surveyls_urldescription']) != '') { $_linkreplace = "<a href='{$thissurvey['surveyls_url']}'>{$thissurvey['surveyls_urldescription']}</a>"; } else { $_linkreplace = "<a href='{$thissurvey['surveyls_url']}'>{$thissurvey['surveyls_url']}</a>"; } } else { $_linkreplace = ''; } if (isset($thissurvey['sid']) && isset($_SESSION['survey_' . $thissurvey['sid']]['srid']) && $thissurvey['active'] == 'Y') { $iscompleted = SurveyDynamic::model($surveyid)->isCompleted($_SESSION['survey_' . $thissurvey['sid']]['srid']); } else { $iscompleted = false; } if (isset($surveyid) && !$iscompleted) { $_clearall = CHtml::htmlButton(gT("Exit and clear survey"), array('type' => 'submit', 'id' => "clearall", 'value' => 'clearall', 'name' => 'clearall', 'class' => 'clearall button btn btn-default btn-lg col-xs-4 hidden', 'data-confirmedby' => 'confirm-clearall', 'title' => gT("This action need confirmation."))); $_clearall .= CHtml::checkBox("confirm-clearall", false, array('id' => 'confirm-clearall', 'value' => 'confirm', 'class' => 'hide jshide btn btn-default btn-lg col-xs-4')); $_clearall .= CHtml::label(gT("Are you sure you want to clear all your responses?"), 'confirm-clearall', array('class' => 'hide jshide btn btn-default btn-lg col-xs-4')); $_clearalllinks = '<li><a href="#" id="clearallbtnlink">' . gT("Exit and clear survey") . '</a></li>'; } else { $_clearall = ""; $_clearalllinks = ''; } if (isset(Yii::app()->session['datestamp'])) { $_datestamp = Yii::app()->session['datestamp']; } else { $_datestamp = '-'; } if (isset($thissurvey['allowsave']) and $thissurvey['allowsave'] == "Y") { $_saveall = doHtmlSaveAll(isset($move) ? $move : NULL); $_savelinks = doHtmlSaveLinks(isset($move) ? $move : NULL); } else { $_saveall = ""; $_savelinks = ""; } if (isset($thissurvey['allowprev']) && $thissurvey['allowprev'] == "N") { $_strreview = ""; } else { $_strreview = gT("If you want to check any of the answers you have made, and/or change them, you can do that now by clicking on the [<< prev] button and browsing through your responses."); } if (isset($surveyid)) { $restartparam = array(); if ($_token) { $restartparam['token'] = sanitize_token($_token); } // urlencode with needed with sanitize_token if (Yii::app()->request->getQuery('lang')) { $restartparam['lang'] = sanitize_languagecode(Yii::app()->request->getQuery('lang')); } elseif ($s_lang) { $restartparam['lang'] = $s_lang; } $restartparam['newtest'] = "Y"; $restarturl = Yii::app()->getController()->createUrl("survey/index/sid/{$surveyid}", $restartparam); $_restart = "<a href='{$restarturl}'>" . gT("Restart this Survey") . "</a>"; } else { $_restart = ""; } if (isset($thissurvey['anonymized']) && $thissurvey['anonymized'] == 'Y') { $_savealert = gT("To remain anonymous please use a pseudonym as your username, also an email address is not required."); } else { $_savealert = ""; } if (isset($surveyid)) { if ($_token) { $returnlink = Yii::app()->getController()->createUrl("survey/index/sid/{$surveyid}", array('token' => Token::sanitizeToken($_token))); } else { $returnlink = Yii::app()->getController()->createUrl("survey/index/sid/{$surveyid}"); } $_return_to_survey = "<a href='{$returnlink}'>" . gT("Return to survey") . "</a>"; } else { $_return_to_survey = ""; } // Save Form $_saveform = "<table class='save-survey-form'><tr class='save-survey-row save-survey-name'><td class='save-survey-label label-cell' align='right'><label for='savename'>" . gT("Name") . "</label>:</td><td class='save-survey-input input-cell'><input type='text' name='savename' id='savename' value='"; if (isset($_POST['savename'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['savename'])); } $_saveform .= "' /></td></tr>\n" . "<tr class='save-survey-row save-survey-password-1'><td class='save-survey-label label-cell' align='right'><label for='savepass'>" . gT("Password") . "</label>:</td><td class='save-survey-input input-cell'><input type='password' id='savepass' name='savepass' value='"; if (isset($_POST['savepass'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['savepass'])); } $_saveform .= "' /></td></tr>\n" . "<tr class='save-survey-row save-survey-password-2'><td class='save-survey-label label-cell' align='right'><label for='savepass2'>" . gT("Repeat password") . "</label>:</td><td class='save-survey-input input-cell'><input type='password' id='savepass2' name='savepass2' value='"; if (isset($_POST['savepass2'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['savepass2'])); } $_saveform .= "' /></td></tr>\n" . "<tr class='save-survey-row save-survey-email'><td class='save-survey-label label-cell' align='right'><label for='saveemail'>" . gT("Your email address") . "</label>:</td><td class='save-survey-input input-cell'><input type='text' id='saveemail' name='saveemail' value='"; if (isset($_POST['saveemail'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['saveemail'])); } $_saveform .= "' /></td></tr>\n"; if (isset($thissurvey['usecaptcha']) && function_exists("ImageCreate") && isCaptchaEnabled('saveandloadscreen', $thissurvey['usecaptcha'])) { $_saveform .= "<tr class='save-survey-row save-survey-captcha'><td class='save-survey-label label-cell' align='right'><label for='loadsecurity'>" . gT("Security question") . "</label>:</td><td class='save-survey-input input-cell'><table class='captcha-table'><tr><td class='captcha-image' valign='middle'><img alt='' src='" . Yii::app()->getController()->createUrl('/verification/image/sid/' . (isset($surveyid) ? $surveyid : '')) . "' /></td><td class='captcha-input' valign='middle' style='text-align:left'><input type='text' size='5' maxlength='3' id='loadsecurity' name='loadsecurity' value='' /></td></tr></table></td></tr>\n"; } $_saveform .= "<tr><td align='right'></td><td></td></tr>\n" . "<tr class='save-survey-row save-survey-submit'><td class='save-survey-label label-cell'><label class='hide jshide' for='savebutton'>" . gT("Save Now") . "</label></td><td class='save-survey-input input-cell'><input type='submit' id='savebutton' name='savesubmit' class='button' value='" . gT("Save Now") . "' /></td></tr>\n" . "</table>"; // Load Form $_loadform = "<table class='load-survey-form'><tr class='load-survey-row load-survey-name'><td class='load-survey-label label-cell' align='right'><label for='loadname'>" . gT("Saved name") . "</label>:</td><td class='load-survey-input input-cell'><input type='text' id='loadname' name='loadname' value='"; if (isset($loadname)) { $_loadform .= HTMLEscape(autoUnescape($loadname)); } $_loadform .= "' /></td></tr>\n" . "<tr class='load-survey-row load-survey-password'><td class='load-survey-label label-cell' align='right'><label for='loadpass'>" . gT("Password") . "</label>:</td><td class='load-survey-input input-cell'><input type='password' id='loadpass' name='loadpass' value='"; if (isset($loadpass)) { $_loadform .= HTMLEscape(autoUnescape($loadpass)); } $_loadform .= "' /></td></tr>\n"; if (isset($thissurvey['usecaptcha']) && function_exists("ImageCreate") && isCaptchaEnabled('saveandloadscreen', $thissurvey['usecaptcha'])) { $_loadform .= "<tr class='load-survey-row load-survey-captcha'><td class='load-survey-label label-cell' align='right'><label for='loadsecurity'>" . gT("Security question") . "</label>:</td><td class='load-survey-input input-cell'><table class='captcha-table'><tr><td class='captcha-image' valign='middle'><img src='" . Yii::app()->getController()->createUrl('/verification/image/sid/' . (isset($surveyid) ? $surveyid : '')) . "' alt='' /></td><td class='captcha-input' valign='middle'><input type='text' size='5' maxlength='3' id='loadsecurity' name='loadsecurity' value='' alt=''/></td></tr></table></td></tr>\n"; } $_loadform .= "<tr class='load-survey-row load-survey-submit'><td class='load-survey-label label-cell'><label class='hide jshide' for='loadbutton'>" . gT("Load now") . "</label></td><td class='load-survey-input input-cell'><input type='submit' id='loadbutton' class='button' value='" . gT("Load now") . "' /></td></tr></table>\n"; // Assessments $assessmenthtml = ""; if (isset($surveyid) && !is_null($surveyid) && function_exists('doAssessment')) { $assessmentdata = doAssessment($surveyid, true); $_assessment_current_total = $assessmentdata['total']; if (stripos($line, "{ASSESSMENTS}")) { $assessmenthtml = doAssessment($surveyid, false); } } else { $_assessment_current_total = ''; } if (isset($thissurvey['googleanalyticsapikey']) && trim($thissurvey['googleanalyticsapikey']) != '') { $_googleAnalyticsAPIKey = trim($thissurvey['googleanalyticsapikey']); } else { $_googleAnalyticsAPIKey = trim(getGlobalSetting('googleanalyticsapikey')); } $_googleAnalyticsStyle = isset($thissurvey['googleanalyticsstyle']) ? $thissurvey['googleanalyticsstyle'] : '0'; $_googleAnalyticsJavaScript = ''; if ($_googleAnalyticsStyle != '' && $_googleAnalyticsStyle != 0 && $_googleAnalyticsAPIKey != '') { switch ($_googleAnalyticsStyle) { case '1': // Default Google Tracking $_googleAnalyticsJavaScript = <<<EOD <script> (function(i,s,o,g,r,a,m){ i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments) },i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', '{$_googleAnalyticsAPIKey}', 'auto'); // Replace with your property ID. ga('send', 'pageview'); </script> EOD; break; case '2': // SurveyName-[SID]/[GSEQ]-GroupName - create custom GSEQ based upon page step $moveInfo = LimeExpressionManager::GetLastMoveResult(); if (is_null($moveInfo)) { $gseq = 'welcome'; } else { if ($moveInfo['finished']) { $gseq = 'finished'; } else { if (isset($moveInfo['at_start']) && $moveInfo['at_start']) { $gseq = 'welcome'; } else { if (is_null($_groupname)) { $gseq = 'printanswers'; } else { $gseq = $moveInfo['gseq'] + 1; } } } } $_trackURL = htmlspecialchars($thissurvey['name'] . '-[' . $surveyid . ']/[' . $gseq . ']-' . $_groupname); $_googleAnalyticsJavaScript = <<<EOD <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', '{$_googleAnalyticsAPIKey}', 'auto'); // Replace with your property ID. ga('send', 'pageview'); ga('send', 'pageview', '{$_trackURL}'); </script> EOD; break; } } $_endtext = ''; if (isset($thissurvey['surveyls_endtext']) && trim($thissurvey['surveyls_endtext']) != '') { $_endtext = $thissurvey['surveyls_endtext']; } $sitelogo = !empty($oTemplate->siteLogo) ? '<img src="' . App()->getAssetManager()->publish($oTemplate->path . '/' . $oTemplate->siteLogo) . '"/>' : ''; // Set the array of replacement variables here - don't include curly braces $coreReplacements = array(); $coreReplacements['ACTIVE'] = isset($thissurvey['active']) && !($thissurvey['active'] != "Y"); $coreReplacements['ANSWERSCLEARED'] = gT("Answers cleared"); $coreReplacements['ASSESSMENTS'] = $assessmenthtml; $coreReplacements['ASSESSMENT_CURRENT_TOTAL'] = $_assessment_current_total; $coreReplacements['ASSESSMENT_HEADING'] = gT("Your assessment"); $coreReplacements['CHECKJAVASCRIPT'] = "<noscript><span class='warningjs'>" . gT("Caution: JavaScript execution is disabled in your browser. You may not be able to answer all questions in this survey. Please, verify your browser parameters.") . "</span></noscript>"; $coreReplacements['CLEARALL'] = $_clearall; $coreReplacements['CLEARALL_LINKS'] = $_clearalllinks; $coreReplacements['CLOSEWINDOW'] = ''; // Obsolete tag - keep this line for compatibility reaons $coreReplacements['COMPLETED'] = isset($redata['completed']) ? $redata['completed'] : ''; // global $coreReplacements['DATESTAMP'] = $_datestamp; $coreReplacements['ENDTEXT'] = $_endtext; $coreReplacements['EXPIRY'] = $_dateoutput; $coreReplacements['ADMINNAME'] = isset($thissurvey['admin']) ? $thissurvey['admin'] : ''; $coreReplacements['ADMINEMAIL'] = isset($thissurvey['adminemail']) ? $thissurvey['adminemail'] : ''; $coreReplacements['GID'] = Yii::app()->getConfig('gid', ''); // Use the gid of the question, except if we are not in question (Randomization group name) $coreReplacements['GOOGLE_ANALYTICS_API_KEY'] = $_googleAnalyticsAPIKey; $coreReplacements['GOOGLE_ANALYTICS_JAVASCRIPT'] = $_googleAnalyticsJavaScript; $coreReplacements['GROUPDESCRIPTION'] = $_groupdescription; $coreReplacements['GROUPNAME'] = $_groupname; $coreReplacements['LANG'] = App()->language; $coreReplacements['LANGUAGECHANGER'] = isset($languagechanger) ? $languagechanger : ''; // global $coreReplacements['LOADERROR'] = isset($errormsg) ? $errormsg : ''; // global $coreReplacements['LOADFORM'] = $_loadform; $coreReplacements['LOADHEADING'] = gT("Load a previously saved survey"); $coreReplacements['LOADMESSAGE'] = gT("You can load a survey that you have previously saved from this screen.") . "<br />" . gT("Type in the 'name' you used to save the survey, and the password.") . "<br />"; $coreReplacements['NAVIGATOR'] = isset($navigator) ? $navigator : ''; // global $coreReplacements['MOVEPREVBUTTON'] = isset($moveprevbutton) ? $moveprevbutton : ''; // global $coreReplacements['MOVENEXTBUTTON'] = isset($movenextbutton) ? $movenextbutton : ''; // global $coreReplacements['NOSURVEYID'] = isset($surveylist) ? $surveylist['nosid'] : ''; $coreReplacements['NUMBEROFQUESTIONS'] = $_totalquestionsAsked; $coreReplacements['PERCENTCOMPLETE'] = isset($percentcomplete) ? $percentcomplete : ''; // global $coreReplacements['PRIVACY'] = isset($privacy) ? $privacy : ''; // global $coreReplacements['PRIVACYMESSAGE'] = "<span style='font-weight:bold; font-style: italic;'>" . gT("A Note On Privacy") . "</span><br />" . gT("This survey is anonymous.") . "<br />" . gT("The record of your survey responses does not contain any identifying information about you, unless a specific survey question explicitly asked for it.") . ' ' . gT("If you used an identifying token to access this survey, please rest assured that this token will not be stored together with your responses. It is managed in a separate database and will only be updated to indicate whether you did (or did not) complete this survey. There is no way of matching identification tokens with survey responses."); $coreReplacements['QUESTION_INDEX'] = isset($questionindex) ? $questionindex : ''; $coreReplacements['QUESTION_INDEX_MENU'] = isset($questionindexmenu) ? $questionindexmenu : ''; $coreReplacements['RESTART'] = $_restart; $coreReplacements['RETURNTOSURVEY'] = $_return_to_survey; $coreReplacements['SAVE_LINKS'] = $_savelinks; $coreReplacements['SAVE'] = $_saveall; $coreReplacements['SAVEALERT'] = $_savealert; $coreReplacements['SAVEDID'] = isset($saved_id) ? $saved_id : ''; // global $coreReplacements['SAVEERROR'] = isset($errormsg) ? $errormsg : ''; // global - same as LOADERROR $coreReplacements['SAVEFORM'] = $_saveform; $coreReplacements['SAVEHEADING'] = gT("Save your unfinished survey"); $coreReplacements['SAVEMESSAGE'] = gT("Enter a name and password for this survey and click save below.") . "<br />\n" . gT("Your survey will be saved using that name and password, and can be completed later by logging in with the same name and password.") . "<br /><br />\n<span class='emailoptional'>" . gT("If you give an email address, an email containing the details will be sent to you.") . "</span><br /><br />\n" . gT("After having clicked the save button you can either close this browser window or continue filling out the survey."); $coreReplacements['SID'] = Yii::app()->getConfig('surveyID', ''); // Allways use surveyID from config $coreReplacements['SITENAME'] = isset($sitename) ? $sitename : ''; // global $coreReplacements['SITELOGO'] = $sitelogo; $coreReplacements['SUBMITBUTTON'] = $_submitbutton; $coreReplacements['SUBMITCOMPLETE'] = "<strong>" . gT("Thank you!") . "<br /><br />" . gT("You have completed answering the questions in this survey.") . "</strong><br /><br />" . gT("Click on 'Submit' now to complete the process and save your answers."); $coreReplacements['SUBMITREVIEW'] = $_strreview; $coreReplacements['SURVEYCONTACT'] = $surveycontact; $coreReplacements['SURVEYDESCRIPTION'] = isset($thissurvey['description']) ? $thissurvey['description'] : ''; $coreReplacements['SURVEYFORMAT'] = isset($surveyformat) ? $surveyformat : ''; // global $coreReplacements['SURVEYLANGUAGE'] = App()->language; $coreReplacements['SURVEYLIST'] = isset($surveylist) ? $surveylist['list'] : ''; $coreReplacements['SURVEYLISTHEADING'] = isset($surveylist) ? $surveylist['listheading'] : ''; $coreReplacements['SURVEYNAME'] = isset($thissurvey['name']) ? $thissurvey['name'] : ''; $coreReplacements['SURVEYRESOURCESURL'] = isset($thissurvey['sid']) ? Yii::app()->getConfig("uploadurl") . '/surveys/' . $thissurvey['sid'] . '/' : ''; $coreReplacements['TEMPLATECSS'] = $_templatecss; $coreReplacements['TEMPLATEJS'] = $_templatejs; $coreReplacements['TEMPLATEURL'] = $templateurl; $coreReplacements['THEREAREXQUESTIONS'] = $_therearexquestions; $coreReplacements['TOKEN'] = !$anonymized ? $_token : ''; // Silently replace TOKEN by empty string $coreReplacements['URL'] = $_linkreplace; $coreReplacements['WELCOME'] = isset($thissurvey['welcome']) ? $thissurvey['welcome'] : ''; if (!isset($replacements['QID'])) { Yii::import('application.helpers.SurveyRuntimeHelper'); $coreReplacements = array_merge($coreReplacements, SurveyRuntimeHelper::getQuestionReplacement(null)); // so $replacements overrides core values } if (!is_null($replacements) && is_array($replacements)) { $doTheseReplacements = array_merge($coreReplacements, $replacements); // so $replacements overrides core values } else { $doTheseReplacements = $coreReplacements; } // Now do all of the replacements - In rare cases, need to do 3 deep recursion, that that is default $line = LimeExpressionManager::ProcessString($line, $questionNum, $doTheseReplacements, false, 3, 1, false, true, $bStaticReplacement); return $line; }
/** * Gets the response for the current response id. * @return type */ public function getResponse() { if (isset($this->responseId)) { $surveyId = Question::model()->findFieldByPk($this->questionId, 'sid'); $response = SurveyDynamic::model($surveyId)->findByPk($this->responseId); $columns = $this->getColumns(); foreach ($columns as &$column) { if (isset($response->{$column})) { $column['response'] = $response->{$column}; } } return $columns; } }
/** * Returns surveys in json format * * @access public * @return void */ public function getSurveys_json() { $this->getController()->loadHelper('surveytranslator'); $dateformatdetails = getDateFormatData(Yii::app()->session['dateformat']); $oSurvey = new Survey(); $oSurvey->permission(Yii::app()->user->getId()); $aSurveys = $oSurvey->with(array('languagesettings' => array('condition' => 'surveyls_language=language'), 'owner'))->findAll(); $aSurveyEntries = new stdClass(); $aSurveyEntries->page = 1; foreach ($aSurveys as $rows) { if (!isset($rows->owner->attributes)) { $aOwner = array('users_name' => gT('(None)')); } else { $aOwner = $rows->owner->attributes; } $rows = array_merge($rows->attributes, $rows->defaultlanguage->attributes, $aOwner); $aSurveyEntry = array(); // Set status if ($rows['active'] == "Y" && $rows['expires'] != '' && $rows['expires'] < dateShift(date("Y-m-d H:i:s"), "Y-m-d", Yii::app()->getConfig('timeadjust'))) { $aSurveyEntry[] = '<!--a--><img src="' . Yii::app()->getConfig('adminimageurl') . 'expired.png" alt="' . gT("This survey is active but expired.") . '" />'; } elseif ($rows['active'] == "Y" && $rows['startdate'] != '' && $rows['startdate'] > dateShift(date("Y-m-d H:i:s"), "Y-m-d", Yii::app()->getConfig('timeadjust'))) { $aSurveyEntry[] = '<!--b--><img src="' . Yii::app()->getConfig('adminimageurl') . 'notyetstarted.png" alt="' . gT("This survey is active but has a start date.") . '" />'; } elseif ($rows['active'] == "Y") { if (Permission::model()->hasSurveyPermission($rows['sid'], 'surveyactivation', 'update')) { $aSurveyEntry[] = '<!--c--><a href="' . $this->getController()->createUrl('admin/survey/sa/deactivate/surveyid/' . $rows['sid']) . '"><img src="' . Yii::app()->getConfig('adminimageurl') . 'active.png" alt="' . gT("This survey is active - click here to stop this survey.") . '"/></a>'; } else { $aSurveyEntry[] = '<!--d--><img src="' . Yii::app()->getConfig('adminimageurl') . 'active.png" alt="' . gT("This survey is currently active.") . '" />'; } } else { $condition = "sid={$rows['sid']} AND language='" . $rows['language'] . "'"; $questionsCountResult = Question::model()->count($condition); if ($questionsCountResult > 0 && Permission::model()->hasSurveyPermission($rows['sid'], 'surveyactivation', 'update')) { $aSurveyEntry[] = '<!--e--><a href="' . $this->getController()->createUrl('admin/survey/sa/activate/surveyid/' . $rows['sid']) . '"><img src="' . Yii::app()->getConfig('adminimageurl') . 'inactive.png" title="" alt="' . gT("This survey is currently not active - click here to activate this survey.") . '" /></a>'; } else { $aSurveyEntry[] = '<!--f--><img src="' . Yii::app()->getConfig('adminimageurl') . 'inactive.png" title="' . gT("This survey is currently not active.") . '" alt="' . gT("This survey is currently not active.") . '" />'; } } //Set SID $aSurveyEntry[] = $rows['sid']; '<a href="' . $this->getController()->createUrl("/admin/survey/sa/view/surveyid/" . $rows['sid']) . '">' . $rows['sid'] . '</a>'; //Set Title $aSurveyEntry[] = '<a href="' . $this->getController()->createUrl("/admin/survey/sa/view/surveyid/" . $rows['sid']) . '">' . CHtml::encode($rows['surveyls_title']) . '</a>'; //Set Date Yii::import('application.libraries.Date_Time_Converter', true); $datetimeobj = new Date_Time_Converter($rows['datecreated'], "Y-m-d H:i:s"); $aSurveyEntry[] = '<!--' . $rows['datecreated'] . '-->' . $datetimeobj->convert($dateformatdetails['phpdate']); //Set Owner if (Permission::model()->hasGlobalPermission('superadmin', 'read') || Yii::app()->session['loginID'] == $rows['owner_id']) { $aSurveyEntry[] = $rows['users_name'] . ' (<a class="ownername_edit" translate_to="' . gT('Edit') . '" id="ownername_edit_' . $rows['sid'] . '">' . gT('Edit') . '</a>)'; } else { $aSurveyEntry[] = $rows['users_name']; } //Set Access if (tableExists('tokens_' . $rows['sid'])) { $aSurveyEntry[] = gT("Closed"); } else { $aSurveyEntry[] = gT("Open"); } //Set Anonymous if ($rows['anonymized'] == "Y") { $aSurveyEntry[] = gT("Yes"); } else { $aSurveyEntry[] = gT("No"); } //Set Responses if ($rows['active'] == "Y") { $cntResult = SurveyDynamic::countAllAndPartial($rows['sid']); $all = $cntResult['cntall']; $partial = $cntResult['cntpartial']; $aSurveyEntry[] = $all - $partial; $aSurveyEntry[] = $partial; $aSurveyEntry[] = $all; $aSurveyEntry['viewurl'] = $this->getController()->createUrl("/admin/survey/sa/view/surveyid/" . $rows['sid']); if (tableExists('tokens_' . $rows['sid'])) { $summary = Token::model($rows['sid'])->summary(); $tokens = $summary['count']; $tokenscompleted = $summary['completed']; $aSurveyEntry[] = $tokens; $aSurveyEntry[] = $tokens == 0 ? 0 : round($tokenscompleted / $tokens * 100, 1) . ' %'; } else { $aSurveyEntry[] = $aSurveyEntry[] = ''; } } else { $aSurveyEntry[] = $aSurveyEntry[] = $aSurveyEntry[] = $aSurveyEntry[] = $aSurveyEntry[] = ''; } $aSurveyEntries->rows[] = array('id' => $rows['sid'], 'cell' => $aSurveyEntry); } header('Content-type: application/json'); echo ls_json_encode($aSurveyEntries); }
/** * Creates an array with details on a particular response for display purposes * Used in Print answers, Detailed response view and Detailed admin notification email * * @param mixed $iSurveyID * @param mixed $iResponseID * @param mixed $sLanguageCode * @param boolean $bHonorConditions Apply conditions */ function getFullResponseTable($iSurveyID, $iResponseID, $sLanguageCode, $bHonorConditions = true) { $aFieldMap = createFieldMap($iSurveyID, 'full', false, false, $sLanguageCode); //Get response data $idrow = SurveyDynamic::model($iSurveyID)->findByAttributes(array('id' => $iResponseID)); // Create array of non-null values - those are the relevant ones $aRelevantFields = array(); foreach ($aFieldMap as $sKey => $fname) { if (LimeExpressionManager::QuestionIsRelevant($fname['qid']) || $bHonorConditions == false) { $aRelevantFields[$sKey] = $fname; } } $aResultTable = array(); $oldgid = 0; $oldqid = 0; foreach ($aRelevantFields as $sKey => $fname) { if (!empty($fname['qid'])) { $attributes = getQuestionAttributeValues($fname['qid']); if (getQuestionAttributeValue($attributes, 'hidden') == 1) { continue; } } $question = $fname['question']; $subquestion = ''; if (isset($fname['gid']) && !empty($fname['gid'])) { //Check to see if gid is the same as before. if not show group name if ($oldgid !== $fname['gid']) { $oldgid = $fname['gid']; if (LimeExpressionManager::GroupIsRelevant($fname['gid']) || $bHonorConditions == false) { $aResultTable['gid_' . $fname['gid']] = array($fname['group_name'], QuestionGroup::model()->getGroupDescription($fname['gid'], $sLanguageCode)); } } } if (!empty($fname['qid'])) { if ($oldqid !== $fname['qid']) { $oldqid = $fname['qid']; if (isset($fname['subquestion']) || isset($fname['subquestion1']) || isset($fname['subquestion2'])) { $aResultTable['qid_' . $fname['sid'] . 'X' . $fname['gid'] . 'X' . $fname['qid']] = array($fname['question'], '', ''); } else { $answer = getExtendedAnswer($iSurveyID, $fname['fieldname'], $idrow[$fname['fieldname']], $sLanguageCode); $aResultTable[$fname['fieldname']] = array($question, '', $answer); continue; } } } else { $answer = getExtendedAnswer($iSurveyID, $fname['fieldname'], $idrow[$fname['fieldname']], $sLanguageCode); $aResultTable[$fname['fieldname']] = array($question, '', $answer); continue; } if (isset($fname['subquestion'])) { $subquestion = "[{$fname['subquestion']}]"; } if (isset($fname['subquestion1'])) { $subquestion = "[{$fname['subquestion1']}]"; } if (isset($fname['subquestion2'])) { $subquestion .= "[{$fname['subquestion2']}]"; } $answer = getExtendedAnswer($iSurveyID, $fname['fieldname'], $idrow[$fname['fieldname']], $sLanguageCode); $aResultTable[$fname['fieldname']] = array($question, $subquestion, $answer); } return $aResultTable; }
/** * Deletes some records from survey's table * according to specific condition * * @static * @access public * @param array $condition * @return int */ public static function deleteSomeRecords($condition = FALSE) { $survey = new SurveyDynamic(); $criteria = new CDbCriteria(); if ($condition != FALSE) { foreach ($condition as $column => $value) { return $criteria->addCondition($column . "=`" . $value . "`"); } } return $survey->deleteAll($criteria); }
/** * Write values to database. * @param <type> $updatedValues * @param <boolean> $finished - true if the survey needs to be finalized */ private function _UpdateValuesInDatabase($updatedValues, $finished = false) { // TODO - now that using $this->updatedValues, may be able to remove local copies of it (unless needed by other sub-systems) $updatedValues = $this->updatedValues; $message = ''; if (!$this->surveyOptions['active'] || $this->sPreviewMode) { return $message; } if (!isset($_SESSION[$this->sessid]['srid'])) { $_SESSION[$this->sessid]['datestamp'] = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $this->surveyOptions['timeadjust']); // Create initial insert row for this record $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $this->surveyOptions['timeadjust']); $sdata = array("startlanguage" => $this->surveyOptions['startlanguage']); if ($this->surveyOptions['anonymized'] == false) { $sdata['token'] = $this->surveyOptions['token']; } if ($this->surveyOptions['datestamp'] == true) { $sdata['datestamp'] = $_SESSION[$this->sessid]['datestamp']; $sdata['startdate'] = $_SESSION[$this->sessid]['datestamp']; } if ($this->surveyOptions['ipaddr'] == true) { $sdata['ipaddr'] = getIPAddress(); } if ($this->surveyOptions['refurl'] == true) { if (isset($_SESSION[$this->sessid]['refurl'])) { $sdata['refurl'] = $_SESSION[$this->sessid]['refurl']; } else { $sdata['refurl'] = getenv("HTTP_REFERER"); } } $sdata = array_filter($sdata); SurveyDynamic::sid($this->sid); $oSurvey = new SurveyDynamic(); $iNewID = $oSurvey->insertRecords($sdata); if ($iNewID) { $srid = $iNewID; $_SESSION[$this->sessid]['srid'] = $iNewID; } else { $message .= $this->gT("Unable to insert record into survey table"); // TODO - add SQL error? echo submitfailed(''); // TODO - report SQL error? } //Insert Row for Timings, if needed if ($this->surveyOptions['savetimings']) { SurveyTimingDynamic::sid($this->sid); $oSurveyTimings = new SurveyTimingDynamic(); $tdata = array('id' => $srid, 'interviewtime' => 0); switchMSSQLIdentityInsert("survey_{$this->sid}_timings", true); $iNewID = $oSurveyTimings->insertRecords($tdata); switchMSSQLIdentityInsert("survey_{$this->sid}_timings", false); } } if (count($updatedValues) > 0 || $finished) { $query = 'UPDATE ' . $this->surveyOptions['tablename'] . ' SET '; $setter = array(); switch ($this->surveyMode) { case 'question': $thisstep = $this->currentQuestionSeq; break; case 'group': $thisstep = $this->currentGroupSeq; break; case 'survey': $thisstep = 1; break; } $setter[] = dbQuoteID('lastpage') . "=" . dbQuoteAll($thisstep); if ($this->surveyOptions['datestamp'] && isset($_SESSION[$this->sessid]['datestamp'])) { $_SESSION[$this->sessid]['datestamp'] = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $this->surveyOptions['timeadjust']); $setter[] = dbQuoteID('datestamp') . "=" . dbQuoteAll(dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $this->surveyOptions['timeadjust'])); } if ($this->surveyOptions['ipaddr']) { $setter[] = dbQuoteID('ipaddr') . "=" . dbQuoteAll(getIPAddress()); } foreach ($updatedValues as $key => $value) { $val = is_null($value) ? NULL : $value['value']; $type = is_null($value) ? NULL : $value['type']; // Clean up the values to cope with database storage requirements switch ($type) { case 'D': //DATE if (trim($val) == '' || $val == "INVALID") { $val = NULL; // since some databases can't store blanks in date fields } // otherwise will already be in yyyy-mm-dd format after ProcessCurrentResponses() break; case '|': //File upload // This block can be removed once we require 5.3 or later if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { $val = addslashes($val); } break; case 'N': //NUMERICAL QUESTION TYPE //NUMERICAL QUESTION TYPE case 'K': //MULTIPLE NUMERICAL QUESTION if (trim($val) == '') { $val = NULL; // since some databases can't store blanks in numerical inputs } break; default: break; } if (is_null($val)) { $setter[] = dbQuoteID($key) . "=NULL"; } else { $setter[] = dbQuoteID($key) . "=" . dbQuoteAll($val); } } $query .= implode(', ', $setter); $query .= " WHERE ID="; if (isset($_SESSION[$this->sessid]['srid']) && $this->surveyOptions['active']) { $query .= $_SESSION[$this->sessid]['srid']; if (!dbExecuteAssoc($query)) { echo submitfailed(''); // TODO - report SQL error? if (($this->debugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY) { $message .= $this->gT('Error in SQL update'); // TODO - add SQL error? } } elseif ($this->surveyOptions['savetimings']) { Yii::import("application.libraries.Save"); $cSave = new Save(); $cSave->set_answer_time(); } if ($finished) { // Delete the save control record if successfully finalize the submission $query = "DELETE FROM {{saved_control}} where srid=" . $_SESSION[$this->sessid]['srid'] . ' and sid=' . $this->sid; Yii::app()->db->createCommand($query)->execute(); if (($this->debugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY) { $message .= ';<br />' . $query; } } else { if ($this->surveyOptions['allowsave'] && isset($_SESSION[$this->sessid]['scid'])) { SavedControl::model()->updateByPk($_SESSION[$this->sessid]['scid'], array('saved_thisstep' => $thisstep)); } } // Check Quotas $aQuotas = checkCompletedQuota($this->sid, 'return'); if ($aQuotas && !empty($aQuotas)) { checkCompletedQuota($this->sid); // will create a page and quit: why not use it directly ? } else { if ($finished) { $sQuery = 'UPDATE ' . $this->surveyOptions['tablename'] . " SET "; if ($this->surveyOptions['datestamp']) { // Replace with date("Y-m-d H:i:s") ? See timeadjust $sQuery .= dbQuoteID('submitdate') . "=" . dbQuoteAll(dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $this->surveyOptions['timeadjust'])); } else { $sQuery .= dbQuoteID('submitdate') . "=" . dbQuoteAll(date("Y-m-d H:i:s", mktime(0, 0, 0, 1, 1, 1980))); } $sQuery .= " WHERE ID=" . $_SESSION[$this->sessid]['srid']; dbExecuteAssoc($sQuery); // Checked } } } if (($this->debugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY) { $message .= $query; } } return $message; }
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; }
function savedcontrol() { //This data will be saved to the "saved_control" table with one row per response. // - a unique "saved_id" value (autoincremented) // - the "sid" for this survey // - the "srid" for the survey_x row id // - "saved_thisstep" which is the step the user is up to in this survey // - "saved_ip" which is the ip address of the submitter // - "saved_date" which is the date ofthe saved response // - an "identifier" which is like a username // - a "password" // - "fieldname" which is the fieldname of the saved response // - "value" which is the value of the response //We start by generating the first 5 values which are consistent for all rows. global $surveyid, $thissurvey, $errormsg, $publicurl, $sitename, $clang, $clienttoken, $thisstep; $timeadjust = getGlobalSetting('timeadjust'); //Check that the required fields have been completed. $errormsg = ''; if (empty($_POST['savename'])) { $errormsg .= $clang->gT("You must supply a name for this saved session.") . "<br />\n"; } if (empty($_POST['savepass'])) { $errormsg .= $clang->gT("You must supply a password for this saved session.") . "<br />\n"; } if (empty($_POST['savepass']) || empty($_POST['savepass2']) || $_POST['savepass'] != $_POST['savepass2']) { $errormsg .= $clang->gT("Your passwords do not match.") . "<br />\n"; } // if security question asnwer is incorrect if (function_exists("ImageCreate") && isCaptchaEnabled('saveandloadscreen', $thissurvey['usecaptcha'])) { if (empty($_POST['loadsecurity']) || !isset($_SESSION['survey_' . $surveyid]['secanswer']) || $_POST['loadsecurity'] != $_SESSION['survey_' . $surveyid]['secanswer']) { $errormsg .= $clang->gT("The answer to the security question is incorrect.") . "<br />\n"; } } if (!empty($errormsg)) { return; } $duplicate = SavedControl::model()->findByAttributes(array('sid' => $surveyid, 'identifier' => $_POST['savename'])); if (!empty($duplicate) && $duplicate->count() > 0) { $errormsg .= $clang->gT("This name has already been used for this survey. You must use a unique save name.") . "<br />\n"; return; } else { //INSERT BLANK RECORD INTO "survey_x" if one doesn't already exist if (!isset($_SESSION['survey_' . $surveyid]['srid'])) { $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust); $sdata = array("datestamp" => $today, "ipaddr" => getIPAddress(), "startlanguage" => $_SESSION['survey_' . $surveyid]['s_lang'], "refurl" => getenv("HTTP_REFERER")); if (SurveyDynamic::model($thissurvey['sid'])->insert($sdata)) { $srid = getLastInsertID('{{survey_' . $surveyid . '}}'); $_SESSION['survey_' . $surveyid]['srid'] = $srid; } else { safeDie("Unable to insert record into survey table.<br /><br />"); } } //CREATE ENTRY INTO "saved_control" $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $timeadjust); $saved_control = new SavedControl(); $saved_control->sid = $surveyid; $saved_control->srid = $_SESSION['survey_' . $surveyid]['srid']; $saved_control->identifier = $_POST['savename']; // Binding does escape, so no quoting/escaping necessary $saved_control->access_code = md5($_POST['savepass']); $saved_control->email = $_POST['saveemail']; $saved_control->ip = getIPAddress(); $saved_control->saved_thisstep = $thisstep; $saved_control->status = 'S'; $saved_control->saved_date = $today; $saved_control->refurl = getenv('HTTP_REFERER'); if ($saved_control->save()) { $scid = getLastInsertID('{{saved_control}}'); $_SESSION['survey_' . $surveyid]['scid'] = $scid; } else { safeDie("Unable to insert record into saved_control table.<br /><br />"); } $_SESSION['survey_' . $surveyid]['holdname'] = $_POST['savename']; //Session variable used to load answers every page. Unsafe - so it has to be taken care of on output $_SESSION['survey_' . $surveyid]['holdpass'] = $_POST['savepass']; //Session variable used to load answers every page. Unsafe - so it has to be taken care of on output //Email if needed if (isset($_POST['saveemail']) && validateEmailAddress($_POST['saveemail'])) { $subject = $clang->gT("Saved Survey Details") . " - " . $thissurvey['name']; $message = $clang->gT("Thank you for saving your survey in progress. The following details can be used to return to this survey and continue where you left off. Please keep this e-mail for your reference - we cannot retrieve the password for you."); $message .= "\n\n" . $thissurvey['name'] . "\n\n"; $message .= $clang->gT("Name") . ": " . $_POST['savename'] . "\n"; $message .= $clang->gT("Password") . ": " . $_POST['savepass'] . "\n\n"; $message .= $clang->gT("Reload your survey by clicking on the following link (or pasting it into your browser):") . "\n"; $message .= Yii::app()->getController()->createAbsoluteUrl("/survey/index/sid/{$surveyid}/loadall/reload/scid/{$scid}/loadname/" . rawurlencode($_POST['savename']) . "/loadpass/" . rawurlencode($_POST['savepass']) . "/lang/" . rawurlencode($clang->langcode)); if ($clienttoken) { $message .= "/token/" . rawurlencode($clienttoken); } $from = "{$thissurvey['adminname']} <{$thissurvey['adminemail']}>"; if (SendEmailMessage($message, $subject, $_POST['saveemail'], $from, $sitename, false, getBounceEmail($surveyid))) { $emailsent = "Y"; } else { $errormsg .= $clang->gT('Error: Email failed, this may indicate a PHP Mail Setup problem on the server. Your survey details have still been saved, however you will not get an email with the details. You should note the "name" and "password" you just used for future reference.'); if (trim($thissurvey['adminemail']) == '') { $errormsg .= $clang->gT('(Reason: Admin email address empty)'); } } } return $clang->gT('Your survey was successfully saved.'); } }
/** * Returns this model's relations * * @access public * @return array */ public function relations() { SurveyDynamic::sid(self::$sid); return array('survey' => array(self::BELONGS_TO, 'Survey', array(), 'condition' => 'sid=' . self::$sid, 'together' => true), 'responses' => array(self::HAS_MANY, 'SurveyDynamic', array('token' => 'token'))); }
/** * Loads results for the survey into the $survey->responses array. The * results begin from $minRecord and end with $maxRecord. Either none, * or both, the $minRecord and $maxRecord variables must be provided. * If none are then all responses are loaded. * * @param Survey $survey * @param int $iMinimum * @param int $iMaximum * @param string $sFilter An optional filter for the results * @param string $completionState all, complete or incomplete */ public function loadSurveyResults(SurveyObj $survey, $iMinimum, $iMaximum, $sFilter = '', $completionState = 'all') { // Get info about the survey $aSelectFields = Yii::app()->db->schema->getTable('{{survey_' . $survey->id . '}}')->getColumnNames(); // Allways add Table prefix : see bug #08396 . Don't use array_walk for PHP < 5.3 compatibility foreach ($aSelectFields as &$sField) { $sField = "{{survey_{$survey->id}}}." . $sField; } $oRecordSet = Yii::app()->db->createCommand()->from('{{survey_' . $survey->id . '}}'); if (tableExists('tokens_' . $survey->id) && array_key_exists('token', SurveyDynamic::model($survey->id)->attributes) && Permission::model()->hasSurveyPermission($survey->id, 'tokens', 'read')) { $oRecordSet->leftJoin('{{tokens_' . $survey->id . '}} tokentable', 'tokentable.token={{survey_' . $survey->id . '}}.token'); $aTokenFields = Yii::app()->db->schema->getTable('{{tokens_' . $survey->id . '}}')->getColumnNames(); foreach ($aTokenFields as &$sField) { $sField = "tokentable." . $sField; } $aSelectFields = array_merge($aSelectFields, array_diff($aTokenFields, array('tokentable.token'))); //$aSelectFields=array_diff($aSelectFields, array('{{survey_{$survey->id}}}.token')); //$aSelectFields[]='{{survey_' . $survey->id . '}}.token'; } if ($survey->info['savetimings'] == "Y") { $oRecordSet->leftJoin("{{survey_" . $survey->id . "_timings}} survey_timings", "{{survey_" . $survey->id . "}}.id = survey_timings.id"); $aTimingFields = Yii::app()->db->schema->getTable("{{survey_" . $survey->id . "_timings}}")->getColumnNames(); foreach ($aTimingFields as &$sField) { $sField = "survey_timings." . $sField; } $aSelectFields = array_merge($aSelectFields, array_diff($aTimingFields, array('survey_timings.id'))); //$aSelectFields=array_diff($aSelectFields, array('{{survey_{$survey->id}}}.id')); //$aSelectFields[]='{{survey_' . $survey->id . '}}.id'; } $aParams = array('min' => $iMinimum, 'max' => $iMaximum); $selection = '{{survey_' . $survey->id . '}}.id >= :min AND {{survey_' . $survey->id . '}}.id <= :max'; $oRecordSet->where($selection, $aParams); if ($sFilter != '') { $oRecordSet->andWhere($sFilter); } switch ($completionState) { case 'incomplete': $oRecordSet->andWhere('submitdate IS NULL'); break; case 'complete': $oRecordSet->andWhere('submitdate IS NOT NULL'); break; case 'all': default: // Do nothing, all responses break; } $survey->responses = $oRecordSet->select($aSelectFields)->query(); }
/** * RPC Routine to export token response in a survey. * Returns the requested file as base64 encoded string * * @access public * @param string $sSessionKey Auth credentials * @param int $iSurveyID Id of the Survey * @param string $sDocumentType pdf,csv,xls,doc,json * @param string $sToken The token for which responses needed * @param string $sLanguageCode The language to be used * @param string $sCompletionStatus Optional 'complete','incomplete' or 'all' - defaults to 'all' * @param string $sHeadingType 'code','full' or 'abbreviated' Optional defaults to 'code' * @param string $sResponseType 'short' or 'long' Optional defaults to 'short' * @param array $aFields Optional Selected fields * @return array|string On success: Requested file as base 64-encoded string. On failure array with error information * */ public function export_responses_by_token($sSessionKey, $iSurveyID, $sDocumentType, $sToken, $sLanguageCode = null, $sCompletionStatus = 'all', $sHeadingType = 'code', $sResponseType = 'short', $aFields = null) { if (!$this->_checkSessionKey($sSessionKey)) { return array('status' => 'Invalid session key'); } if (!Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'export')) { return array('status' => 'No permission'); } if (!tableExists('{{survey_' . $iSurveyID . '}}')) { return array('status' => 'No Data'); } if (!($oResult = SurveyDynamic::model($iSurveyID)->findByAttributes(array('token' => $sToken)))) { return array('status' => 'No Response found for Token'); } if ($oResult['id']) { return $this->export_responses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCode, $sCompletionStatus, $sHeadingType, $sResponseType, $oResult['id'], $oResult['id'], $aFields); } }
/** * This function replaces keywords in a text and is mainly intended for templates * If you use this functions put your replacement strings into the $replacements variable * instead of using global variables * NOTE - Don't do any embedded replacements in this function. Create the array of replacement values and * they will be done in batch at the end * * @param mixed $line Text to search in * @param mixed $replacements Array of replacements: Array( <stringtosearch>=><stringtoreplacewith> * @param boolean $anonymized Determines if token data is being used or just replaced with blanks * @param questionNum - needed to support dynamic JavaScript-based tailoring within questions * @param bStaticReplacement - Default off, forces non-dynamic replacements without <SPAN> tags (e.g. for the Completed page) * @return string Text with replaced strings */ function templatereplace($line, $replacements = array(), &$redata = array(), $debugSrc = 'Unspecified', $anonymized = false, $questionNum = NULL, $registerdata = array(), $bStaticReplacement = false) { /* global $clienttoken,$token,$sitename,$move,$showxquestions,$showqnumcode,$questioncode; global $s_lang,$errormsg,$saved_id, $languagechanger,$captchapath,$loadname; */ /* $allowedvars = array('surveylist', 'sitename', 'clienttoken', 'rooturl', 'thissurvey', 'imageurl', 'defaulttemplate', 'percentcomplete', 'move', 'groupname', 'groupdescription', 'question', 'showxquestions', 'showgroupinfo', 'showqnumcode', 'questioncode', 'answer', 'navigator', 'help', 'totalquestions', 'surveyformat', 'completed', 'notanswered', 'privacy', 'surveyid', 'publicurl', 'templatedir', 'token', 'assessments', 's_lang', 'errormsg', 'clang', 'saved_id', 'usertemplaterootdir', 'languagechanger', 'printoutput', 'captchapath', 'loadname'); */ $allowedvars = array('answer', 'assessments', 'captchapath', 'clienttoken', 'completed', 'errormsg', 'groupdescription', 'groupname', 'help', 'imageurl', 'languagechanger', 'loadname', 'move', 'navigator', 'percentcomplete', 'privacy', 'question', 's_lang', 'saved_id', 'showgroupinfo', 'showqnumcode', 'showxquestions', 'sitename', 'surveylist', 'templatedir', 'thissurvey', 'token', 'totalBoilerplatequestions', 'totalquestions'); $varsPassed = array(); foreach ($allowedvars as $var) { if (isset($redata[$var])) { ${$var} = $redata[$var]; $varsPassed[] = $var; } } // if (count($varsPassed) > 0) { // log_message('debug', 'templatereplace() called from ' . $debugSrc . ' contains: ' . implode(', ', $varsPassed)); // } // if (isset($redata['question'])) { // LimeExpressionManager::ShowStackTrace('has QID and/or SGA',$allowedvars); // } // extract($redata); // creates variables for each of the keys in the array // Local over-rides in case not set above if (!isset($showgroupinfo)) { $showgroupinfo = Yii::app()->getConfig('showgroupinfo'); } if (!isset($showqnumcode)) { $showqnumcode = Yii::app()->getConfig('showqnumcode'); } $_surveyid = Yii::app()->getConfig('surveyID'); if (!isset($showxquestions)) { $showxquestions = Yii::app()->getConfig('showxquestions'); } if (!isset($s_lang)) { $s_lang = isset(Yii::app()->session['survey_' . $_surveyid]['s_lang']) ? Yii::app()->session['survey_' . $_surveyid]['s_lang'] : 'en'; } if ($_surveyid && !isset($thissurvey)) { $thissurvey = getSurveyInfo($_surveyid, $s_lang); } if (!isset($captchapath)) { $captchapath = ''; } if (!isset($sitename)) { $sitename = Yii::app()->getConfig('sitename'); } if (!isset($saved_id) && isset(Yii::app()->session['survey_' . $_surveyid]['srid'])) { $saved_id = Yii::app()->session['survey_' . $_surveyid]['srid']; } $clang = Yii::app()->lang; Yii::app()->loadHelper('surveytranslator'); if (isset($thissurvey['sid'])) { $surveyid = $thissurvey['sid']; } // lets sanitize the survey template if (isset($thissurvey['templatedir'])) { $templatename = $thissurvey['templatedir']; } else { $templatename = Yii::app()->getConfig('defaulttemplate'); } if (!isset($templatedir)) { $templatedir = getTemplatePath($templatename); } if (!isset($templateurl)) { $templateurl = getTemplateURL($templatename) . "/"; } if (!$anonymized && isset($thissurvey['anonymized'])) { $anonymized = $thissurvey['anonymized'] == "Y"; } // TEMPLATECSS $_templatecss = ""; if (stripos($line, "{TEMPLATECSS}")) { if (file_exists($templatedir . DIRECTORY_SEPARATOR . 'jquery-ui-custom.css')) { Yii::app()->getClientScript()->registerCssFile("{$templateurl}jquery-ui-custom.css"); } elseif (file_exists($templatedir . DIRECTORY_SEPARATOR . 'jquery-ui.css')) { Yii::app()->getClientScript()->registerCssFile("{$templateurl}jquery-ui.css"); } else { Yii::app()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl') . "jquery-ui.css"); } Yii::app()->getClientScript()->registerCssFile("{$templateurl}template.css"); if (getLanguageRTL($clang->langcode)) { Yii::app()->getClientScript()->registerCssFile("{$templateurl}template-rtl.css"); } } // surveyformat if (isset($thissurvey['format'])) { $surveyformat = str_replace(array("A", "S", "G"), array("allinone", "questionbyquestion", "groupbygroup"), $thissurvey['format']); } else { $surveyformat = ""; } if (isset(Yii::app()->session['step']) && Yii::app()->session['step'] % 2 && $surveyformat != "allinone") { $surveyformat .= " page-odd"; } if (isset($thissurvey['questionindex']) && $thissurvey['questionindex'] > 0 && $surveyformat != "allinone" && (isset(Yii::app()->session['step']) && Yii::app()->session['step'] > 0)) { $surveyformat .= " withindex"; } if (isset($thissurvey['showprogress']) && $thissurvey['showprogress'] == "Y") { $surveyformat .= " showprogress"; } if (isset($thissurvey['showqnumcode'])) { $surveyformat .= " showqnumcode-" . $thissurvey['showqnumcode']; } // real survey contact if (isset($surveylist) && isset($surveylist['contact'])) { $surveycontact = $surveylist['contact']; } elseif (isset($surveylist) && isset($thissurvey['admin']) && $thissurvey['admin'] != "") { $surveycontact = sprintf($clang->gT("Please contact %s ( %s ) for further assistance."), $thissurvey['admin'], $thissurvey['adminemail']); } else { $surveycontact = ""; } // If there are non-bracketed replacements to be made do so above this line. // Only continue in this routine if there are bracketed items to replace {} if (strpos($line, "{") === false) { // process string anyway so that it can be pretty-printed return LimeExpressionManager::ProcessString($line, $questionNum, NULL, false, 1, 1, true); } if ($showgroupinfo == 'both' || $showgroupinfo == 'name' || $showgroupinfo == 'choose' && !isset($thissurvey['showgroupinfo']) || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'B' || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'N') { $_groupname = isset($groupname) ? $groupname : ''; } else { $_groupname = ''; } if ($showgroupinfo == 'both' || $showgroupinfo == 'description' || $showgroupinfo == 'choose' && !isset($thissurvey['showgroupinfo']) || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'B' || $showgroupinfo == 'choose' && $thissurvey['showgroupinfo'] == 'D') { $_groupdescription = isset($groupdescription) ? $groupdescription : ''; } else { $_groupdescription = ''; } if (isset($question) && is_array($question)) { $_question = $question['all']; $_question_text = $question['text']; $_question_help = $question['help']; $_question_mandatory = $question['mandatory']; $_question_man_message = $question['man_message']; $_question_valid_message = $question['valid_message']; $_question_file_valid_message = $question['file_valid_message']; $question['sgq'] = isset($question['sgq']) ? $question['sgq'] : ''; $_question_essentials = $question['essentials']; $_getQuestionClass = $question['class']; $_question_man_class = $question['man_class']; $_question_input_error_class = $question['input_error_class']; $_question_number = $question['number']; $_question_code = $question['code']; $_question_type = $question['type']; if ($question['sgq']) { // Not sure it can happen today ? But if set : allways sXgXq list($question['sid'], $question['gid'], $question['qid']) = explode("X", $question['sgq']); } else { list($question['sid'], $question['gid'], $question['qid']) = array('', '', ''); } $question['aid'] = isset($question['aid']) ? $question['aid'] : ''; } else { $_question = isset($question) ? $question : ''; $_question_text = ''; $_question_help = ''; $_question_mandatory = ''; $_question_man_message = ''; $_question_valid_message = ''; $_question_file_valid_message = ''; $_question_essentials = ''; $_getQuestionClass = ''; $_question_man_class = ''; $_question_input_error_class = ''; $_question_number = ''; $_question_code = ''; $_question_type = ''; $question = array_fill_keys(array('sid', 'gid', 'qid', 'aid', 'sgq'), ''); } if ($_question_type == '*') { $_question_text = '<div class="em_equation">' . $_question_text . '</div>'; } if (!($showqnumcode == 'both' || $showqnumcode == 'number' || $showqnumcode == 'choose' && !isset($thissurvey['showqnumcode']) || $showqnumcode == 'choose' && $thissurvey['showqnumcode'] == 'B' || $showqnumcode == 'choose' && $thissurvey['showqnumcode'] == 'N')) { $_question_number = ''; } if (!($showqnumcode == 'both' || $showqnumcode == 'code' || $showqnumcode == 'choose' && !isset($thissurvey['showqnumcode']) || $showqnumcode == 'choose' && $thissurvey['showqnumcode'] == 'B' || $showqnumcode == 'choose' && $thissurvey['showqnumcode'] == 'C')) { $_question_code = ''; } if (!isset($totalquestions)) { $totalquestions = 0; } $_totalquestionsAsked = $totalquestions; if ($showxquestions == 'show' || $showxquestions == 'choose' && !isset($thissurvey['showxquestions']) || $showxquestions == 'choose' && $thissurvey['showxquestions'] == 'Y') { if ($_totalquestionsAsked < 1) { $_therearexquestions = $clang->gT("There are no questions in this survey"); // Singular } elseif ($_totalquestionsAsked == 1) { $_therearexquestions = $clang->gT("There is 1 question in this survey"); //Singular } else { $_therearexquestions = $clang->gT("There are {NUMBEROFQUESTIONS} questions in this survey."); //Note this line MUST be before {NUMBEROFQUESTIONS} } } else { $_therearexquestions = ''; } if (isset($token)) { $_token = $token; } elseif (isset($clienttoken)) { $_token = htmlentities($clienttoken, ENT_QUOTES, 'UTF-8'); // or should it be URL-encoded? } else { $_token = ''; } // Expiry if (isset($thissurvey['expiry'])) { $dateformatdetails = getDateFormatData($thissurvey['surveyls_dateformat']); Yii::import('application.libraries.Date_Time_Converter', true); $datetimeobj = new Date_Time_Converter($thissurvey['expiry'], "Y-m-d"); $_dateoutput = $datetimeobj->convert($dateformatdetails['phpdate']); } else { $_dateoutput = '-'; } $_submitbutton = "<input class='submit' type='submit' value=' " . $clang->gT("Submit") . " ' name='move2' onclick=\"javascript:document.limesurvey.move.value = 'movesubmit';\" />"; if (isset($thissurvey['surveyls_url']) and $thissurvey['surveyls_url'] != "") { if (trim($thissurvey['surveyls_urldescription']) != '') { $_linkreplace = "<a href='{$thissurvey['surveyls_url']}'>{$thissurvey['surveyls_urldescription']}</a>"; } else { $_linkreplace = "<a href='{$thissurvey['surveyls_url']}'>{$thissurvey['surveyls_url']}</a>"; } } else { $_linkreplace = ''; } if (isset($thissurvey['sid']) && isset($_SESSION['survey_' . $thissurvey['sid']]['srid']) && $thissurvey['active'] == 'Y') { $iscompleted = SurveyDynamic::model($surveyid)->isCompleted($_SESSION['survey_' . $thissurvey['sid']]['srid']); } else { $iscompleted = false; } if (isset($surveyid) && !$iscompleted) { $_clearall = CHtml::htmlButton($clang->gT("Exit and clear survey"), array('type' => 'submit', 'id' => "clearall", 'value' => 'clearall', 'name' => 'clearall', 'class' => 'clearall button', 'data-confirmedby' => 'confirm-clearall', 'title' => $clang->gT("This action need confirmation."))); $_clearall .= CHtml::checkBox("confirm-clearall", false, array('id' => 'confirm-clearall', 'value' => 'confirm', 'class' => 'hide jshide')); $_clearall .= CHtml::label($clang->gT("Are you sure you want to clear all your responses?"), 'confirm-clearall', array('class' => 'hide jshide')); } else { $_clearall = ""; } if (isset(Yii::app()->session['datestamp'])) { $_datestamp = Yii::app()->session['datestamp']; } else { $_datestamp = '-'; } if (isset($thissurvey['allowsave']) and $thissurvey['allowsave'] == "Y") { $_saveall = doHtmlSaveAll(isset($move) ? $move : NULL); } else { $_saveall = ""; } if (!isset($help)) { $help = ""; } if (flattenText($help, true, true) != '') { if (!isset($helpicon)) { if (file_exists($templatedir . '/help.gif')) { $helpicon = $templateurl . 'help.gif'; } elseif (file_exists($templatedir . '/help.png')) { $helpicon = $templateurl . 'help.png'; } else { $helpicon = Yii::app()->getConfig('imageurl') . "/help.gif"; } } $_questionhelp = "<img src='{$helpicon}' alt='Help' align='left' />" . $help; } else { $_questionhelp = $help; } if (isset($thissurvey['allowprev']) && $thissurvey['allowprev'] == "N") { $_strreview = ""; } else { $_strreview = $clang->gT("If you want to check any of the answers you have made, and/or change them, you can do that now by clicking on the [<< prev] button and browsing through your responses."); } if (isset($surveyid)) { $restartparam = array(); if ($_token) { $restartparam['token'] = sanitize_token($_token); } // urlencode with needed with sanitize_token if (Yii::app()->request->getQuery('lang')) { $restartparam['lang'] = sanitize_languagecode(Yii::app()->request->getQuery('lang')); } elseif ($s_lang) { $restartparam['lang'] = $s_lang; } $restartparam['newtest'] = "Y"; $restarturl = Yii::app()->getController()->createUrl("survey/index/sid/{$surveyid}", $restartparam); $_restart = "<a href='{$restarturl}'>" . $clang->gT("Restart this Survey") . "</a>"; } else { $_restart = ""; } if (isset($thissurvey['anonymized']) && $thissurvey['anonymized'] == 'Y') { $_savealert = $clang->gT("To remain anonymous please use a pseudonym as your username, also an email address is not required."); } else { $_savealert = ""; } if (isset($surveyid)) { if ($_token) { $returnlink = Yii::app()->getController()->createUrl("survey/index/sid/{$surveyid}", array('token' => sanitize_token($_token))); } else { $returnlink = Yii::app()->getController()->createUrl("survey/index/sid/{$surveyid}"); } $_return_to_survey = "<a href='{$returnlink}'>" . $clang->gT("Return to survey") . "</a>"; } else { $_return_to_survey = ""; } // Save Form $_saveform = "<table class='save-survey-form'><tr class='save-survey-row save-survey-name'><td class='save-survey-label label-cell' align='right'><label for='savename'>" . $clang->gT("Name") . "</label>:</td><td class='save-survey-input input-cell'><input type='text' name='savename' id='savename' value='"; if (isset($_POST['savename'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['savename'])); } $_saveform .= "' /></td></tr>\n" . "<tr class='save-survey-row save-survey-password-1'><td class='save-survey-label label-cell' align='right'><label for='savepass'>" . $clang->gT("Password") . "</label>:</td><td class='save-survey-input input-cell'><input type='password' id='savepass' name='savepass' value='"; if (isset($_POST['savepass'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['savepass'])); } $_saveform .= "' /></td></tr>\n" . "<tr class='save-survey-row save-survey-password-2'><td class='save-survey-label label-cell' align='right'><label for='savepass2'>" . $clang->gT("Repeat password") . "</label>:</td><td class='save-survey-input input-cell'><input type='password' id='savepass2' name='savepass2' value='"; if (isset($_POST['savepass2'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['savepass2'])); } $_saveform .= "' /></td></tr>\n" . "<tr class='save-survey-row save-survey-email'><td class='save-survey-label label-cell' align='right'><label for='saveemail'>" . $clang->gT("Your email address") . "</label>:</td><td class='save-survey-input input-cell'><input type='text' id='saveemail' name='saveemail' value='"; if (isset($_POST['saveemail'])) { $_saveform .= HTMLEscape(autoUnescape($_POST['saveemail'])); } $_saveform .= "' /></td></tr>\n"; if (isset($thissurvey['usecaptcha']) && function_exists("ImageCreate") && isCaptchaEnabled('saveandloadscreen', $thissurvey['usecaptcha'])) { $_saveform .= "<tr class='save-survey-row save-survey-captcha'><td class='save-survey-label label-cell' align='right'><label for='loadsecurity'>" . $clang->gT("Security question") . "</label>:</td><td class='save-survey-input input-cell'><table class='captcha-table'><tr><td class='captcha-image' valign='middle'><img alt='' src='" . Yii::app()->getController()->createUrl('/verification/image/sid/' . (isset($surveyid) ? $surveyid : '')) . "' /></td><td class='captcha-input' valign='middle' style='text-align:left'><input type='text' size='5' maxlength='3' id='loadsecurity' name='loadsecurity' value='' /></td></tr></table></td></tr>\n"; } $_saveform .= "<tr><td align='right'></td><td></td></tr>\n" . "<tr class='save-survey-row save-survey-submit'><td class='save-survey-label label-cell'><label class='hide jshide' for='savebutton'>" . $clang->gT("Save Now") . "</label></td><td class='save-survey-input input-cell'><input type='submit' id='savebutton' name='savesubmit' class='button' value='" . $clang->gT("Save Now") . "' /></td></tr>\n" . "</table>"; // Load Form $_loadform = "<table class='load-survey-form'><tr class='load-survey-row load-survey-name'><td class='load-survey-label label-cell' align='right'><label for='loadname'>" . $clang->gT("Saved name") . "</label>:</td><td class='load-survey-input input-cell'><input type='text' id='loadname' name='loadname' value='"; if (isset($loadname)) { $_loadform .= HTMLEscape(autoUnescape($loadname)); } $_loadform .= "' /></td></tr>\n" . "<tr class='load-survey-row load-survey-password'><td class='load-survey-label label-cell' align='right'><label for='loadpass'>" . $clang->gT("Password") . "</label>:</td><td class='load-survey-input input-cell'><input type='password' id='loadpass' name='loadpass' value='"; if (isset($loadpass)) { $_loadform .= HTMLEscape(autoUnescape($loadpass)); } $_loadform .= "' /></td></tr>\n"; if (isset($thissurvey['usecaptcha']) && function_exists("ImageCreate") && isCaptchaEnabled('saveandloadscreen', $thissurvey['usecaptcha'])) { $_loadform .= "<tr class='load-survey-row load-survey-captcha'><td class='load-survey-label label-cell' align='right'><label for='loadsecurity'>" . $clang->gT("Security question") . "</label>:</td><td class='load-survey-input input-cell'><table class='captcha-table'><tr><td class='captcha-image' valign='middle'><img src='" . Yii::app()->getController()->createUrl('/verification/image/sid/' . (isset($surveyid) ? $surveyid : '')) . "' alt='' /></td><td class='captcha-input' valign='middle'><input type='text' size='5' maxlength='3' id='loadsecurity' name='loadsecurity' value='' alt=''/></td></tr></table></td></tr>\n"; } $_loadform .= "<tr class='load-survey-row load-survey-submit'><td class='load-survey-label label-cell'><label class='hide jshide' for='loadbutton'>" . $clang->gT("Load now") . "</label></td><td class='load-survey-input input-cell'><input type='submit' id='loadbutton' class='button' value='" . $clang->gT("Load now") . "' /></td></tr></table>\n"; // Registration Form if (isset($surveyid) || isset($registerdata) && $debugSrc == 'register.php') { if (isset($surveyid)) { $tokensid = $surveyid; } else { $tokensid = $registerdata['sid']; } $_registerform = CHtml::form(array("/register/index/surveyid/{$tokensid}"), 'post'); if (!isset($_REQUEST['lang'])) { $_reglang = Survey::model()->findByPk($tokensid)->language; } else { $_reglang = returnGlobal('lang'); } $_registerform .= "\n<input type='hidden' name='lang' value='" . $_reglang . "' />\n"; $_registerform .= "<input type='hidden' name='sid' value='{$tokensid}' id='sid' />\n"; $_registerform .= "<table class='register register-form-table' summary='Registrationform'>\n" . "<tr class='register-form-row register-form-fname'><td class='register-form-label label-cell' align='right'><label for='register_firstname'>" . $clang->gT("First name") . "</label>:</td>" . "<td class='register-form-input input-cell' align='left'><input class='text' type='text' id='register_firstname' name='register_firstname'"; if (isset($_POST['register_firstname'])) { $_registerform .= " value='" . htmlentities(returnGlobal('register_firstname'), ENT_QUOTES, 'UTF-8') . "'"; } $_registerform .= " /></td></tr>" . "<tr class='register-form-row register-form-lname'><td class='register-form-label label-cell' align='right'><label for='register_lastname'>" . $clang->gT("Last name") . "</label>:</td>\n" . "<td class='register-form-input input-cell' align='left'><input class='text' type='text' id='register_lastname' name='register_lastname'"; if (isset($_POST['register_lastname'])) { $_registerform .= " value='" . htmlentities(returnGlobal('register_lastname'), ENT_QUOTES, 'UTF-8') . "'"; } $_registerform .= " /></td></tr>\n" . "<tr class='register-form-row register-form-email'><td class='register-form-label label-cell' align='right'><label for='register_email'>" . $clang->gT("Email address") . "</label>:</td>\n" . "<td class='register-form-input input-cell' align='left'><input class='text' type='text' id='register_email' name='register_email'"; if (isset($_POST['register_email'])) { $_registerform .= " value='" . htmlentities(returnGlobal('register_email'), ENT_QUOTES, 'UTF-8') . "'"; } $_registerform .= " /></td></tr>\n"; foreach ($thissurvey['attributedescriptions'] as $field => $attribute) { if (empty($attribute['show_register']) || $attribute['show_register'] != 'Y') { continue; } $_registerform .= ' <tr class="register-form-row register-form-attribute"> <td class="register-form-label label-cell" align="right"><label for="register_' . $field . '">' . $thissurvey['attributecaptions'][$field] . ($attribute['mandatory'] == 'Y' ? '*' : '') . '</label>:</td> <td class="register-form-input input-cell" align="left"><input class="text" type="text" id="register_' . $field . '" name="register_' . $field . '" /></td> </tr>'; } if ((count($registerdata) > 1 || isset($thissurvey['usecaptcha'])) && function_exists("ImageCreate") && isCaptchaEnabled('registrationscreen', $thissurvey['usecaptcha'])) { $_registerform .= "<tr class='register-form-row register-form-captcha'><td class='register-form-label label-cell' align='right'><label for='loadsecurity'>" . $clang->gT("Security Question") . "</label>:</td><td class='register-form-input input-cell'><table><tr><td valign='middle'><img src='" . Yii::app()->getController()->createUrl('/verification/image/sid/' . $surveyid) . "' alt='' /></td><td valign='middle'><input type='text' size='5' maxlength='3' id='loadsecurity' name='loadsecurity' value='' /></td></tr></table></td></tr>\n"; } $_registerform .= "<tr class='register-form-row register-form-submit'><td class='register-form-label label-cell'><label class='hide jshide' for='registercontinue'>" . $clang->gT("Continue") . "</label></td><td class='register-form-input input-cell' align='left'><input id='registercontinue' class='submit button' type='submit' value='" . $clang->gT("Continue") . "' />" . "</td></tr>\n" . "</table>\n"; if (count($registerdata) > 1 && $registerdata['sid'] != NULL && $debugSrc == 'register.php') { $_registerform .= "<input name='startdate' type ='hidden' value='" . $registerdata['startdate'] . "' />"; $_registerform .= "<input name='enddate' type ='hidden' value='" . $registerdata['enddate'] . "' />"; } $_registerform .= "</form>\n"; } else { $_registerform = ""; } // Assessments $assessmenthtml = ""; if (isset($surveyid) && !is_null($surveyid) && function_exists('doAssessment')) { $assessmentdata = doAssessment($surveyid, true); $_assessment_current_total = $assessmentdata['total']; if (stripos($line, "{ASSESSMENTS}")) { $assessmenthtml = doAssessment($surveyid, false); } } else { $_assessment_current_total = ''; } if (isset($thissurvey['googleanalyticsapikey']) && trim($thissurvey['googleanalyticsapikey']) != '') { $_googleAnalyticsAPIKey = trim($thissurvey['googleanalyticsapikey']); } else { $_googleAnalyticsAPIKey = trim(getGlobalSetting('googleanalyticsapikey')); } $_googleAnalyticsStyle = isset($thissurvey['googleanalyticsstyle']) ? $thissurvey['googleanalyticsstyle'] : '0'; $_googleAnalyticsJavaScript = ''; if ($_googleAnalyticsStyle != '' && $_googleAnalyticsStyle != 0 && $_googleAnalyticsAPIKey != '') { switch ($_googleAnalyticsStyle) { case '1': // Default Google Tracking $_googleAnalyticsJavaScript = <<<EOD <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', '{$_googleAnalyticsAPIKey}']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> EOD; break; case '2': // SurveyName-[SID]/[GSEQ]-GroupName - create custom GSEQ based upon page step $moveInfo = LimeExpressionManager::GetLastMoveResult(); if (is_null($moveInfo)) { $gseq = 'welcome'; } else { if ($moveInfo['finished']) { $gseq = 'finished'; } else { if (isset($moveInfo['at_start']) && $moveInfo['at_start']) { $gseq = 'welcome'; } else { if (is_null($_groupname)) { $gseq = 'printanswers'; } else { $gseq = $moveInfo['gseq'] + 1; } } } } $_trackURL = htmlspecialchars($thissurvey['name'] . '-[' . $surveyid . ']/[' . $gseq . ']-' . $_groupname); $_googleAnalyticsJavaScript = <<<EOD <script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', '{$_googleAnalyticsAPIKey}']); _gaq.push(['_trackPageview','{$_trackURL}']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script> EOD; break; } } $_endtext = ''; if (isset($thissurvey['surveyls_endtext']) && trim($thissurvey['surveyls_endtext']) != '') { $_endtext = $thissurvey['surveyls_endtext']; } if (isset($surveyid) && isset($_SESSION['survey_' . $surveyid]) && isset($_SESSION['survey_' . $surveyid]['register_errormsg'])) { $register_errormsg = $_SESSION['survey_' . $surveyid]['register_errormsg']; } // Set the array of replacement variables here - don't include curly braces $coreReplacements = array(); $coreReplacements['ACTIVE'] = isset($thissurvey['active']) && !($thissurvey['active'] != "Y"); $coreReplacements['AID'] = $question['aid']; $coreReplacements['ANSWER'] = isset($answer) ? $answer : ''; // global $coreReplacements['ANSWERSCLEARED'] = $clang->gT("Answers cleared"); $coreReplacements['ASSESSMENTS'] = $assessmenthtml; $coreReplacements['ASSESSMENT_CURRENT_TOTAL'] = $_assessment_current_total; $coreReplacements['ASSESSMENT_HEADING'] = $clang->gT("Your assessment"); $coreReplacements['CHECKJAVASCRIPT'] = "<noscript><span class='warningjs'>" . $clang->gT("Caution: JavaScript execution is disabled in your browser. You may not be able to answer all questions in this survey. Please, verify your browser parameters.") . "</span></noscript>"; $coreReplacements['CLEARALL'] = $_clearall; $coreReplacements['CLOSEWINDOW'] = "<a href='javascript:%20self.close()'>" . $clang->gT("Close this window") . "</a>"; $coreReplacements['COMPLETED'] = isset($redata['completed']) ? $redata['completed'] : ''; // global $coreReplacements['DATESTAMP'] = $_datestamp; $coreReplacements['ENDTEXT'] = $_endtext; $coreReplacements['EXPIRY'] = $_dateoutput; $coreReplacements['GID'] = $question['gid'] ? $question['gid'] : Yii::app()->getConfig('gid', ''); // Use the gid of the question, except if we are not in question (Randomization group name) $coreReplacements['GOOGLE_ANALYTICS_API_KEY'] = $_googleAnalyticsAPIKey; $coreReplacements['GOOGLE_ANALYTICS_JAVASCRIPT'] = $_googleAnalyticsJavaScript; $coreReplacements['GROUPDESCRIPTION'] = $_groupdescription; $coreReplacements['GROUPNAME'] = $_groupname; $coreReplacements['LANG'] = $clang->getlangcode(); $coreReplacements['LANGUAGECHANGER'] = isset($languagechanger) ? $languagechanger : ''; // global $coreReplacements['LOADERROR'] = isset($errormsg) ? $errormsg : ''; // global $coreReplacements['LOADFORM'] = $_loadform; $coreReplacements['LOADHEADING'] = $clang->gT("Load a previously saved survey"); $coreReplacements['LOADMESSAGE'] = $clang->gT("You can load a survey that you have previously saved from this screen.") . "<br />" . $clang->gT("Type in the 'name' you used to save the survey, and the password.") . "<br />"; $coreReplacements['NAVIGATOR'] = isset($navigator) ? $navigator : ''; // global $coreReplacements['NOSURVEYID'] = isset($surveylist) ? $surveylist['nosid'] : ''; $coreReplacements['NUMBEROFQUESTIONS'] = $_totalquestionsAsked; $coreReplacements['PERCENTCOMPLETE'] = isset($percentcomplete) ? $percentcomplete : ''; // global $coreReplacements['PRIVACY'] = isset($privacy) ? $privacy : ''; // global $coreReplacements['PRIVACYMESSAGE'] = "<span style='font-weight:bold; font-style: italic;'>" . $clang->gT("A Note On Privacy") . "</span><br />" . $clang->gT("This survey is anonymous.") . "<br />" . $clang->gT("The record of your survey responses does not contain any identifying information about you, unless a specific survey question explicitly asked for it.") . ' ' . $clang->gT("If you used an identifying token to access this survey, please rest assured that this token will not be stored together with your responses. It is managed in a separate database and will only be updated to indicate whether you did (or did not) complete this survey. There is no way of matching identification tokens with survey responses."); $coreReplacements['QID'] = $question['qid']; $coreReplacements['QUESTION'] = $_question; $coreReplacements['QUESTIONHELP'] = $_questionhelp; $coreReplacements['QUESTIONHELPPLAINTEXT'] = strip_tags(addslashes($help)); // global $coreReplacements['QUESTION_CLASS'] = $_getQuestionClass; $coreReplacements['QUESTION_CODE'] = $_question_code; $coreReplacements['QUESTION_ESSENTIALS'] = $_question_essentials; $coreReplacements['QUESTION_FILE_VALID_MESSAGE'] = $_question_file_valid_message; $coreReplacements['QUESTION_HELP'] = $_question_help; $coreReplacements['QUESTION_INPUT_ERROR_CLASS'] = $_question_input_error_class; $coreReplacements['QUESTION_MANDATORY'] = $_question_mandatory; $coreReplacements['QUESTION_MAN_CLASS'] = $_question_man_class; $coreReplacements['QUESTION_MAN_MESSAGE'] = $_question_man_message; $coreReplacements['QUESTION_NUMBER'] = $_question_number; $coreReplacements['QUESTION_TEXT'] = $_question_text; $coreReplacements['QUESTION_VALID_MESSAGE'] = $_question_valid_message; $coreReplacements['REGISTERERROR'] = isset($register_errormsg) ? $register_errormsg : ''; // global $coreReplacements['REGISTERFORM'] = $_registerform; $coreReplacements['REGISTERMESSAGE1'] = $clang->gT("You must be registered to complete this survey"); $coreReplacements['REGISTERMESSAGE2'] = $clang->gT("You may register for this survey if you wish to take part.") . "<br />\n" . $clang->gT("Enter your details below, and an email containing the link to participate in this survey will be sent immediately."); $coreReplacements['RESTART'] = $_restart; $coreReplacements['RETURNTOSURVEY'] = $_return_to_survey; $coreReplacements['SAVE'] = $_saveall; $coreReplacements['SAVEALERT'] = $_savealert; $coreReplacements['SAVEDID'] = isset($saved_id) ? $saved_id : ''; // global $coreReplacements['SAVEERROR'] = isset($errormsg) ? $errormsg : ''; // global - same as LOADERROR $coreReplacements['SAVEFORM'] = $_saveform; $coreReplacements['SAVEHEADING'] = $clang->gT("Save your unfinished survey"); $coreReplacements['SAVEMESSAGE'] = $clang->gT("Enter a name and password for this survey and click save below.") . "<br />\n" . $clang->gT("Your survey will be saved using that name and password, and can be completed later by logging in with the same name and password.") . "<br /><br />\n" . $clang->gT("If you give an email address, an email containing the details will be sent to you.") . "<br /><br />\n" . $clang->gT("After having clicked the save button you can either close this browser window or continue filling out the survey."); $coreReplacements['SGQ'] = $question['sgq']; $coreReplacements['SID'] = Yii::app()->getConfig('surveyID', ''); // Allways use surveyID from config $coreReplacements['SITENAME'] = isset($sitename) ? $sitename : ''; // global $coreReplacements['SUBMITBUTTON'] = $_submitbutton; $coreReplacements['SUBMITCOMPLETE'] = "<strong>" . $clang->gT("Thank you!") . "<br /><br />" . $clang->gT("You have completed answering the questions in this survey.") . "</strong><br /><br />" . $clang->gT("Click on 'Submit' now to complete the process and save your answers."); $coreReplacements['SUBMITREVIEW'] = $_strreview; $coreReplacements['SURVEYCONTACT'] = $surveycontact; $coreReplacements['SURVEYDESCRIPTION'] = isset($thissurvey['description']) ? $thissurvey['description'] : ''; $coreReplacements['SURVEYFORMAT'] = isset($surveyformat) ? $surveyformat : ''; // global $coreReplacements['SURVEYLANGAGE'] = $clang->langcode; $coreReplacements['SURVEYLANGUAGE'] = $clang->langcode; $coreReplacements['SURVEYLIST'] = isset($surveylist) ? $surveylist['list'] : ''; $coreReplacements['SURVEYLISTHEADING'] = isset($surveylist) ? $surveylist['listheading'] : ''; $coreReplacements['SURVEYNAME'] = isset($thissurvey['name']) ? $thissurvey['name'] : ''; $coreReplacements['TEMPLATECSS'] = $_templatecss; $coreReplacements['TEMPLATEJS'] = CHtml::tag('script', array('type' => 'text/javascript', 'src' => $templateurl . 'template.js'), ''); $coreReplacements['TEMPLATEURL'] = $templateurl; $coreReplacements['THEREAREXQUESTIONS'] = $_therearexquestions; $coreReplacements['TOKEN'] = !$anonymized ? $_token : ''; // Silently replace TOKEN by empty string $coreReplacements['URL'] = $_linkreplace; $coreReplacements['WELCOME'] = isset($thissurvey['welcome']) ? $thissurvey['welcome'] : ''; if (!is_null($replacements) && is_array($replacements)) { $doTheseReplacements = array_merge($coreReplacements, $replacements); // so $replacements overrides core values } else { $doTheseReplacements = $coreReplacements; } // Now do all of the replacements - In rare cases, need to do 3 deep recursion, that that is default $line = LimeExpressionManager::ProcessString($line, $questionNum, $doTheseReplacements, false, 3, 1, false, true, $bStaticReplacement); return $line; }
public function time($iSurveyID) { $aData = $this->_getData(array('iSurveyId' => $iSurveyID)); extract($aData); $aViewUrls = array(); if ($aData['surveyinfo']['savetimings'] != "Y") { die; } if (Yii::app()->request->getPost('deleteanswer') && Yii::app()->request->getPost('deleteanswer') != '' && Yii::app()->request->getPost('deleteanswer') != 'marked' && Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'delete')) { $iResponseID = (int) Yii::app()->request->getPost('deleteanswer'); SurveyDynamic::model($iSurveyID)->deleteByPk($iResponseID); SurveyTimingDynamic::model($iSurveyID)->deleteByPk($iResponseID); } if (Yii::app()->request->getPost('markedresponses') && count(Yii::app()->request->getPost('markedresponses')) > 0) { if (Yii::app()->request->getPost('deleteanswer') && Yii::app()->request->getPost('deleteanswer') === 'marked' && Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'delete')) { foreach (Yii::app()->request->getPost('markedresponses') as $iResponseID) { $iResponseID = (int) $iResponseID; SurveyDynamic::model($iSurveyID)->deleteByPk($iResponseID); SurveyTimingDynamic::model($iSurveyID)->deleteByPk($iResponseID); } } } $fields = createTimingsFieldMap($iSurveyID, 'full', true, false, $aData['language']); foreach ($fields as $fielddetails) { // headers for answer id and time data if ($fielddetails['type'] == 'id') { $fnames[] = array($fielddetails['fieldname'], $fielddetails['question']); } if ($fielddetails['type'] == 'interview_time') { $fnames[] = array($fielddetails['fieldname'], gT('Total time')); } if ($fielddetails['type'] == 'page_time') { $fnames[] = array($fielddetails['fieldname'], gT('Group') . ": " . $fielddetails['group_name']); } if ($fielddetails['type'] == 'answer_time') { $fnames[] = array($fielddetails['fieldname'], gT('Question') . ": " . $fielddetails['title']); } } $fncount = count($fnames); //NOW LETS CREATE A TABLE WITH THOSE HEADINGS foreach ($fnames as $fn) { if (!isset($currentgroup)) { $currentgroup = $fn[1]; $gbc = "oddrow"; } if ($currentgroup != $fn[1]) { $currentgroup = $fn[1]; if ($gbc == "oddrow") { $gbc = "evenrow"; } else { $gbc = "oddrow"; } } } $aData['fnames'] = $fnames; $start = Yii::app()->request->getParam('start', 0); $limit = Yii::app()->request->getParam('limit', 50); if (!$limit) { $limit = 50; } //LETS COUNT THE DATA $oCriteria = new CdbCriteria(); $oCriteria->select = 'tid'; $oCriteria->join = "INNER JOIN {{survey_{$iSurveyID}}} s ON t.id=s.id"; $oCriteria->condition = 'submitdate IS NOT NULL'; $dtcount = SurveyTimingDynamic::model($iSurveyID)->count($oCriteria); // or die("Couldn't get response data"); if ($limit > $dtcount) { $limit = $dtcount; } //NOW LETS SHOW THE DATA $oCriteria = new CdbCriteria(); $oCriteria->join = "INNER JOIN {{survey_{$iSurveyID}}} s ON t.id=s.id"; $oCriteria->condition = 'submitdate IS NOT NULL'; $oCriteria->order = "s.id " . (Yii::app()->request->getParam('order') == 'desc' ? 'desc' : 'asc'); $oCriteria->offset = $start; $oCriteria->limit = $limit; $dtresult = SurveyTimingDynamic::model($iSurveyID)->findAllAsArray($oCriteria); $dtcount2 = count($dtresult); $cells = $fncount + 1; //CONTROL MENUBAR $last = $start - $limit; $next = $start + $limit; $end = $dtcount - $limit; if ($end < 0) { $end = 0; } if ($last < 0) { $last = 0; } if ($next >= $dtcount) { $next = $dtcount - $limit; } if ($end < 0) { $end = 0; } $aData['sCompletionStateValue'] = incompleteAnsFilterState(); $aData['start'] = $start; $aData['limit'] = $limit; $aData['last'] = $last; $aData['next'] = $next; $aData['end'] = $end; $aViewUrls[] = 'browsetimeheader_view'; $aData['fncount'] = $fncount; $bgcc = 'oddrow'; foreach ($dtresult as $dtrow) { if ($bgcc == "evenrow") { $bgcc = "oddrow"; } else { $bgcc = "evenrow"; } $browsedatafield = array(); for ($i = 0; $i < $fncount; $i++) { $browsedatafield[$i] = $dtrow[$fnames[$i][0]]; // seconds -> minutes & seconds if (strtolower(substr($fnames[$i][0], -4)) == "time") { $minutes = (int) ($browsedatafield[$i] / 60); $seconds = $browsedatafield[$i] % 60; $browsedatafield[$i] = ''; if ($minutes > 0) { $browsedatafield[$i] .= "{$minutes} min "; } $browsedatafield[$i] .= "{$seconds} s"; } } $aData['browsedatafield'] = $browsedatafield; $aData['bgcc'] = $bgcc; $aData['dtrow'] = $dtrow; $aViewUrls['browsetimerow_view'][] = $aData; } //interview Time statistics $aData['statistics'] = SurveyTimingDynamic::model($iSurveyId)->statistics(); $aData['num_total_answers'] = SurveyDynamic::model($iSurveyID)->count(); $aData['num_completed_answers'] = SurveyDynamic::model($iSurveyID)->count('submitdate IS NOT NULL'); $aViewUrls[] = 'browsetimefooter_view'; $this->_renderWrappedTemplate('', $aViewUrls, $aData); }
/** * RPC Routine to export token response in a survey. * Returns the requested file as base64 encoded string * * @access public * @param string $sSessionKey Auth credentials * @param int $iSurveyID Id of the Survey * @param string $sDocumentType pdf,csv,xls,doc,json * @param string $sToken The token for which responses needed * @param string $sLanguageCode The language to be used * @param string $sCompletionStatus Optional 'complete','incomplete' or 'all' - defaults to 'all' * @param string $sHeadingType 'code','full' or 'abbreviated' Optional defaults to 'code' * @param string $sResponseType 'short' or 'long' Optional defaults to 'short' * @param array $aFields Optional Selected fields * @return array|string On success: Requested file as base 64-encoded string. On failure array with error information * */ public function export_responses_by_token($sSessionKey, $iSurveyID, $sDocumentType, $sToken, $sLanguageCode = null, $sCompletionStatus = 'all', $sHeadingType = 'code', $sResponseType = 'short', $aFields = null) { if (!$this->_checkSessionKey($sSessionKey)) { return array('status' => 'Invalid session key'); } Yii::app()->loadHelper('admin/exportresults'); if (!tableExists('{{survey_' . $iSurveyID . '}}')) { return array('status' => 'No Data, survey table does not exist.'); } if (!($maxId = SurveyDynamic::model($iSurveyID)->getMaxId())) { return array('status' => 'No Data, could not get max id.'); } if (!empty($sLanguageCode) && !in_array($sLanguageCode, Survey::model()->findByPk($iSurveyID)->getAllLanguages())) { return array('status' => 'Language code not found for this survey.'); } if (!SurveyDynamic::model($iSurveyID)->findByAttributes(array('token' => $sToken))) { return array('status' => 'No Response found for Token'); } if (!Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'export')) { return array('status' => 'No permission'); } if (empty($sLanguageCode)) { $sLanguageCode = getBaseLanguageFromSurveyID($iSurveyID); } if (is_null($aFields)) { $aFields = array_keys(createFieldMap($iSurveyID, 'full', true, false, $sLanguageCode)); } if ($sDocumentType == 'xls') { // Cut down to the first 255 fields $aFields = array_slice($aFields, 0, 255); } $oFormattingOptions = new FormattingOptions(); $oFormattingOptions->responseMinRecord = 1; $oFormattingOptions->responseMaxRecord = $maxId; $oFormattingOptions->selectedColumns = $aFields; $oFormattingOptions->responseCompletionState = $sCompletionStatus; $oFormattingOptions->headingFormat = $sHeadingType; $oFormattingOptions->answerFormat = $sResponseType; $oFormattingOptions->output = 'file'; $oExport = new ExportSurveyResultsService(); $sTableName = Yii::app()->db->tablePrefix . 'survey_' . $iSurveyID; $sTempFile = $oExport->exportSurvey($iSurveyID, $sLanguageCode, $sDocumentType, $oFormattingOptions, "{$sTableName}.token='{$sToken}'"); return new BigFile($sTempFile, true, 'base64'); }
/** * Returns a simple list of values in a particular column, that meet the requirements of the SQL */ function _listcolumn($surveyid, $column, $sortby = "", $sortmethod = "", $sorttype = "") { $search['condition'] = Yii::app()->db->quoteColumnName($column) . " != ''"; $sDBDriverName = Yii::app()->db->getDriverName(); if ($sDBDriverName == 'sqlsrv' || $sDBDriverName == 'mssql' || $sDBDriverName == 'dblib') { $search['condition'] = "CAST(" . Yii::app()->db->quoteColumnName($column) . " as varchar) != ''"; } //filter incomplete answers if set if (incompleteAnsFilterState() == "incomplete") { $search['condition'] .= " AND submitdate is null"; } elseif (incompleteAnsFilterState() == "complete") { $search['condition'] .= " AND submitdate is not null"; } //Look for any selects/filters set in the original statistics query, and apply them to the column listing if (isset(Yii::app()->session['statistics_selects_' . $surveyid]) && is_array(Yii::app()->session['statistics_selects_' . $surveyid])) { foreach (Yii::app()->session['statistics_selects_' . $surveyid] as $sql) { $search['condition'] .= " AND {$sql}"; } } if ($sortby != '') { if ($sDBDriverName == 'sqlsrv' || $sDBDriverName == 'mssql' || $sDBDriverName == 'dblib') { $sortby = "CAST(" . Yii::app()->db->quoteColumnName($sortby) . " as varchar)"; } else { $sortby = Yii::app()->db->quoteColumnName($sortby); } if ($sorttype == 'N') { $sortby = "({$sortby} * 1)"; } //Converts text sorting into numerical sorting $search['order'] = $sortby . ' ' . $sortmethod; } $results = SurveyDynamic::model($surveyid)->findAll($search); $output = array(); foreach ($results as $row) { $output[] = array("id" => $row['id'], "value" => $row[$column]); } return $output; }
/** * This function sends the shared participant info to the share panel using JSON encoding * This function is called after the share panel grid is loaded * This function returns the json depending on the user logged in by checking it from the session * @param it takes the session user data loginID * @return JSON encoded string containg sharing information */ function getTokens_json($iSurveyId, $search = null) { // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) { $clang->eT("No token table."); // return json ? error not treated in js. return; } $clang = $this->getController()->lang; if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'read')) { $clang->eT("We are sorry but you don't have permissions to do this."); // return json ? error not treated in js. return; } $page = Yii::app()->request->getPost('page', 1); $sidx = Yii::app()->request->getPost('sidx', 'lastname'); $sord = Yii::app()->request->getPost('sord', 'asc'); $limit = Yii::app()->request->getPost('rows', 25); $aData = new stdClass(); $aData->page = $page; $aSearchArray = Yii::app()->request->getPost('searcharray'); if (empty($search) && !empty($aSearchArray)) { $search = $aSearchArray; } if (!empty($search)) { $condition = TokenDynamic::model($iSurveyId)->getSearchMultipleCondition($search); } else { $condition = new CDbCriteria(); } $condition->order = $sidx . " " . $sord; $condition->offset = ($page - 1) * $limit; $condition->limit = $limit; $tokens = Token::model($iSurveyId)->findAll($condition); $condition->offset = 0; $condition->limit = 0; $aData->records = Token::model($iSurveyId)->count($condition); if ($limit > $aData->records) { $limit = $aData->records; } if ($limit != 0) { $aData->total = ceil($aData->records / $limit); } else { $aData->total = 0; } Yii::app()->loadHelper("surveytranslator"); $format = getDateFormatData(Yii::app()->session['dateformat']); $aSurveyInfo = Survey::model()->findByPk($iSurveyId)->getAttributes(); //Get survey settings $attributes = getAttributeFieldNames($iSurveyId); // Now find all responses for the visible tokens $visibleTokens = array(); $answeredTokens = array(); if ($aSurveyInfo['anonymized'] == "N" && $aSurveyInfo['active'] == "Y") { foreach ($tokens as $token) { if (isset($token['token']) && $token['token']) { $visibleTokens[] = $token['token']; } } $answers = SurveyDynamic::model($iSurveyId)->findAllByAttributes(array('token' => $visibleTokens)); foreach ($answers as $answer) { $answeredTokens[$answer['token']] = $answer['token']; } } $bReadPermission = Permission::model()->hasSurveyPermission($iSurveyId, 'responses', 'read'); $bCreatePermission = Permission::model()->hasSurveyPermission($iSurveyId, 'responses', 'create'); $bTokenUpdatePermission = Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update'); $bTokenDeletePermission = Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'delete'); $bGlobalPanelReadPermission = Permission::model()->hasGlobalPermission('participantpanel', 'read'); foreach ($tokens as $token) { $aRowToAdd = array(); if ((int) $token['validfrom']) { $token['validfrom'] = date($format['phpdate'] . ' H:i', strtotime(trim($token['validfrom']))); } else { $token['validfrom'] = ''; } if ((int) $token['validuntil']) { $token['validuntil'] = date($format['phpdate'] . ' H:i', strtotime(trim($token['validuntil']))); } else { $token['validuntil'] = ''; } $aRowToAdd['id'] = $token['tid']; $action = ""; $action .= "<div class='inputbuttons'>"; // so we can hide this when edit is clicked // Check is we have an answer if (in_array($token['token'], $answeredTokens) && $bReadPermission) { // @@TODO change link $url = $this->getController()->createUrl("admin/responses/sa/browse/surveyid/{$iSurveyId}", array('token' => $token['token'])); $title = $clang->gT("View response details"); $action .= CHtml::link(CHtml::image(Yii::app()->getConfig('adminimageurl') . 'token_viewanswer.png', $title, array('title' => $title)), $url, array('class' => 'imagelink')); } else { $action .= '<div style="width: 20px; height: 16px; float: left;"></div>'; } // Check if the token can be taken if ($token['token'] != "" && ($token['completed'] == "N" || $token['completed'] == "" || $aSurveyInfo['alloweditaftercompletion'] == "Y") && $bCreatePermission) { $action .= viewHelper::getImageLink('do_16.png', "survey/index/sid/{$iSurveyId}/token/{$token['token']}/lang/{$token['language']}/newtest/Y", $clang->gT("Do survey"), '_blank'); } else { $action .= '<div style="width: 20px; height: 16px; float: left;"></div>'; } if ($bTokenDeletePermission) { $attribs = array('onclick' => 'if (confirm("' . $clang->gT("Are you sure you want to delete this entry?") . ' (' . $token['tid'] . ')")) {$("#displaytokens").delRowData(' . $token['tid'] . ');$.post(delUrl,{tid:' . $token['tid'] . '});}'); $action .= viewHelper::getImageLink('token_delete.png', null, $clang->gT("Delete token entry"), null, 'imagelink btnDelete', $attribs); } if (strtolower($token['emailstatus']) == 'ok' && $token['email'] && $bTokenUpdatePermission) { if ($token['completed'] == 'N' && $token['usesleft'] > 0) { if ($token['sent'] == 'N') { $action .= viewHelper::getImageLink('token_invite.png', "admin/tokens/sa/email/surveyid/{$iSurveyId}/tokenids/" . $token['tid'], $clang->gT("Send invitation email to this person (if they have not yet been sent an invitation email)"), "_blank"); } else { $action .= viewHelper::getImageLink('token_remind.png', "admin/tokens/sa/email/action/remind/surveyid/{$iSurveyId}/tokenids/" . $token['tid'], $clang->gT("Send reminder email to this person (if they have already received the invitation email)"), "_blank"); } } else { $action .= '<div style="width: 20px; height: 16px; float: left;"></div>'; } } else { $action .= '<div style="width: 20px; height: 16px; float: left;"></div>'; } if ($bTokenUpdatePermission) { $action .= viewHelper::getImageLink('edit_16.png', null, $clang->gT("Edit token entry"), null, 'imagelink token_edit'); } if (!empty($token['participant_id']) && $token['participant_id'] != "" && $bGlobalPanelReadPermission) { $action .= viewHelper::getImageLink('cpdb_16.png', null, $clang->gT("View this person in the central participants database"), null, 'imagelink cpdb', array('onclick' => "sendPost('" . $this->getController()->createUrl('admin/participants/sa/displayParticipants') . "','',['searchcondition'],['participant_id||equal||{$token['participant_id']}']);")); } else { $action .= '<div style="width: 20px; height: 16px; float: left;"></div>'; } $action .= '</div>'; $aRowToAdd['cell'] = array($token['tid'], $action, $token['firstname'], $token['lastname'], $token['email'], $token['emailstatus'], $token['token'], $token['language'], $token['sent'], $token['remindersent'], $token['remindercount'], $token['completed'], $token['usesleft'], $token['validfrom'], $token['validuntil']); foreach ($attributes as $attribute) { $aRowToAdd['cell'][] = $token[$attribute]; } $aData->rows[] = $aRowToAdd; } viewHelper::disableHtmlLogging(); header("Content-type: application/json"); echo ls_json_encode($aData); }
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>"; } }
/** * 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); global $oTemplate; $sTemplatePath = $oTemplate->path; $sTemplateViewPath = $oTemplate->viewPath; //$sTemplatePath=getTemplatePath(Yii::app()->getConfig("defaulttemplate")).DIRECTORY_SEPARATOR; // TODO : check if necessary : /* 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(App()->language) ? App()->language : $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); //TODO : check if necessary //$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::NavigateForwards(); //$_SESSION[$LEMsessid]['step']=1; } } elseif ($surveyid != LimeExpressionManager::getLEMsurveyId()) { $_SESSION[$LEMsessid]['step'] = $_SESSION[$LEMsessid]['step'] < 0 ? 0 : $_SESSION[$LEMsessid]['step']; //$_SESSION[$LEMsessid]['step'] can not be less than 0, fix it always #09772 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 = 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=gT("Clear all need confirmation."); } if (isset($move)) { if (!in_array($move, array("clearall", "changelang", "saveall", "reload"))) { $_SESSION[$LEMsessid]['prevstep'] = $_SESSION[$LEMsessid]['step']; } else { // Accepted $move without error $_SESSION[$LEMsessid]['prevstep'] = $move; } } else { //$_SESSION[$LEMsessid]['prevstep'] = $_SESSION[$LEMsessid]['step']-1; // Is this needed ? } if (!isset($_SESSION[$LEMsessid]['prevstep'])) { $_SESSION[$LEMsessid]['prevstep'] = $_SESSION[$LEMsessid]['step'] - 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 if ($thissurvey['questionindex'] == 2) { // Must : save actual page , review whole before set finished to true (see #09906), index==1 seems to don't need it : (don't force move) LimeExpressionManager::StartSurvey($surveyid, $surveyMode, $surveyOptions); } $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 && $move != 'movesubmit' && $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($sTemplateViewPath . "startpage.pstpl"), array(), $redata, 'SubmitStartpageI', false, NULL, array(), true); //Check for assessments if ($thissurvey['assessments'] == "Y" && $assessments) { echo templatereplace(file_get_contents($sTemplateViewPath . "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'>" . gT("Did Not Save") . "</font></strong><br /><br />\n\n"; $completed .= 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") . "'>" . 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($sTemplateViewPath . "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($sTemplateViewPath . "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($sTemplateViewPath . "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($sTemplateViewPath . "assessment.pstpl"), array(), $redata, 'SubmitAssessment', false, NULL, array(), true); } } if (trim(str_replace(array('<p>', '</p>'), '', $thissurvey['surveyls_endtext'])) == '') { $completed = "<br /><span class='success'>" . gT("Thank you!") . "</span><br /><br />\n\n" . 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'>" . gT("Print your answers.") . "</a><br />\n"; } //***************************************** if ($thissurvey['publicstatistics'] == 'Y' && $thissurvey['printanswers'] == 'Y') { $completed .= '<br />' . 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'>" . 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($sTemplateViewPath . "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($sTemplateViewPath . "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($sTemplateViewPath . "startpage.pstpl"), array(), $redata); echo "\t<center><br />\n"; echo "\t" . gT("Sorry. There is no matching survey.") . "<br /></center> \n"; echo templatereplace(file_get_contents($sTemplateViewPath . "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 gT('Invalid group number for this survey: ') . $_gid; exit; } $moveResult = LimeExpressionManager::JumpTo($gseq + 1, true); if (is_null($moveResult)) { echo 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 = gT("Submit your answers"); $groupdescription = 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 //// To diplay one question, all the questions are processed ? 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]); 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(); /** * Question Index */ $aQuestionindexbuttons = null; $aQuestionindexbuttonsmenu = null; if (!$previewgrp && !$previewquestion) { if ($surveyMode != 'survey' && $thissurvey['questionindex'] == 1) { //$aQuestionindex = $this->createIncrementalQuestionIndex($LEMsessid, $surveyMode); $aQuestionindexmenu = $this->createIncrementalQuestionIndexMenu($LEMsessid, $surveyMode); } elseif ($surveyMode != 'survey' && $thissurvey['questionindex'] == 2) { //$aQuestionindex = $this->createFullQuestionIndex($LEMsessid, $surveyMode); $aQuestionindexmenu = $this->createFullQuestionIndexMenu($LEMsessid, $surveyMode); } //$questionindex = (isset($aQuestionindex['menulist']))?$aQuestionindex['menulist']:''; $questionindexmenu = isset($aQuestionindexmenu['menulist']) ? $aQuestionindexmenu['menulist'] : ''; //$aQuestionindexbuttons = (isset($aQuestionindex['buttons']))?$aQuestionindex['buttons']:''; $aQuestionindexbuttonsmenu = isset($aQuestionindexmenu['buttons']) ? $aQuestionindexmenu['buttons'] : ''; } ///////////////////////////////// // First call to templatereplace echo "<!-- SurveyRunTimeHelper -->"; $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplateViewPath . "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", "sid" => $surveyid), 'post', array('enctype' => 'multipart/form-data', 'id' => 'limesurvey', 'name' => 'limesurvey', 'autocomplete' => 'off', 'class' => 'survey-form-container surveyRunTimeUploadFile')) . "\n\n <!-- INPUT NAMES -->\n <input type='hidden' name='fieldnames' value='{$hiddenfieldnames}' id='fieldnames' />\n"; } else { echo CHtml::form(array("/survey/index", "sid" => $surveyid), 'post', array('id' => 'limesurvey', 'name' => 'limesurvey', 'autocomplete' => 'off', 'class' => 'survey-form-container surveyRunTime')) . "\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($sTemplateViewPath . "welcome.pstpl"), array(), $redata) . "\n"; } if ($thissurvey['anonymized'] == "Y") { echo templatereplace(file_get_contents($sTemplateViewPath . "privacy.pstpl"), array(), $redata) . "\n"; } } // <-- START THE SURVEY --> if ($surveyMode != 'survey') { echo templatereplace(file_get_contents($sTemplateViewPath . "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 alert alert-danger' role='alert'>" . 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 alert alert-danger' role='alert'>" . 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 alert alert-danger' role='alert'>" . 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 (in SurveyRunTime ) -->\n"; echo "\n\n<div id='group-{$_gseq}'"; $gnoshow = LimeExpressionManager::GroupIsIrrelevantOrHidden($_gseq); if ($gnoshow && !$previewgrp) { echo " style='display: none;'"; } echo " class='row'>\n"; echo templatereplace(file_get_contents($sTemplateViewPath . "startgroup.pstpl"), array(), $redata); echo "\n"; if (!$previewquestion && trim($redata['groupdescription']) == "") { echo templatereplace(file_get_contents($sTemplateViewPath . "groupdescription.pstpl"), array(), $redata); } echo "\n"; echo "\n\n<!-- PRESENT THE QUESTIONS (in SurveyRunTime ) -->\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]; $n_q_display = ''; if ($qinfo['hidden'] && $qinfo['info']['type'] != '*') { continue; // skip this one } $aReplacement = array(); $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['sgq'] = $qa[7]; $question['aid'] = !empty($qinfo['info']['aid']) ? $qinfo['info']['aid'] : 0; $question['sqid'] = !empty($qinfo['info']['sqid']) ? $qinfo['info']['sqid'] : 0; //=================================================================== $question_template = file_get_contents($sTemplateViewPath . 'question.pstpl'); // Fix old template : can we remove it ? Old template are surely already broken by another issue 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); $question_template = "<div {QUESTION_ESSENTIALS} class='{QUESTION_CLASS} {QUESTION_MAN_CLASS} {QUESTION_INPUT_ERROR_CLASS}'" . $question_template . "</div>"; } $redata = compact(array_keys(get_defined_vars())); $aQuestionReplacement = $this->getQuestionReplacement($qa); echo templatereplace($question_template, $aQuestionReplacement, $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($sTemplateViewPath . "endgroup.pstpl"), array(), $redata); echo "\n\n</div>\n"; Yii::app()->setConfig('gid', ''); } LimeExpressionManager::FinishProcessingGroup($LEMskipReprocessing); echo LimeExpressionManager::GetRelevanceAndTailoringJavaScript(); LimeExpressionManager::FinishProcessingPage(); /** * Navigator */ if (!$previewgrp && !$previewquestion) { $aNavigator = surveymover(); $moveprevbutton = $aNavigator['sMovePrevButton']; $movenextbutton = $aNavigator['sMoveNextButton']; $navigator = $moveprevbutton . ' ' . $movenextbutton; $redata = compact(array_keys(get_defined_vars())); echo "\n\n<!-- PRESENT THE NAVIGATOR -->\n"; echo templatereplace(file_get_contents($sTemplateViewPath . "navigator.pstpl"), array(), $redata); echo "\n"; if ($thissurvey['active'] != "Y") { echo "<p style='text-align:center' class='error'>" . 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); $this->createIncrementalQuestionIndexMenu($LEMsessid, $surveyMode); } elseif ($surveyMode != 'survey' && $thissurvey['questionindex'] == 2) { $this->createFullQuestionIndex($LEMsessid, $surveyMode); $this->createFullQuestionIndexMenu($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($sTemplateViewPath . "endpage.pstpl"), array(), $redata); echo "\n"; doFooter(); }
function loadanswers() { Yii::trace('start', 'survey.loadanswers'); global $surveyid; global $thissurvey, $thisstep; global $clienttoken; $clang = Yii::app()->lang; $scid = Yii::app()->request->getQuery('scid'); if (Yii::app()->request->getParam('loadall') == "reload") { $sLoadName = Yii::app()->request->getParam('loadname'); $sLoadPass = Yii::app()->request->getParam('loadpass'); $oCriteria = new CDbCriteria(); $oCriteria->join = "LEFT JOIN {{saved_control}} ON t.id={{saved_control}}.srid"; $oCriteria->condition = "{{saved_control}}.sid=:sid"; $aParams = array(':sid' => $surveyid); if (isset($scid)) { $oCriteria->addCondition("{{saved_control}}.scid=:scid"); $aParams[':scid'] = $scid; } $oCriteria->addCondition("{{saved_control}}.identifier=:identifier"); $aParams[':identifier'] = $sLoadName; if (in_array(Yii::app()->db->getDriverName(), array('mssql', 'sqlsrv', 'dblib'))) { // To be validated with mssql, think it's not needed $oCriteria->addCondition(" CAST({{saved_control}}.access_code as varchar(32))=:access_code"); } else { $oCriteria->addCondition("{{saved_control}}.access_code=:access_code"); } $aParams[':access_code'] = md5($sLoadPass); } elseif (isset($_SESSION['survey_' . $surveyid]['srid'])) { $oCriteria = new CDbCriteria(); $oCriteria->condition = "id=:id"; $aParams = array(':id' => $_SESSION['survey_' . $surveyid]['srid']); } else { return; } $oCriteria->params = $aParams; $oResponses = SurveyDynamic::model($surveyid)->find($oCriteria); if (!$oResponses) { return false; } else { //A match has been found. Let's load the values! //If this is from an email, build surveysession first $_SESSION['survey_' . $surveyid]['LEMtokenResume'] = true; // If survey come from reload (GET or POST); some value need to be found on saved_control, not on survey if (Yii::app()->request->getParam('loadall') == "reload") { $oSavedSurvey = SavedControl::model()->find("identifier=:identifier AND access_code=:access_code", array(":identifier" => $sLoadName, ":access_code" => md5($sLoadPass))); // We don't need to control if we have one, because we do the test before $_SESSION['survey_' . $surveyid]['scid'] = $oSavedSurvey->scid; $_SESSION['survey_' . $surveyid]['step'] = $oSavedSurvey->saved_thisstep > 1 ? $oSavedSurvey->saved_thisstep : 1; $thisstep = $_SESSION['survey_' . $surveyid]['step'] - 1; // deprecated ? $_SESSION['survey_' . $surveyid]['srid'] = $oSavedSurvey->srid; // Seems OK without $_SESSION['survey_' . $surveyid]['refurl'] = $oSavedSurvey->refurl; } // Get if survey is been answered $submitdate = $oResponses->submitdate; $aRow = $oResponses->attributes; foreach ($aRow as $column => $value) { if ($column == "token") { $clienttoken = $value; $token = $value; } elseif ($column == 'lastpage' && !isset($_SESSION['survey_' . $surveyid]['step'])) { if (is_null($submitdate) || $submitdate == "N") { $_SESSION['survey_' . $surveyid]['step'] = $value > 1 ? $value : 1; $thisstep = $_SESSION['survey_' . $surveyid]['step'] - 1; } else { $_SESSION['survey_' . $surveyid]['maxstep'] = $value > 1 ? $value : 1; } } elseif ($column == "datestamp") { $_SESSION['survey_' . $surveyid]['datestamp'] = $value; } if ($column == "startdate") { $_SESSION['survey_' . $surveyid]['startdate'] = $value; } else { //Only make session variables for those in insertarray[] if (in_array($column, $_SESSION['survey_' . $surveyid]['insertarray']) && isset($_SESSION['survey_' . $surveyid]['fieldmap'][$column])) { if (($_SESSION['survey_' . $surveyid]['fieldmap'][$column]['type'] == 'N' || $_SESSION['survey_' . $surveyid]['fieldmap'][$column]['type'] == 'K' || $_SESSION['survey_' . $surveyid]['fieldmap'][$column]['type'] == 'D') && $value == null) { // For type N,K,D NULL in DB is to be considered as NoAnswer in any case. // We need to set the _SESSION[field] value to '' in order to evaluate conditions. // This is especially important for the deletenonvalue feature, // otherwise we would erase any answer with condition such as EQUALS-NO-ANSWER on such // question types (NKD) $_SESSION['survey_' . $surveyid][$column] = ''; } else { $_SESSION['survey_' . $surveyid][$column] = $value; } } // if (in_array( } // else } // foreach return true; } }
/** * dataentry::insert() * insert new dataentry * @return */ public function insert() { $subaction = Yii::app()->request->getPost('subaction'); $surveyid = Yii::app()->request->getPost('sid'); $lang = isset($_POST['lang']) ? Yii::app()->request->getPost('lang') : NULL; $aData = array('surveyid' => $surveyid, 'lang' => $lang); if (Permission::model()->hasSurveyPermission($surveyid, 'responses', 'create')) { if ($subaction == "insert" && Permission::model()->hasSurveyPermission($surveyid, 'responses', 'create')) { $surveytable = "{{survey_{$surveyid}}}"; $thissurvey = getSurveyInfo($surveyid); $errormsg = ""; Yii::app()->loadHelper("database"); $aViewUrls['display']['menu_bars']['browse'] = gT("Data entry"); $aDataentryoutput = ''; $aDataentrymsgs = array(); $hiddenfields = ''; $lastanswfortoken = ''; // check if a previous answer has been submitted or saved $rlanguage = ''; if (Yii::app()->request->getPost('token') && Permission::model()->hasSurveyPermission($surveyid, 'tokens', 'update')) { $tokencompleted = ""; $tcquery = "SELECT completed from {{tokens_{$surveyid}}} WHERE token=" . dbQuoteAll($_POST['token']); $tcresult = dbExecuteAssoc($tcquery); $tcresult = $tcresult->readAll(); $tccount = count($tcresult); foreach ($tcresult as $tcrow) { $tokencompleted = $tcrow['completed']; } if ($tccount < 1) { // token doesn't exist in token table $lastanswfortoken = 'UnknownToken'; } elseif ($thissurvey['anonymized'] == "Y") { // token exist but survey is anonymous, check completed state if ($tokencompleted != "" && $tokencompleted != "N") { // token is completed $lastanswfortoken = 'PrivacyProtected'; } } else { // token is valid, survey not anonymous, try to get last recorded response id $aquery = "SELECT id,startlanguage FROM {$surveytable} WHERE token=" . dbQuoteAll($_POST['token']); $aresult = dbExecuteAssoc($aquery); foreach ($aresult->readAll() as $arow) { if ($tokencompleted != "N") { $lastanswfortoken = $arow['id']; } $rlanguage = $arow['startlanguage']; } } } // First Check if the survey uses tokens and if a token has been provided if (tableExists('{{tokens_' . $thissurvey['sid'] . '}}') && !$_POST['token']) { $errormsg = CHtml::tag('div', array('class' => 'warningheader'), gT("Error")); $errormsg .= CHtml::tag('p', array(), gT("This is a closed-access survey, so you must supply a valid token. Please contact the administrator for assistance.")); } elseif (tableExists('{{tokens_' . $thissurvey['sid'] . '}}') && $lastanswfortoken == 'UnknownToken') { $errormsg = CHtml::tag('div', array('class' => 'warningheader'), gT("Error")); $errormsg .= CHtml::tag('p', array(), gT("The token you have provided is not valid or has already been used.")); } elseif (tableExists('{{tokens_' . $thissurvey['sid'] . '}}') && $lastanswfortoken != '') { $errormsg = CHtml::tag('div', array('class' => 'warningheader'), gT("Error")); $errormsg .= CHtml::tag('p', array(), gT("There is already a recorded answer for this token")); if ($lastanswfortoken != 'PrivacyProtected') { $errormsg .= "<br /><br />" . gT("Follow the following link to update it") . ":\n"; $errormsg .= CHtml::link("[id:{$lastanswfortoken}]", $this->getController()->createUrl('/admin/dataentry/sa/editdata/subaction/edit/id/' . $lastanswfortoken . '/surveyid/' . $surveyid . '/lang/' . $rlanguage), array('title' => gT("Edit this entry"))); $errormsg .= "<br/><br/>"; } else { $errormsg .= "<br /><br />" . gT("This surveys uses anonymized responses, so you can't update your response.") . "\n"; } } else { $last_db_id = 0; if (isset($_POST['save']) && $_POST['save'] == "on") { $aData['save'] = TRUE; $saver['identifier'] = $_POST['save_identifier']; $saver['language'] = $_POST['save_language']; $saver['password'] = $_POST['save_password']; $saver['passwordconfirm'] = $_POST['save_confirmpassword']; $saver['email'] = $_POST['save_email']; if (!returnGlobal('redo')) { $password = md5($saver['password']); } else { $password = $saver['password']; } $errormsg = ""; if (!$saver['identifier']) { $errormsg .= gT("Error") . ": " . gT("You must supply a name for this saved session."); } if (!$saver['password']) { $errormsg .= gT("Error") . ": " . gT("You must supply a password for this saved session."); } if ($saver['password'] != $saver['passwordconfirm']) { $errormsg .= gT("Error") . ": " . gT("Your passwords do not match."); } $aData['errormsg'] = $errormsg; if ($errormsg) { foreach ($_POST as $key => $val) { if (substr($key, 0, 4) != "save" && $key != "action" && $key != "sid" && $key != "datestamp" && $key != "ipaddr") { $hiddenfields .= CHtml::hiddenField($key, $val); //$aDataentryoutput .= "<input type='hidden' name='$key' value='$val' />\n"; } } } } //BUILD THE SQL TO INSERT RESPONSES $baselang = Survey::model()->findByPk($surveyid)->language; $fieldmap = createFieldMap($surveyid, 'full', false, false, getBaseLanguageFromSurveyID($surveyid)); $insert_data = array(); $_POST['startlanguage'] = $baselang; if ($thissurvey['datestamp'] == "Y") { $_POST['startdate'] = $_POST['datestamp']; } if (isset($_POST['closerecord'])) { if ($thissurvey['datestamp'] == "Y") { $_POST['submitdate'] = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", Yii::app()->getConfig('timeadjust')); } else { $_POST['submitdate'] = date("Y-m-d H:i:s", mktime(0, 0, 0, 1, 1, 1980)); } } foreach ($fieldmap as $irow) { $fieldname = $irow['fieldname']; if (isset($_POST[$fieldname])) { if ($_POST[$fieldname] == "" && ($irow['type'] == 'D' || $irow['type'] == 'N' || $irow['type'] == 'K')) { // can't add '' in Date column // Do nothing } else { if ($irow['type'] == '|') { if (!strpos($irow['fieldname'], "_filecount")) { $json = $_POST[$fieldname]; $phparray = json_decode(stripslashes($json)); $filecount = 0; for ($i = 0; $filecount < count($phparray); $i++) { if ($_FILES[$fieldname . "_file_" . $i]['error'] != 4) { $target = Yii::app()->getConfig('uploaddir') . "/surveys/" . $thissurvey['sid'] . "/files/" . randomChars(20); $size = 0.001 * $_FILES[$fieldname . "_file_" . $i]['size']; $name = rawurlencode($_FILES[$fieldname . "_file_" . $i]['name']); if (move_uploaded_file($_FILES[$fieldname . "_file_" . $i]['tmp_name'], $target)) { $phparray[$filecount]->filename = basename($target); $phparray[$filecount]->name = $name; $phparray[$filecount]->size = $size; $pathinfo = pathinfo($_FILES[$fieldname . "_file_" . $i]['name']); $phparray[$filecount]->ext = $pathinfo['extension']; $filecount++; } } } $insert_data[$fieldname] = ls_json_encode($phparray); } else { $insert_data[$fieldname] = count($phparray); } } elseif ($irow['type'] == 'D') { Yii::app()->loadLibrary('Date_Time_Converter'); $qidattributes = getQuestionAttributeValues($irow['qid']); $dateformatdetails = getDateFormatDataForQID($qidattributes, $thissurvey); $datetimeobj = new Date_Time_Converter($_POST[$fieldname], $dateformatdetails['phpdate']); $insert_data[$fieldname] = $datetimeobj->convert("Y-m-d H:i:s"); } else { $insert_data[$fieldname] = $_POST[$fieldname]; } } } } SurveyDynamic::sid($surveyid); $new_response = new SurveyDynamic(); foreach ($insert_data as $column => $value) { $new_response->{$column} = $value; } $new_response->save(); $last_db_id = $new_response->getPrimaryKey(); if (isset($_POST['closerecord']) && isset($_POST['token']) && $_POST['token'] != '') { // get submit date if (isset($_POST['closedate'])) { $submitdate = $_POST['closedate']; } else { $submitdate = dateShift(date("Y-m-d H:i:s"), "Y-m-d", $timeadjust); } // check how many uses the token has left $usesquery = "SELECT usesleft FROM {{tokens_}}{$surveyid} WHERE token=" . dbQuoteAll($_POST['token']); $usesresult = dbExecuteAssoc($usesquery); $usesrow = $usesresult->readAll(); //$usesresult->row_array() if (isset($usesrow)) { $usesleft = $usesrow[0]['usesleft']; } // query for updating tokens $utquery = "UPDATE {{tokens_{$surveyid}}}\n"; if (isTokenCompletedDatestamped($thissurvey)) { if (isset($usesleft) && $usesleft <= 1) { $utquery .= "SET usesleft=usesleft-1, completed=" . dbQuoteAll($submitdate); } else { $utquery .= "SET usesleft=usesleft-1\n"; } } else { if (isset($usesleft) && $usesleft <= 1) { $utquery .= "SET usesleft=usesleft-1, completed='Y'\n"; } else { $utquery .= "SET usesleft=usesleft-1\n"; } } $utquery .= "WHERE token=" . dbQuoteAll($_POST['token']); $utresult = dbExecuteAssoc($utquery); //Yii::app()->db->Execute($utquery) or safeDie ("Couldn't update tokens table!<br />\n$utquery<br />\n".Yii::app()->db->ErrorMsg()); // save submitdate into survey table $sdquery = "UPDATE {{survey_{$surveyid}}} SET submitdate='" . $submitdate . "' WHERE id={$last_db_id}\n"; $sdresult = dbExecuteAssoc($sdquery) or safeDie("Couldn't set submitdate response in survey table!<br />\n{$sdquery}<br />\n"); } if (isset($_POST['save']) && $_POST['save'] == "on") { $srid = $last_db_id; $aUserData = Yii::app()->session; //CREATE ENTRY INTO "saved_control" $saved_control_table = '{{saved_control}}'; $columns = array("sid", "srid", "identifier", "access_code", "email", "ip", "refurl", 'saved_thisstep', "status", "saved_date"); $values = array("'" . $surveyid . "'", "'" . $srid . "'", "'" . $saver['identifier'] . "'", "'" . $password . "'", "'" . $saver['email'] . "'", "'" . $aUserData['ip_address'] . "'", "'" . getenv("HTTP_REFERER") . "'", 0, "'" . "S" . "'", "'" . dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", "'" . Yii::app()->getConfig('timeadjust')) . "'"); $SQL = "INSERT INTO {$saved_control_table}\n (" . implode(',', $columns) . ")\n VALUES\n (" . implode(',', $values) . ")"; /*$scdata = array("sid"=>$surveyid, "srid"=>$srid, "identifier"=>$saver['identifier'], "access_code"=>$password, "email"=>$saver['email'], "ip"=>$aUserData['ip_address'], "refurl"=>getenv("HTTP_REFERER"), 'saved_thisstep' => 0, "status"=>"S", "saved_date"=>dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", Yii::app()->getConfig('timeadjust'))); $this->load->model('saved_control_model');*/ if (dbExecuteAssoc($SQL)) { $scid = getLastInsertID('{{saved_control}}'); $aDataentrymsgs[] = CHtml::tag('font', array('class' => 'successtitle'), gT("Your survey responses have been saved successfully. You will be sent a confirmation e-mail. Please make sure to save your password, since we will not be able to retrieve it for you.")); //$aDataentryoutput .= "<font class='successtitle'></font><br />\n"; $tokens_table = "{{tokens_{$surveyid}}}"; if (tableExists($tokens_table)) { $tkquery = "SELECT * FROM {$tokens_table}"; $tkresult = dbExecuteAssoc($tkquery); /*$tokendata = array ( "firstname"=> $saver['identifier'], "lastname"=> $saver['identifier'], "email"=>$saver['email'], "token"=>randomChars(15), "language"=>$saver['language'], "sent"=>dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", $timeadjust), "completed"=>"N");*/ $columns = array("firstname", "lastname", "email", "token", "language", "sent", "completed"); $values = array("'" . $saver['identifier'] . "'", "'" . $saver['identifier'] . "'", "'" . $saver['email'] . "'", "'" . $password . "'", "'" . randomChars(15) . "'", "'" . $saver['language'] . "'", "'" . "N" . "'"); $SQL = "INSERT INTO {$token_table}\n (" . implode(',', $columns) . ")\n VALUES\n (" . implode(',', $values) . ")"; dbExecuteAssoc($SQL); $aDataentrymsgs[] = CHtml::tag('font', array('class' => 'successtitle'), gT("A token entry for the saved survey has been created too.")); //$aDataentryoutput .= "<font class='successtitle'></font><br />\n"; } if ($saver['email']) { //Send email if (validateEmailAddress($saver['email']) && !returnGlobal('redo')) { $subject = gT("Saved Survey Details"); $message = gT("Thank you for saving your survey in progress. The following details can be used to return to this survey and continue where you left off. Please keep this e-mail for your reference - we cannot retrieve the password for you."); $message .= "\n\n" . $thissurvey['name'] . "\n\n"; $message .= gT("Name") . ": " . $saver['identifier'] . "\n"; $message .= gT("Password") . ": " . $saver['password'] . "\n\n"; $message .= gT("Reload your survey by clicking on the following link (or pasting it into your browser):") . "\n"; $message .= Yii::app()->getController()->createAbsoluteUrl("/survey/index/sid/{$iSurveyID}/loadall/reload/scid/{$scid}/loadname/" . rawurlencode($saver['identifier']) . "/loadpass/" . rawurlencode($saver['password']) . "/lang/" . rawurlencode($saver['language'])); if (isset($tokendata['token'])) { $message .= "/token/" . rawurlencode($tokendata['token']); } $from = $thissurvey['adminemail']; if (SendEmailMessage($message, $subject, $saver['email'], $from, $sitename, false, getBounceEmail($surveyid))) { $emailsent = "Y"; $aDataentrymsgs[] = CHtml::tag('font', array('class' => 'successtitle'), gT("An email has been sent with details about your saved survey")); } } } } else { safeDie("Unable to insert record into saved_control table.<br /><br />"); } } $aData['thisid'] = $last_db_id; } $aData['errormsg'] = $errormsg; $aData['dataentrymsgs'] = $aDataentrymsgs; $aData['sidemenu']['state'] = false; $this->_renderWrappedTemplate('dataentry', 'insert', $aData); } } }
/** * Supply an array with the responseIds and all files will be added to the zip * and it will be be spit out on success * * @param array $responseIds * @param string $zipfilename * @param string $language * @return ZipArchive */ private function _zipFiles($iSurveyID, $responseIds, $zipfilename, $language) { Yii::app()->loadLibrary('admin/pclzip'); $tmpdir = Yii::app()->getConfig('uploaddir') . DIRECTORY_SEPARATOR . "surveys" . DIRECTORY_SEPARATOR . $iSurveyID . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR; $filelist = array(); $fieldmap = createFieldMap($iSurveyID, 'full', false, false, $language); foreach ($fieldmap as $field) { if ($field['type'] == "|" && $field['aid'] !== 'filecount') { $filequestion[] = $field['fieldname']; } } foreach ((array) $responseIds as $responseId) { $responseId = (int) $responseId; // sanitize the value $filearray = SurveyDynamic::model($iSurveyID)->findAllByAttributes(array('id' => $responseId)) or die('Could not download response'); $metadata = array(); $filecount = 0; foreach ($filearray as $metadata) { foreach ($metadata as $aData) { $phparray = json_decode_ls($aData); if (is_array($phparray)) { foreach ($phparray as $file) { $filecount++; $file['responseid'] = $responseId; $file['name'] = rawurldecode($file['name']); $file['index'] = $filecount; /* * Now add the file to the archive, prefix files with responseid_index to keep them * unique. This way we can have 234_1_image1.gif, 234_2_image1.gif as it could be * files from a different source with the same name. */ if (file_exists($tmpdir . $file['filename'])) { $filelist[] = array(PCLZIP_ATT_FILE_NAME => $tmpdir . $file['filename'], PCLZIP_ATT_FILE_NEW_FULL_NAME => sprintf("%05s_%02s_%s", $file['responseid'], $file['index'], $file['name'])); } } } } } } if (count($filelist) > 0) { // TODO: to extend the yii app function loadLibrary to meet the app requirements $zip = new PclZip($tmpdir . $zipfilename); if ($zip->create($filelist) === 0) { //Oops something has gone wrong! } if (file_exists($tmpdir . '/' . $zipfilename)) { @ob_clean(); header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . basename($zipfilename)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($tmpdir . "/" . $zipfilename)); readfile($tmpdir . '/' . $zipfilename); unlink($tmpdir . '/' . $zipfilename); exit; } } }