lang; $scid=returnGlobal('scid',true); if (Yii::app()->request->getParam('loadall') == "reload") { $query = "SELECT * FROM {{saved_control}} INNER JOIN {$thissurvey['tablename']} ON {{saved_control}}.srid = {$thissurvey['tablename']}.id WHERE {{saved_control}}.sid=$surveyid\n"; if (isset($scid)) //Would only come from email { $query .= "AND {{saved_control}}.scid={$scid}\n"; } $query .="AND {{saved_control}}.identifier = '".autoEscape($_SESSION['survey_'.$surveyid]['holdname'])."' "; if (in_array(Yii::app()->db->getDriverName(), array('mssql', 'sqlsrv', 'dblib'))) { $query .="AND CAST({{saved_control}}.access_code as varchar(32))= '".md5($_SESSION['survey_'.$surveyid]['holdpass'])."'\n"; } else { $query .="AND {{saved_control}}.access_code = '".md5($_SESSION['survey_'.$surveyid]['holdpass'])."'\n";// md5 don't need to be escaped } } elseif (isset($_SESSION['survey_'.$surveyid]['srid'])) { $query = "SELECT * FROM {$thissurvey['tablename']} WHERE {$thissurvey['tablename']}.id=".$_SESSION['survey_'.$surveyid]['srid']."\n"; } else { return; } $aRow = Yii::app()->db->createCommand($query)->queryRow();// TODO : use Yii for query if (!$aRow) { 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; // Get if survey is been answered $submitdate=$aRow['submitdate']; foreach ($aRow as $column => $value) { if ($column == "token") { $clienttoken=$value; $token=$value; } elseif ($column == "saved_thisstep" && $thissurvey['alloweditaftercompletion'] != 'Y' ) { $_SESSION['survey_'.$surveyid]['step']=($value>1? $value:1) ; $thisstep=$_SESSION['survey_'.$surveyid]['step']-1; } elseif ($column =='lastpage' && isset($_GET['token'])) { 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) ; } } /* Commented this part out because otherwise startlanguage would overwrite any other language during a running survey. We will need a new field named 'endlanguage' to save the current language (for example for returning participants) /the language the survey was completed in. elseif ($column =='startlanguage') { $clang = SetSurveyLanguage( $surveyid, $value); UpdateSessionGroupList($value); // to refresh the language strings in the group list session variable UpdateFieldArray(); // to refresh question titles and question text }*/ elseif ($column == "scid") { $_SESSION['survey_'.$surveyid]['scid']=$value; } elseif ($column == "srid") { $_SESSION['survey_'.$surveyid]['srid']=$value; } 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; } function makegraph($currentstep, $total) { global $thissurvey; $clang = Yii::app()->lang; Yii::app()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicstyleurl') . 'lime-progress.css'); $size = intval(($currentstep-1)/$total*100); $graph = '
'.sprintf($clang->gT('You have completed %s%% of this survey'),$size).'
'; if (getLanguageRTL($clang->langcode)) { $graph.='100%'; } else { $graph.='0%'; } $graph.='
'; if (getLanguageRTL($clang->langcode)) { $graph.='0%'; } else { $graph.='100%'; } $graph.='
'; if ($size == 0) // Progress bar looks dumb if 0 { $graph.=' '; } return $graph; } /** * This function creates the language selector for a particular survey * * @param mixed $sSelectedLanguage The language in which all information is shown */ function makeLanguageChangerSurvey($sSelectedLanguage) { $surveyid = Yii::app()->getConfig('surveyID'); $clang = Yii::app()->lang; Yii::app()->loadHelper("surveytranslator"); $aSurveyLangs = Survey::model()->findByPk($surveyid)->getAllLanguages(); if (count($aSurveyLangs)>1) // return a dropdow only of there are more than one lanagage { $aAllLanguages=getLanguageData(true); $aSurveyLangs=array_intersect_key($aAllLanguages,array_flip($aSurveyLangs)); // Sort languages by their locale name $sClass="languagechanger"; $sHTMLCode=""; $sAction=Yii::app()->request->getParam('action','');// Different behaviour if preview $sSelected=""; if(substr($sAction,0,7)=='preview') { $route="/survey/index/sid/{$surveyid}"; if ($sAction=='previewgroup' && intval(Yii::app()->request->getParam('gid',0))) { $route.="/action/previewgroup/gid/".intval(Yii::app()->request->getParam('gid',0)); } if ($sAction=='previewquestion' && intval(Yii::app()->request->getParam('gid',0)) && intval(Yii::app()->request->getParam('qid',0))) { $route.="/action/previewquestion/gid/".intval(Yii::app()->request->getParam('gid',0))."/qid/".intval(Yii::app()->request->getParam('qid',0)); } if (!is_null(Yii::app()->request->getParam('token'))) { $route.="/token/".Yii::app()->request->getParam('token'); } $sClass.=" previewmode"; // Maybe add other param (for prefilling by URL): then need a real createUrl with array # foreach ($aSurveyLangs as $sLangCode => $aSurveyLang) # { # $sTargetURL=Yii::app()->getController()->createUrl($route."/lang/$sLangCode"); # $aListLang[$sTargetURL]=html_entity_decode($aSurveyLang['nativedescription'], ENT_COMPAT,'UTF-8'); # if($clang->langcode==$sLangCode) # $sSelected=$sTargetURL; # } } else { $route="/survey/index/sid/{$surveyid}"; } $sTargetURL=Yii::app()->getController()->createUrl($route); foreach ($aSurveyLangs as $sLangCode => $aSurveyLang) { $aListLang[$sLangCode]=html_entity_decode($aSurveyLang['nativedescription'], ENT_COMPAT,'UTF-8'); } $sSelected=$clang->langcode; $sHTMLCode=CHtml::label($clang->gT("Choose another language"), 'lang',array('class'=>'hide label')); $sHTMLCode.=CHtml::dropDownList('lang', $sSelected,$aListLang,array('class'=>$sClass,'data-targeturl'=>$sTargetURL)); // We don't have to add this button if in previewmode $sHTMLCode.= CHtml::htmlButton($clang->gT("Change the language"),array('type'=>'submit','id'=>"changelangbtn",'value'=>'changelang','name'=>'changelang','class'=>'changelang jshide')); return $sHTMLCode; } else { return false; } } /** * This function creates the language selector for the public survey index page * * @param mixed $sSelectedLanguage The language in which all information is shown */ function makeLanguageChanger($sSelectedLanguage) { $aLanguages=getLanguageDataRestricted(true,$sSelectedLanguage);// Order by native if(count($aLanguages)>1) { # $sHTMLCode = "\n"; $clang = Yii::app()->lang; $sClass= "languagechanger"; foreach ($aLanguages as $sLangCode => $aLanguage) $aListLang[$sLangCode]=html_entity_decode($aLanguage['nativedescription'], ENT_COMPAT,'UTF-8').' - '.$aLanguage['description']; $sSelected=$sSelectedLanguage; $sHTMLCode= CHtml::beginForm(App()->createUrl('surveys/publiclist'),'get'); $sHTMLCode.=CHtml::label($clang->gT("Choose another language"), 'lang',array('class'=>'hide label')); $sHTMLCode.= CHtml::dropDownList('lang', $sSelected,$aListLang,array('class'=>$sClass)); //$sHTMLCode.= CHtml::htmlButton($clang->gT("Change the language"),array('type'=>'submit','id'=>"changelangbtn",'value'=>'changelang','name'=>'changelang','class'=>'jshide')); $sHTMLCode.=""; $sHTMLCode.= CHtml::endForm(); return $sHTMLCode; } else { return false; } } /** * checkUploadedFileValidity used in SurveyRuntimeHelper */ function checkUploadedFileValidity($surveyid, $move, $backok=null) { global $thisstep; $clang = Yii::app()->lang; if (!isset($backok) || $backok != "Y") { $fieldmap = createFieldMap($surveyid,'full',false,false,$_SESSION['survey_'.$surveyid]['s_lang']); if (isset($_POST['fieldnames']) && $_POST['fieldnames']!="") { $fields = explode("|", $_POST['fieldnames']); foreach ($fields as $field) { if ($fieldmap[$field]['type'] == "|" && !strrpos($fieldmap[$field]['fieldname'], "_filecount")) { $validation= getQuestionAttributeValues($fieldmap[$field]['qid']); $filecount = 0; $json = $_POST[$field]; // if name is blank, its basic, hence check // else, its ajax, don't check, bypass it. if ($json != "" && $json != "[]") { $phparray = json_decode(stripslashes($json)); if ($phparray[0]->size != "") { // ajax $filecount = count($phparray); } else { // basic for ($i = 1; $i <= $validation['max_num_of_files']; $i++) { if (!isset($_FILES[$field."_file_".$i]) || $_FILES[$field."_file_".$i]['name'] == '') continue; $filecount++; $file = $_FILES[$field."_file_".$i]; // File size validation if ($file['size'] > $validation['max_filesize'] * 1000) { $filenotvalidated = array(); $filenotvalidated[$field."_file_".$i] = sprintf($clang->gT("Sorry, the uploaded file (%s) is larger than the allowed filesize of %s KB."), $file['size'], $validation['max_filesize']); $append = true; } // File extension validation $pathinfo = pathinfo(basename($file['name'])); $ext = $pathinfo['extension']; $validExtensions = explode(",", $validation['allowed_filetypes']); if (!(in_array($ext, $validExtensions))) { if (isset($append) && $append) { $filenotvalidated[$field."_file_".$i] .= sprintf($clang->gT("Sorry, only %s extensions are allowed!"),$validation['allowed_filetypes']); unset($append); } else { $filenotvalidated = array(); $filenotvalidated[$field."_file_".$i] .= sprintf($clang->gT("Sorry, only %s extensions are allowed!"),$validation['allowed_filetypes']); } } } } } else $filecount = 0; if (isset($validation['min_num_of_files']) && $filecount < $validation['min_num_of_files'] && LimeExpressionManager::QuestionIsRelevant($fieldmap[$field]['qid'])) { $filenotvalidated = array(); $filenotvalidated[$field] = $clang->gT("The minimum number of files has not been uploaded."); } } } } if (isset($filenotvalidated)) { if (isset($move) && $move == "moveprev") $_SESSION['survey_'.$surveyid]['step'] = $thisstep; if (isset($move) && $move == "movenext") $_SESSION['survey_'.$surveyid]['step'] = $thisstep; return $filenotvalidated; } } if (!isset($filenotvalidated)) return false; else return $filenotvalidated; } /** * Takes two single element arrays and adds second to end of first if value exists * Why not use array_merge($array1,array_filter($array2); */ function addtoarray_single($array1, $array2) { // if (is_array($array2)) { foreach ($array2 as $ar) { if ($ar && $ar !== null) { $array1[]=$ar; } } } return $array1; } /** * Marks a tokens as completed and sends a confirmation email to the participiant. * If $quotaexit is set to true then the user exited the survey due to a quota * restriction and the according token is only marked as 'Q' * * @param mixed $quotaexit */ function submittokens($quotaexit=false) { $surveyid=Yii::app()->getConfig('surveyID'); if(isset($_SESSION['survey_'.$surveyid]['s_lang'])) { $thissurvey=getSurveyInfo($surveyid,$_SESSION['survey_'.$surveyid]['s_lang']); } else { $thissurvey=getSurveyInfo($surveyid); } $clienttoken = $_SESSION['survey_'.$surveyid]['token']; $sitename = Yii::app()->getConfig("sitename"); $emailcharset = Yii::app()->getConfig("emailcharset"); // Shift the date due to global timeadjust setting $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust")); // check how many uses the token has left $token = Token::model($surveyid)->findByAttributes(array('token' => $clienttoken)); if ($quotaexit==true) { $token->completed = 'Q'; $token->usesleft--; } else { if ($token->usesleft <= 1) { // Finish the token if (isTokenCompletedDatestamped($thissurvey)) { $token->completed = $today; } else { $token->completed = 'Y'; } if(isset($token->participant_id)) { $slquery = SurveyLink::model()->find('participant_id = :pid AND survey_id = :sid AND token_id = :tid', array(':pid'=> $token->participant_id, ':sid'=>$surveyid, ':tid'=>$token->tid)); if ($slquery) { if (isTokenCompletedDatestamped($thissurvey)) { $slquery->date_completed = $today; } else { // Update the survey_links table if necessary, to protect anonymity, use the date_created field date $slquery->date_completed = $slquery->date_created; } $slquery->save(); } } } $token->usesleft--; } $token->save(); if ($quotaexit==false) { if ($token && trim(strip_tags($thissurvey['email_confirm'])) != "" && $thissurvey['sendconfirmation'] == "Y") { // if($token->completed == "Y" || $token->completed == $today) // { $from = "{$thissurvey['adminname']} <{$thissurvey['adminemail']}>"; $to = $token->email; $subject=$thissurvey['email_confirm_subj']; $aReplacementVars=array(); $aReplacementVars["ADMINNAME"]=$thissurvey['admin']; $aReplacementVars["ADMINEMAIL"]=$thissurvey['adminemail']; $aReplacementVars['ADMINEMAIL'] = $thissurvey['adminemail']; //Fill with token info, because user can have his information with anonimity control $aReplacementVars["FIRSTNAME"]=$token->firstname; $aReplacementVars["LASTNAME"]=$token->lastname; $aReplacementVars["TOKEN"]=$token->token; // added survey url in replacement vars $surveylink = Yii::app()->createAbsoluteUrl("/survey/index/sid/{$surveyid}",array('lang'=>$_SESSION['survey_'.$surveyid]['s_lang'],'token'=>$token->token)); $aReplacementVars['SURVEYURL'] = $surveylink; $attrfieldnames=getAttributeFieldNames($surveyid); foreach ($attrfieldnames as $attr_name) { $aReplacementVars[strtoupper($attr_name)] = $token->$attr_name; } $dateformatdatat=getDateFormatData($thissurvey['surveyls_dateformat']); $numberformatdatat = getRadixPointData($thissurvey['surveyls_numberformat']); $redata=array('thissurvey'=>$thissurvey); $subject=templatereplace($subject,$aReplacementVars,$redata); $subject=html_entity_decode($subject,ENT_QUOTES,$emailcharset); if (getEmailFormat($surveyid) == 'html') { $ishtml=true; } else { $ishtml=false; } $message=$thissurvey['email_confirm']; //$message=ReplaceFields($message, $fieldsarray, true); $message=templatereplace($message,$aReplacementVars,$redata); if (!$ishtml) { $message=strip_tags(breakToNewline(html_entity_decode($message,ENT_QUOTES,$emailcharset))); } else { $message=html_entity_decode($message,ENT_QUOTES, $emailcharset ); } //Only send confirmation email if there is a valid email address if (validateEmailAddress($to)) { $aAttachments = unserialize($thissurvey['attachments']); $aRelevantAttachments = array(); /* * Iterate through attachments and check them for relevance. */ if (isset($aAttachments['confirmation'])) { foreach ($aAttachments['confirmation'] as $aAttachment) { $relevance = $aAttachment['relevance']; // If the attachment is relevant it will be added to the mail. if (LimeExpressionManager::ProcessRelevance($relevance) && file_exists($aAttachment['url'])) { $aRelevantAttachments[] = $aAttachment['url']; } } } SendEmailMessage($message, $subject, $to, $from, $sitename, $ishtml, null, $aRelevantAttachments); } // } else { // Leave it to send optional confirmation at closed token // } } } } /** * Send a submit notification to the email address specified in the notifications tab in the survey settings */ function sendSubmitNotifications($surveyid) { // @todo: Remove globals global $thissurvey, $maildebug, $tokensexist; if (trim($thissurvey['adminemail'])=='') { return; } $homeurl=Yii::app()->createAbsoluteUrl('/admin'); $clang = Yii::app()->lang; $sitename = Yii::app()->getConfig("sitename"); $debug=Yii::app()->getConfig('debug'); $bIsHTML = ($thissurvey['htmlemail'] == 'Y'); $aReplacementVars=array(); if ($thissurvey['allowsave'] == "Y" && isset($_SESSION['survey_'.$surveyid]['scid'])) { $aReplacementVars['RELOADURL']="".Yii::app()->getController()->createUrl("/survey/index/sid/{$surveyid}/loadall/reload/scid/".$_SESSION['survey_'.$surveyid]['scid']."/loadname/".urlencode($_SESSION['survey_'.$surveyid]['holdname'])."/loadpass/".urlencode($_SESSION['survey_'.$surveyid]['holdpass'])."/lang/".urlencode($clang->langcode)); if ($bIsHTML) { $aReplacementVars['RELOADURL']="{$aReplacementVars['RELOADURL']}"; } } else { $aReplacementVars['RELOADURL']=''; } if (!isset($_SESSION['survey_'.$surveyid]['srid'])) $srid = null; else $srid = $_SESSION['survey_'.$surveyid]['srid']; $aReplacementVars['ADMINNAME'] = $thissurvey['adminname']; $aReplacementVars['ADMINEMAIL'] = $thissurvey['adminemail']; $aReplacementVars['VIEWRESPONSEURL']=Yii::app()->createAbsoluteUrl("/admin/responses/sa/view/surveyid/{$surveyid}/id/{$srid}"); $aReplacementVars['EDITRESPONSEURL']=Yii::app()->createAbsoluteUrl("/admin/dataentry/sa/editdata/subaction/edit/surveyid/{$surveyid}/id/{$srid}"); $aReplacementVars['STATISTICSURL']=Yii::app()->createAbsoluteUrl("/admin/statistics/sa/index/surveyid/{$surveyid}"); if ($bIsHTML) { $aReplacementVars['VIEWRESPONSEURL']="{$aReplacementVars['VIEWRESPONSEURL']}"; $aReplacementVars['EDITRESPONSEURL']="{$aReplacementVars['EDITRESPONSEURL']}"; $aReplacementVars['STATISTICSURL']="{$aReplacementVars['STATISTICSURL']}"; } $aReplacementVars['ANSWERTABLE']=''; $aEmailResponseTo=array(); $aEmailNotificationTo=array(); $sResponseData=""; if (!empty($thissurvey['emailnotificationto'])) { $aRecipient=explode(";", ReplaceFields($thissurvey['emailnotificationto'],array('ADMINEMAIL' =>$thissurvey['adminemail'] ), true)); foreach($aRecipient as $sRecipient) { if(validateEmailAddress($sRecipient)) { $aEmailNotificationTo[]=$sRecipient; } } } if (!empty($thissurvey['emailresponseto'])) { // there was no token used so lets remove the token field from insertarray if (!isset($_SESSION['survey_'.$surveyid]['token']) && $_SESSION['survey_'.$surveyid]['insertarray'][0]=='token') { unset($_SESSION['survey_'.$surveyid]['insertarray'][0]); } //Make an array of email addresses to send to $aRecipient=explode(";", ReplaceFields($thissurvey['emailresponseto'],array('ADMINEMAIL' =>$thissurvey['adminemail'] ), true)); foreach($aRecipient as $sRecipient) { if(validateEmailAddress($sRecipient)) { $aEmailResponseTo[]=$sRecipient; } } $aFullResponseTable=getFullResponseTable($surveyid,$_SESSION['survey_'.$surveyid]['srid'],$_SESSION['survey_'.$surveyid]['s_lang']); $ResultTableHTML = "\n"; $ResultTableText ="\n\n"; $oldgid = 0; $oldqid = 0; foreach ($aFullResponseTable as $sFieldname=>$fname) { if (substr($sFieldname,0,4)=='gid_') { $ResultTableHTML .= "\t\n"; $ResultTableText .="\n{$fname[0]}\n\n"; } elseif (substr($sFieldname,0,4)=='qid_') { $ResultTableHTML .= "\t\n"; $ResultTableText .="\n{$fname[0]}\n"; } else { $ResultTableHTML .= "\t"; $ResultTableText .=" {$fname[0]} {$fname[1]}: {$fname[2]}\n"; } } $ResultTableHTML .= "
{$fname[0]}
{$fname[0]}
{$fname[0]} {$fname[1]}{$fname[2]}
\n"; $ResultTableText .= "\n\n"; if ($bIsHTML) { $aReplacementVars['ANSWERTABLE']=$ResultTableHTML; } else { $aReplacementVars['ANSWERTABLE']=$ResultTableText; } } $sFrom = $thissurvey['adminname'].' <'.$thissurvey['adminemail'].'>'; $aAttachments = unserialize($thissurvey['attachments']); $aRelevantAttachments = array(); /* * Iterate through attachments and check them for relevance. */ if (isset($aAttachments['admin_notification'])) { foreach ($aAttachments['admin_notification'] as $aAttachment) { $relevance = $aAttachment['relevance']; // If the attachment is relevant it will be added to the mail. if (LimeExpressionManager::ProcessRelevance($relevance) && file_exists($aAttachment['url'])) { $aRelevantAttachments[] = $aAttachment['url']; } } } $redata=compact(array_keys(get_defined_vars())); if (count($aEmailNotificationTo)>0) { $sMessage=templatereplace($thissurvey['email_admin_notification'],$aReplacementVars,$redata,'frontend_helper[1398]',($thissurvey['anonymized'] == "Y"),NULL, array(), true); $sSubject=templatereplace($thissurvey['email_admin_notification_subj'],$aReplacementVars,$redata,'frontend_helper[1399]',($thissurvey['anonymized'] == "Y"),NULL, array(), true); foreach ($aEmailNotificationTo as $sRecipient) { if (!SendEmailMessage($sMessage, $sSubject, $sRecipient, $sFrom, $sitename, true, getBounceEmail($surveyid), $aRelevantAttachments)) { if ($debug>0) { echo '
Email could not be sent. Reason: '.$maildebug.'
'; } } } } $aRelevantAttachments = array(); /* * Iterate through attachments and check them for relevance. */ if (isset($aAttachments['detailed_admin_notification'])) { foreach ($aAttachments['detailed_admin_notification'] as $aAttachment) { $relevance = $aAttachment['relevance']; // If the attachment is relevant it will be added to the mail. if (LimeExpressionManager::ProcessRelevance($relevance) && file_exists($aAttachment['url'])) { $aRelevantAttachments[] = $aAttachment['url']; } } } if (count($aEmailResponseTo)>0) { $sMessage=templatereplace($thissurvey['email_admin_responses'],$aReplacementVars,$redata,'frontend_helper[1414]',($thissurvey['anonymized'] == "Y")); $sSubject=templatereplace($thissurvey['email_admin_responses_subj'],$aReplacementVars,$redata,'frontend_helper[1415]',($thissurvey['anonymized'] == "Y")); foreach ($aEmailResponseTo as $sRecipient) { if (!SendEmailMessage($sMessage, $sSubject, $sRecipient, $sFrom, $sitename, true, getBounceEmail($surveyid), $aRelevantAttachments)) { if ($debug>0) { echo '
Email could not be sent. Reason: '.$maildebug.'
'; } } } } } /** * submitfailed : used in em_manager_helper.php */ function submitfailed($errormsg='') { global $debug; global $thissurvey; global $subquery, $surveyid; $clang = Yii::app()->lang; $completed = "
" . $clang->gT("Did Not Save")."

\n\n" . $clang->gT("An unexpected error has occurred and your responses cannot be saved.")."

\n"; if ($thissurvey['adminemail']) { $completed .= $clang->gT("Your responses have not been lost and have been emailed to the survey administrator and will be entered into our database at a later point.")."

\n"; if ($debug>0) { $completed.='Error message: '.htmlspecialchars($errormsg).'
'; } $email=$clang->gT("An error occurred saving a response to survey id","unescaped")." ".$thissurvey['name']." - $surveyid\n\n"; $email .= $clang->gT("DATA TO BE ENTERED","unescaped").":\n"; foreach ($_SESSION['survey_'.$surveyid]['insertarray'] as $value) { $email .= "$value: {$_SESSION['survey_'.$surveyid][$value]}\n"; } $email .= "\n".$clang->gT("SQL CODE THAT FAILED","unescaped").":\n" . "$subquery\n\n" . $clang->gT("ERROR MESSAGE","unescaped").":\n" . $errormsg."\n\n"; SendEmailMessage($email, $clang->gT("Error saving results","unescaped"), $thissurvey['adminemail'], $thissurvey['adminemail'], "LimeSurvey", false, getBounceEmail($surveyid)); //echo "\n"; //An email has been sent, so we can kill off this session. killSurveySession($surveyid); } else { $completed .= "".$clang->gT("Try to submit again")."

\n"; $completed .= $subquery; } return $completed; } /** * This function builds all the required session variables when a survey is first started and * it loads any answer defaults from command line or from the table defaultvalues * It is called from the related format script (group.php, question.php, survey.php) * if the survey has just started. */ function buildsurveysession($surveyid,$preview=false) { global $secerror, $clienttoken; global $tokensexist; //global $surveyid; global $move, $rooturl; $clang = Yii::app()->lang; $sLangCode=$clang->langcode; $languagechanger=makeLanguageChangerSurvey($sLangCode); if(!$preview) $preview=Yii::app()->getConfig('previewmode'); $thissurvey = getSurveyInfo($surveyid,$sLangCode); $_SESSION['survey_'.$surveyid]['templatename']=validateTemplateDir($thissurvey['template']); $_SESSION['survey_'.$surveyid]['templatepath']=getTemplatePath($_SESSION['survey_'.$surveyid]['templatename']).DIRECTORY_SEPARATOR; $sTemplatePath=$_SESSION['survey_'.$surveyid]['templatepath']; $loadsecurity = returnGlobal('loadsecurity',true); // NO TOKEN REQUIRED BUT CAPTCHA ENABLED FOR SURVEY ACCESS if ($tokensexist == 0 && isCaptchaEnabled('surveyaccessscreen',$thissurvey['usecaptcha']) && !isset($_SESSION['survey_'.$surveyid]['captcha_surveyaccessscreen'])&& !$preview) { // IF CAPTCHA ANSWER IS NOT CORRECT OR NOT SET if (!isset($loadsecurity) || !isset($_SESSION['survey_'.$surveyid]['secanswer']) || $loadsecurity != $_SESSION['survey_'.$surveyid]['secanswer']) { sendCacheHeaders(); doHeader(); // No or bad answer to required security question $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath."startpage.pstpl"),array(),$redata,'frontend_helper[875]'); //echo makedropdownlist(); echo templatereplace(file_get_contents($sTemplatePath."survey.pstpl"),array(),$redata,'frontend_helper[877]'); if (isset($loadsecurity)) { // was a bad answer echo "".$clang->gT("The answer to the security question is incorrect.")."
"; } echo "

".$clang->gT("Please confirm access to survey by answering the security question below and click continue.")."

" .CHtml::form(array("/survey/index/sid/{$surveyid}"), 'post', array('class'=>'captcha'))." "; if (function_exists("ImageCreate") && isCaptchaEnabled('surveyaccessscreen', $thissurvey['usecaptcha'])) { echo ""; } echo "
"; // In case we this is a direct Reload previous answers URL, then add hidden fields if (isset($_GET['loadall']) && isset($_GET['scid']) && isset($_GET['loadname']) && isset($_GET['loadpass'])) { echo " "; } echo "
captcha
"; echo templatereplace(file_get_contents($sTemplatePath."endpage.pstpl"),array(),$redata,'frontend_helper[1567]'); doFooter(); exit; } else{ $_SESSION['survey_'.$surveyid]['captcha_surveyaccessscreen']=true; } } //BEFORE BUILDING A NEW SESSION FOR THIS SURVEY, LET'S CHECK TO MAKE SURE THE SURVEY SHOULD PROCEED! // TOKEN REQUIRED BUT NO TOKEN PROVIDED if ($tokensexist == 1 && !$clienttoken && !$preview) { if ($thissurvey['nokeyboard']=='Y') { includeKeypad(); $kpclass = "text-keypad"; } else { $kpclass = ""; } // DISPLAY REGISTER-PAGE if needed // DISPLAY CAPTCHA if needed sendCacheHeaders(); doHeader(); $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath."startpage.pstpl"),array(),$redata,'frontend_helper[1594]'); //echo makedropdownlist(); echo templatereplace(file_get_contents($sTemplatePath."survey.pstpl"),array(),$redata,'frontend_helper[1596]'); if (isset($thissurvey) && $thissurvey['allowregister'] == "Y") { echo templatereplace(file_get_contents($sTemplatePath."register.pstpl"),array(),$redata,'frontend_helper[1599]'); } else { // ->renderPartial('entertoken_view'); if (isset($secerror)) echo "".$secerror."
"; echo '

'.$clang->gT("This is a controlled survey. You need a valid token to participate.")."
"; echo $clang->gT("If you have been issued a token, please enter it in the box below and click continue.")."

" .CHtml::form(array("/survey/index/sid/{$surveyid}"), 'post', array('id'=>'tokenform','autocomplete'=>'off'))."
"; } echo templatereplace(file_get_contents($sTemplatePath."endpage.pstpl"),array(),$redata,'frontend_helper[1645]'); doFooter(); exit; } // TOKENS REQUIRED, A TOKEN PROVIDED // SURVEY WITH NO NEED TO USE CAPTCHA elseif ($tokensexist == 1 && $clienttoken && !isCaptchaEnabled('surveyaccessscreen',$thissurvey['usecaptcha'])) { //check if token actually does exist // check also if it is allowed to change survey after completion if ($thissurvey['alloweditaftercompletion'] == 'Y' ) { $oTokenEntry = Token::model($surveyid)->findByAttributes(array('token'=>$clienttoken)); } else { $oTokenEntry = Token::model($surveyid)->usable()->incomplete()->findByAttributes(array('token' => $clienttoken)); } if (!isset($oTokenEntry)) { //TOKEN DOESN'T EXIST OR HAS ALREADY BEEN USED. EXPLAIN PROBLEM AND EXIT killSurveySession($surveyid); sendCacheHeaders(); doHeader(); $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath."startpage.pstpl"),array(),$redata,'frontend_helper[1676]'); echo templatereplace(file_get_contents($sTemplatePath."survey.pstpl"),array(),$redata,'frontend_helper[1677]'); echo '

'.$clang->gT("This is a controlled survey. You need a valid token to participate.")."

\n" ."\t".$clang->gT("The token you have provided is either not valid, or has already been used.")."

\n" ."\t".sprintf($clang->gT("For further information please contact %s"), $thissurvey['adminname']) ." (" ."{$thissurvey['adminemail']})

\n"; echo templatereplace(file_get_contents($sTemplatePath."endpage.pstpl"),array(),$redata,'frontend_helper[1684]'); doFooter(); exit; } } // TOKENS REQUIRED, A TOKEN PROVIDED // SURVEY CAPTCHA REQUIRED elseif ($tokensexist == 1 && $clienttoken && isCaptchaEnabled('surveyaccessscreen',$thissurvey['usecaptcha'])) { // IF CAPTCHA ANSWER IS CORRECT if (isset($loadsecurity) && isset($_SESSION['survey_'.$surveyid]['secanswer']) && $loadsecurity == $_SESSION['survey_'.$surveyid]['secanswer']) { if ($thissurvey['alloweditaftercompletion'] == 'Y' ) { $oTokenEntry = Token::model($surveyid)->findByAttributes(array('token'=> $clienttoken)); } else { $oTokenEntry = Token::model($surveyid)->incomplete()->findByAttributes(array( 'token' => $clienttoken )); } if (!isset($oTokenEntry)) { sendCacheHeaders(); doHeader(); //TOKEN DOESN'T EXIST OR HAS ALREADY BEEN USED. EXPLAIN PROBLEM AND EXIT $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath."startpage.pstpl"),array(),$redata,'frontend_helper[1719]'); echo templatereplace(file_get_contents($sTemplatePath."survey.pstpl"),array(),$redata,'frontend_helper[1720]'); echo "\t
\n" ."\t

\n" ."\t".$clang->gT("This is a controlled survey. You need a valid token to participate.")."

\n" ."\t".$clang->gT("The token you have provided is either not valid, or has already been used.")."

\n" ."\t".sprintf($clang->gT("For further information please contact %s"), $thissurvey['adminname']) ." (" ."{$thissurvey['adminemail']})\n" ."\t

\n" ."\t
\n"; echo templatereplace(file_get_contents($sTemplatePath."endpage.pstpl"),array(),$redata,'frontend_helper[1731]'); doFooter(); exit; } } // IF CAPTCHA ANSWER IS NOT CORRECT else if (!isset($move) || is_null($move)) { unset($_SESSION['survey_'.$surveyid]['srid']); $gettoken = $clienttoken; sendCacheHeaders(); doHeader(); // No or bad answer to required security question $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath."startpage.pstpl"),array(),$redata,'frontend_helper[1745]'); echo templatereplace(file_get_contents($sTemplatePath."survey.pstpl"),array(),$redata,'frontend_helper[1746]'); // If token wasn't provided and public registration // is enabled then show registration form if ( !isset($gettoken) && isset($thissurvey) && $thissurvey['allowregister'] == "Y") { echo templatereplace(file_get_contents($sTemplatePath."register.pstpl"),array(),$redata,'frontend_helper[1751]'); } else { // only show CAPTCHA echo '

'; if (isset($loadsecurity)) { // was a bad answer echo "".$clang->gT("The answer to the security question is incorrect.")."
"; } echo $clang->gT("This is a controlled survey. You need a valid token to participate.")."

"; // IF TOKEN HAS BEEN GIVEN THEN AUTOFILL IT // AND HIDE ENTRY FIELD if (!isset($gettoken)) { echo $clang->gT("If you have been issued a token, please enter it in the box below and click continue.")."

'.templatereplace(file_get_contents($sTemplatePath."endpage.pstpl"),array(),$redata,'frontend_helper[1817]'); doFooter(); exit; } } //RESET ALL THE SESSION VARIABLES AND START AGAIN unset($_SESSION['survey_'.$surveyid]['grouplist']); unset($_SESSION['survey_'.$surveyid]['fieldarray']); unset($_SESSION['survey_'.$surveyid]['insertarray']); unset($_SESSION['survey_'.$surveyid]['fieldnamesInfo']); unset($_SESSION['survey_'.$surveyid]['fieldmap-' . $surveyid . '-randMaster']); unset($_SESSION['survey_'.$surveyid]['groupReMap']); $_SESSION['survey_'.$surveyid]['fieldnamesInfo'] = Array(); //RL: multilingual support if (isset($_GET['token']) && tableExists('{{tokens_'.$surveyid.'}}')) { //get language from token (if one exists) $tkquery2 = "SELECT * FROM {{tokens_".$surveyid."}} WHERE token='".$clienttoken."' AND (completed = 'N' or completed='')"; //echo $tkquery2; $result = dbExecuteAssoc($tkquery2) or safeDie ("Couldn't get tokens
$tkquery
"); //Checked foreach ($result->readAll() as $rw) { $tklanguage=$rw['language']; } } if (returnGlobal('lang',true)) { $language_to_set=returnGlobal('lang',true); } elseif (isset($tklanguage)) { $language_to_set=$tklanguage; } else { $language_to_set = $thissurvey['language']; } if (!isset($_SESSION['survey_'.$surveyid]['s_lang'])) { SetSurveyLanguage($surveyid, $language_to_set); } UpdateGroupList($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']); $sQuery = "SELECT count(*)\n" ." FROM {{groups}} INNER JOIN {{questions}} ON {{groups}}.gid = {{questions}}.gid\n" ." WHERE {{questions}}.sid=".$surveyid."\n" ." AND {{groups}}.language='".$_SESSION['survey_'.$surveyid]['s_lang']."'\n" ." AND {{questions}}.language='".$_SESSION['survey_'.$surveyid]['s_lang']."'\n" ." AND {{questions}}.parent_qid=0\n"; $totalquestions = Yii::app()->db->createCommand($sQuery)->queryScalar(); // Fix totalquestions by substracting Test Display questions $iNumberofQuestions=dbExecuteAssoc("SELECT count(*)\n" ." FROM {{questions}}" ." WHERE type in ('X','*')\n" ." AND sid={$surveyid}" ." AND language='".$_SESSION['survey_'.$surveyid]['s_lang']."'" ." AND parent_qid=0")->read(); $_SESSION['survey_'.$surveyid]['totalquestions'] = $totalquestions - (int) reset($iNumberofQuestions); //2. SESSION VARIABLE: totalsteps //The number of "pages" that will be presented in this survey //The number of pages to be presented will differ depending on the survey format switch($thissurvey['format']) { case "A": $_SESSION['survey_'.$surveyid]['totalsteps']=1; break; case "G": if (isset($_SESSION['survey_'.$surveyid]['grouplist'])) { $_SESSION['survey_'.$surveyid]['totalsteps']=count($_SESSION['survey_'.$surveyid]['grouplist']); } break; case "S": $_SESSION['survey_'.$surveyid]['totalsteps']=$totalquestions; } if ($totalquestions == 0) //break out and crash if there are no questions! { sendCacheHeaders(); doHeader(); $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath."startpage.pstpl"),array(),$redata,'frontend_helper[1914]'); echo templatereplace(file_get_contents($sTemplatePath."survey.pstpl"),array(),$redata,'frontend_helper[1915]'); echo "\t
\n" ."\t

\n" ."\t".$clang->gT("This survey does not yet have any questions and cannot be tested or completed.")."

\n" ."\t".sprintf($clang->gT("For further information please contact %s"), $thissurvey['adminname']) ." (" ."{$thissurvey['adminemail']})

\n" ."\t

\n" ."\t
\n"; echo templatereplace(file_get_contents($sTemplatePath."endpage.pstpl"),array(),$redata,'frontend_helper[1925]'); doFooter(); exit; } //Perform a case insensitive natural sort on group name then question title of a multidimensional array // usort($arows, 'groupOrderThenQuestionOrder'); //3. SESSION VARIABLE - insertarray //An array containing information about used to insert the data into the db at the submit stage //4. SESSION VARIABLE - fieldarray //See rem at end.. if ($tokensexist == 1 && $clienttoken) { $_SESSION['survey_'.$surveyid]['token'] = $clienttoken; } if ($thissurvey['anonymized'] == "N") { $_SESSION['survey_'.$surveyid]['insertarray'][]= "token"; } $qtypes=getQuestionTypeList('','array'); $fieldmap=createFieldMap($surveyid,'full',true,false,$_SESSION['survey_'.$surveyid]['s_lang']); // Randomization groups for groups $aRandomGroups=array(); $aGIDCompleteMap=array(); // first find all groups and their groups IDS $criteria = new CDbCriteria; $criteria->addColumnCondition(array('sid' => $surveyid, 'language' => $_SESSION['survey_'.$surveyid]['s_lang'])); $criteria->addCondition("randomization_group != ''"); $oData = QuestionGroup::model()->findAll($criteria); foreach($oData as $aGroup) { $aRandomGroups[$aGroup['randomization_group']][] = $aGroup['gid']; } // Shuffle each group and create a map for old GID => new GID foreach ($aRandomGroups as $sGroupName=>$aGIDs) { $aShuffledIDs=$aGIDs; shuffle($aShuffledIDs); $aGIDCompleteMap=$aGIDCompleteMap+array_combine($aGIDs,$aShuffledIDs); } $_SESSION['survey_' . $surveyid]['groupReMap'] = $aGIDCompleteMap; $randomized = false; // So we can trigger reorder once for group and question randomization // Now adjust the grouplist if (count($aRandomGroups)>0 && !$preview) { $randomized = true; // So we can trigger reorder once for group and question randomization // Now adjust the grouplist Yii::import('application.helpers.frontend_helper', true); // make sure frontend helper is loaded UpdateGroupList($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']); // ... and the fieldmap // First create a fieldmap with GID as key foreach ($fieldmap as $aField) { if (isset($aField['gid'])) { $GroupFieldMap[$aField['gid']][]=$aField; } else{ $GroupFieldMap['other'][]=$aField; } } // swap it foreach ($GroupFieldMap as $iOldGid => $fields) { $iNewGid = $iOldGid; if (isset($aGIDCompleteMap[$iOldGid])) { $iNewGid = $aGIDCompleteMap[$iOldGid]; } $newGroupFieldMap[$iNewGid] = $GroupFieldMap[$iNewGid]; } $GroupFieldMap = $newGroupFieldMap; // and convert it back to a fieldmap unset($fieldmap); foreach($GroupFieldMap as $aGroupFields) { foreach ($aGroupFields as $aField) { if (isset($aField['fieldname'])) { $fieldmap[$aField['fieldname']] = $aField; // isset() because of the shuffled flag above } } } unset($GroupFieldMap); } // Randomization groups for questions // Find all defined randomization groups through question attribute values $randomGroups=array(); if (in_array(Yii::app()->db->getDriverName(), array('mssql', 'sqlsrv', 'dblib'))) { $rgquery = "SELECT attr.qid, CAST(value as varchar(255)) as value FROM {{question_attributes}} as attr right join {{questions}} as quests on attr.qid=quests.qid WHERE attribute='random_group' and CAST(value as varchar(255)) <> '' and sid=$surveyid GROUP BY attr.qid, CAST(value as varchar(255))"; } else { $rgquery = "SELECT attr.qid, value FROM {{question_attributes}} as attr right join {{questions}} as quests on attr.qid=quests.qid WHERE attribute='random_group' and value <> '' and sid=$surveyid GROUP BY attr.qid, value"; } $rgresult = dbExecuteAssoc($rgquery); foreach($rgresult->readAll() as $rgrow) { // Get the question IDs for each randomization group $randomGroups[$rgrow['value']][] = $rgrow['qid']; } // If we have randomization groups set, then lets cycle through each group and // replace questions in the group with a randomly chosen one from the same group if (count($randomGroups) > 0 && !$preview) { $randomized = true; // So we can trigger reorder once for group and question randomization $copyFieldMap = array(); $oldQuestOrder = array(); $newQuestOrder = array(); $randGroupNames = array(); foreach ($randomGroups as $key=>$value) { $oldQuestOrder[$key] = $randomGroups[$key]; $newQuestOrder[$key] = $oldQuestOrder[$key]; // We shuffle the question list to get a random key->qid which will be used to swap from the old key shuffle($newQuestOrder[$key]); $randGroupNames[] = $key; } // Loop through the fieldmap and swap each question as they come up foreach ($fieldmap as $fieldkey => $fieldval) { $found = 0; foreach ($randomGroups as $gkey => $gval) { // We found a qid that is in the randomization group if (isset($fieldval['qid']) && in_array($fieldval['qid'],$oldQuestOrder[$gkey])) { // Get the swapped question $idx = array_search($fieldval['qid'],$oldQuestOrder[$gkey]); foreach ($fieldmap as $key => $field) { if (isset($field['qid']) && $field['qid'] == $newQuestOrder[$gkey][$idx]) { $field['random_gid'] = $fieldval['gid']; // It is possible to swap to another group $copyFieldMap[$key] = $field; } } $found = 1; break; } else { $found = 2; } } if ($found == 2) { $copyFieldMap[$fieldkey]=$fieldval; } reset($randomGroups); } $fieldmap = $copyFieldMap; } if ($randomized === true) { // reset the sequencing counts $gseq = -1; $_gid = -1; $qseq = -1; $_qid = -1; $copyFieldMap = array(); foreach ($fieldmap as $key => $val) { if ($val['gid'] != '') { if (isset($val['random_gid'])) { $gid = $val['random_gid']; } else { $gid = $val['gid']; } if ($gid != $_gid) { $_gid = $gid; ++$gseq; } } if ($val['qid'] != '' && $val['qid'] != $_qid) { $_qid = $val['qid']; ++$qseq; } if ($val['gid'] != '' && $val['qid'] != '') { $val['groupSeq'] = $gseq; $val['questionSeq'] = $qseq; } $copyFieldMap[$key] = $val; } $fieldmap = $copyFieldMap; unset($copyFieldMap); $_SESSION['survey_'.$surveyid]['fieldmap-' . $surveyid . $_SESSION['survey_'.$surveyid]['s_lang']] = $fieldmap; $_SESSION['survey_'.$surveyid]['fieldmap-' . $surveyid . '-randMaster'] = 'fieldmap-' . $surveyid . $_SESSION['survey_'.$surveyid]['s_lang']; } // TMSW Condition->Relevance: don't need hasconditions, or usedinconditions $_SESSION['survey_'.$surveyid]['fieldmap']=$fieldmap; foreach ($fieldmap as $field) { if (isset($field['qid']) && $field['qid']!='') { $_SESSION['survey_'.$surveyid]['fieldnamesInfo'][$field['fieldname']]=$field['sid'].'X'.$field['gid'].'X'.$field['qid']; $_SESSION['survey_'.$surveyid]['insertarray'][]=$field['fieldname']; //fieldarray ARRAY CONTENTS - // [0]=questions.qid, // [1]=fieldname, // [2]=questions.title, // [3]=questions.question // [4]=questions.type, // [5]=questions.gid, // [6]=questions.mandatory, // [7]=conditionsexist, // [8]=usedinconditions // [8]=usedinconditions // [9]=used in group.php for question count // [10]=new group id for question in randomization group (GroupbyGroup Mode) if (!isset($_SESSION['survey_'.$surveyid]['fieldarray'][$field['sid'].'X'.$field['gid'].'X'.$field['qid']])) { //JUST IN CASE : PRECAUTION! //following variables are set only if $style=="full" in createFieldMap() in common_helper. //so, if $style = "short", set some default values here! if (isset($field['title'])) $title = $field['title']; else $title = ""; if (isset($field['question'])) $question = $field['question']; else $question = ""; if (isset($field['mandatory'])) $mandatory = $field['mandatory']; else $mandatory = 'N'; if (isset($field['hasconditions'])) $hasconditions = $field['hasconditions']; else $hasconditions = 'N'; if (isset($field['usedinconditions'])) $usedinconditions = $field['usedinconditions']; else $usedinconditions = 'N'; $_SESSION['survey_'.$surveyid]['fieldarray'][$field['sid'].'X'.$field['gid'].'X'.$field['qid']]=array($field['qid'], $field['sid'].'X'.$field['gid'].'X'.$field['qid'], $title, $question, $field['type'], $field['gid'], $mandatory, $hasconditions, $usedinconditions); } if (isset($field['random_gid'])) { $_SESSION['survey_'.$surveyid]['fieldarray'][$field['sid'].'X'.$field['gid'].'X'.$field['qid']][10] = $field['random_gid']; } } } // Prefill questions/answers from command line params $reservedGetValues= array('token','sid','gid','qid','lang','newtest','action'); $startingValues=array(); if (isset($_GET)) { foreach ($_GET as $k=>$v) { if (!in_array($k,$reservedGetValues) && isset($_SESSION['survey_'.$surveyid]['fieldmap'][$k])) { $startingValues[$k] = $v; } else { // Search question codes to use those for prefilling. foreach($_SESSION['survey_'.$surveyid]['fieldmap'] as $sgqa => $details) { if ($details['title'] == $k) { $startingValues[$sgqa] = $v; } } } } } $_SESSION['survey_'.$surveyid]['startingValues']=$startingValues; if (isset($_SESSION['survey_'.$surveyid]['fieldarray'])) $_SESSION['survey_'.$surveyid]['fieldarray']=array_values($_SESSION['survey_'.$surveyid]['fieldarray']); //Check if a passthru label and value have been included in the query url $oResult=SurveyURLParameter::model()->getParametersForSurvey($surveyid); foreach($oResult->readAll() as $aRow) { if(isset($_GET[$aRow['parameter']]) && !$preview) { $_SESSION['survey_'.$surveyid]['urlparams'][$aRow['parameter']]=$_GET[$aRow['parameter']]; if ($aRow['targetqid']!='') { foreach ($fieldmap as $sFieldname=>$aField) { if ($aRow['targetsqid']!='') { if ($aField['qid']==$aRow['targetqid'] && $aField['sqid']==$aRow['targetsqid']) { $_SESSION['survey_'.$surveyid]['startingValues'][$sFieldname]=$_GET[$aRow['parameter']]; $_SESSION['survey_'.$surveyid]['startingValues'][$aRow['parameter']]=$_GET[$aRow['parameter']]; } } else { if ($aField['qid']==$aRow['targetqid']) { $_SESSION['survey_'.$surveyid]['startingValues'][$sFieldname]=$_GET[$aRow['parameter']]; $_SESSION['survey_'.$surveyid]['startingValues'][$aRow['parameter']]=$_GET[$aRow['parameter']]; } } } } } } } /** * This function creates the form elements in the survey navigation bar * Adding a hidden input for default behaviour without javascript * Use button name="move" for real browser (with or without javascript) and IE6/7/8 with javascript */ function surveymover() { $surveyid=Yii::app()->getConfig('surveyID'); $thissurvey=getSurveyInfo($surveyid); $clang = Yii::app()->lang; $sMoveNext="movenext"; $sMovePrev=""; $iSessionStep=(isset($_SESSION['survey_'.$surveyid]['step']))?$_SESSION['survey_'.$surveyid]['step']:false; $iSessionMaxStep=(isset($_SESSION['survey_'.$surveyid]['maxstep']))?$_SESSION['survey_'.$surveyid]['maxstep']:false; $iSessionTotalSteps=(isset($_SESSION['survey_'.$surveyid]['totalsteps']))?$_SESSION['survey_'.$surveyid]['totalsteps']:false; $sClass="submit button"; $sSurveyMover = ""; // Count down if ($thissurvey['navigationdelay'] > 0 && ($iSessionMaxStep!==false && $iSessionMaxStep == $iSessionStep)) { $sClass.=" disabled"; App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."/navigator-countdown.js"); App()->getClientScript()->registerScript('navigator_countdown',"navigator_countdown(" . $thissurvey['navigationdelay'] . ");\n",CClientScript::POS_BEGIN); } // Previous ? if ($thissurvey['format'] != "A" && ($thissurvey['allowprev'] != "N") && $iSessionStep && !($iSessionStep == 1 && $thissurvey['showwelcome'] == 'N') && !Yii::app()->getConfig('previewmode') ) { $sMovePrev="moveprev"; } // Submit ? if ($iSessionStep && ($iSessionStep == $iSessionTotalSteps) || $thissurvey['format'] == 'A' ) { $sMoveNext="movesubmit"; } // todo Remove Next if needed (exemple quota show previous only: maybe other, but actually don't use surveymover) if(Yii::app()->getConfig('previewmode')) { $sMoveNext=""; } // Construction of mover if($sMovePrev){ $sLangMoveprev=$clang->gT("Previous"); $sSurveyMover.= CHtml::htmlButton($sLangMoveprev,array('type'=>'submit','id'=>"{$sMovePrev}btn",'value'=>$sMovePrev,'name'=>$sMovePrev,'accesskey'=>'p','class'=>$sClass)); } if($sMovePrev && $sMoveNext){ $sSurveyMover .= " "; } if($sMoveNext){ if($sMoveNext=="movesubmit"){ $sLangMovenext=$clang->gT("Submit"); $sAccessKeyNext='l';// Why l ? }else{ $sLangMovenext=$clang->gT("Next"); $sAccessKeyNext='n'; } $sSurveyMover.= CHtml::htmlButton($sLangMovenext,array('type'=>'submit','id'=>"{$sMoveNext}btn",'value'=>$sMoveNext,'name'=>$sMoveNext,'accesskey'=>$sAccessKeyNext,'class'=>$sClass)); } return $sSurveyMover; } /** * Caculate assessement scores * * @param mixed $surveyid * @param mixed $returndataonly - only returns an array with data */ function doAssessment($surveyid, $returndataonly=false) { $clang = Yii::app()->lang; $baselang=Survey::model()->findByPk($surveyid)->language; if(Survey::model()->findByPk($surveyid)->assessments!="Y") { return false; } $total=0; if (!isset($_SESSION['survey_'.$surveyid]['s_lang'])) { $_SESSION['survey_'.$surveyid]['s_lang']=$baselang; } $query = "SELECT * FROM {{assessments}} WHERE sid=$surveyid and language='".$_SESSION['survey_'.$surveyid]['s_lang']."' ORDER BY scope, id"; if ($result = dbExecuteAssoc($query)) //Checked { $aResultSet=$result->readAll(); if (count($aResultSet) > 0) { foreach($aResultSet as $row) { if ($row['scope'] == "G") { $assessment['group'][$row['gid']][]=array("name"=>$row['name'], "min"=>$row['minimum'], "max"=>$row['maximum'], "message"=>$row['message']); } else { $assessment['total'][]=array( "name"=>$row['name'], "min"=>$row['minimum'], "max"=>$row['maximum'], "message"=>$row['message']); } } $fieldmap=createFieldMap($surveyid, "full",false,false,$_SESSION['survey_'.$surveyid]['s_lang']); $i=0; $total=0; $groups=array(); foreach($fieldmap as $field) { if (in_array($field['type'],array('1','F','H','W','Z','L','!','M','O','P'))) { $fieldmap[$field['fieldname']]['assessment_value']=0; if (isset($_SESSION['survey_'.$surveyid][$field['fieldname']])) { if (($field['type'] == "M") || ($field['type'] == "P")) //Multiflexi choice - result is the assessment attribute value { if ($_SESSION['survey_'.$surveyid][$field['fieldname']] == "Y") { $aAttributes=getQuestionAttributeValues($field['qid'],$field['type']); $fieldmap[$field['fieldname']]['assessment_value']=(int)$aAttributes['assessment_value']; $total=$total+(int)$aAttributes['assessment_value']; } } else // Single choice question { $usquery = "SELECT assessment_value FROM {{answers}} where qid=".$field['qid']." and language='$baselang' and code=".dbQuoteAll($_SESSION['survey_'.$surveyid][$field['fieldname']]); $usresult = dbExecuteAssoc($usquery); //Checked if ($usresult) { $usrow = $usresult->read(); $fieldmap[$field['fieldname']]['assessment_value']=$usrow['assessment_value']; $total=$total+$usrow['assessment_value']; } } } $groups[]=$field['gid']; } $i++; } $groups=array_unique($groups); foreach($groups as $group) { $grouptotal=0; foreach ($fieldmap as $field) { if ($field['gid'] == $group && isset($field['assessment_value'])) { //$grouptotal=$grouptotal+$field['answer']; if (isset ($_SESSION['survey_'.$surveyid][$field['fieldname']])) { $grouptotal=$grouptotal+$field['assessment_value']; } } } $subtotal[$group]=$grouptotal; } } $assessments = ""; if (isset($subtotal) && is_array($subtotal)) { foreach($subtotal as $key=>$val) { if (isset($assessment['group'][$key])) { foreach($assessment['group'][$key] as $assessed) { if ($val >= $assessed['min'] && $val <= $assessed['max'] && $returndataonly===false) { $assessments .= "\t
".str_replace(array("{PERC}", "{TOTAL}"), array($val, $total), $assessed['name'])."
".str_replace(array("{PERC}", "{TOTAL}"), array($val, $total), $assessed['message'])."

\n"; } } } } } if (isset($assessment['total'])) { foreach($assessment['total'] as $assessed) { if ($total >= $assessed['min'] && $total <= $assessed['max'] && $returndataonly===false) { $assessments .= "\t\t\t
".str_replace(array("{PERC}", "{TOTAL}"), array($val, $total), stripslashes($assessed['name']))."
".str_replace(array("{PERC}", "{TOTAL}"), array($val, $total), stripslashes($assessed['message']))."
\n"; } } } if ($returndataonly==true) { return array('total'=>$total); } else { return $assessments; } } } /** * Update SESSION VARIABLE: grouplist * A list of groups in this survey, ordered by group name. * @param int surveyid * @param string language */ function UpdateGroupList($surveyid, $language) { $clang = Yii::app()->lang; unset ($_SESSION['survey_'.$surveyid]['grouplist']); $query = "SELECT * FROM {{groups}} WHERE sid=$surveyid AND language='".$language."' ORDER BY group_order"; $result = dbExecuteAssoc($query) or safeDie ("Couldn't get group list
$query
"); //Checked $groupList = array(); foreach ($result->readAll() as $row) { $group = array( 'gid' => $row['gid'], 'group_name' => $row['group_name'], 'description' => $row['description']); $groupList[] = $group; $gidList[$row['gid']] = $group; } if (!Yii::app()->getConfig('previewmode') && isset($_SESSION['survey_'.$surveyid]['groupReMap']) && count($_SESSION['survey_'.$surveyid]['groupReMap'])>0) { // Now adjust the grouplist $groupRemap = $_SESSION['survey_'.$surveyid]['groupReMap']; $groupListCopy = $groupList; foreach ($groupList as $gseq => $info) { $gid = $info['gid']; if (isset($groupRemap[$gid])) { $gid = $groupRemap[$gid]; } $groupListCopy[$gseq] = $gidList[$gid]; } $groupList = $groupListCopy; } $_SESSION['survey_'.$surveyid]['grouplist'] = $groupList; } /** * FieldArray contains all necessary information regarding the questions * This function is needed to update it in case the survey is switched to another language * @todo: Make 'fieldarray' obsolete by replacing with EM session info */ function UpdateFieldArray() { global $surveyid; $clang = Yii::app()->lang; if (isset($_SESSION['survey_'.$surveyid]['fieldarray'])) { foreach ($_SESSION['survey_'.$surveyid]['fieldarray'] as $key => $value) { $questionarray = &$_SESSION['survey_'.$surveyid]['fieldarray'][$key]; $query = "SELECT title, question FROM {{questions}} WHERE qid=".$questionarray[0]." AND language='".$_SESSION['survey_'.$surveyid]['s_lang']."'"; $usrow = Yii::app()->db->createCommand($query)->queryRow(); if ($usrow) { $questionarray[2]=$usrow['title']; $questionarray[3]=$usrow['question']; } unset($questionarray); } } } /** * checkQuota() returns quota information for the current survey * @param string $checkaction - action the function must take after completing: * enforce: Enforce the Quota action * return: Return the updated quota array from getQuotaAnswers() * @param string $surveyid - Survey identification number * @return array - nested array, Quotas->Members->Fields, includes quota status and which members matched in session. */ function checkQuota($checkaction,$surveyid) { global $clienttoken ; if (!isset($_SESSION['survey_'.$surveyid]['srid'])) { return; } $thissurvey=getSurveyInfo($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']); $sTemplatePath=getTemplatePath($thissurvey['templatedir']); $global_matched = false; $quota_info = getQuotaInformation($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']); $x=0; $clang = Yii::app()->lang; if(count($quota_info) > 0) // Quota's have to exist { // Check each quota on saved data to see if it is full $querycond = array(); foreach ($quota_info as $quota) { if (count($quota['members']) > 0) // Quota can't be empty { $fields_list = array(); // Keep a list of fields for easy reference $y=0; // We need to make the conditions for the select statement here unset($querycond); // fill the array of value and query for each fieldnames $fields_value_array = array(); $fields_query_array = array(); foreach($quota['members'] as $member) { foreach($member['fieldnames'] as $fieldname) { if (!in_array($fieldname,$fields_list)) { $fields_list[] = $fieldname; $fields_value_array[$fieldname] = array(); $fields_query_array[$fieldname] = array(); } $fields_value_array[$fieldname][]=$member['value']; $fields_query_array[$fieldname][]= dbQuoteID($fieldname)." = '{$member['value']}'"; } } // fill the $querycond array with each fields_query grouped by fieldname foreach($fields_list as $fieldname) { $select_query = " ( ".implode(' OR ',$fields_query_array[$fieldname]).' )'; $querycond[] = $select_query; } // Test if the fieldname is in the array of value in the session foreach($quota['members'] as $member) { foreach($member['fieldnames'] as $fieldname) { if (isset($_SESSION['survey_'.$surveyid][$fieldname])) { if (in_array($_SESSION['survey_'.$surveyid][$fieldname],$fields_value_array[$fieldname])){ $quota_info[$x]['members'][$y]['insession'] = "true"; } } } $y++; } unset($fields_query_array);unset($fields_value_array); // Lets only continue if any of the quota fields is in the posted page $matched_fields = false; if (isset($_POST['fieldnames'])) { $posted_fields = explode("|",$_POST['fieldnames']); foreach ($fields_list as $checkfield) { if (in_array($checkfield,$posted_fields)) { $matched_fields = true; $global_matched = true; } } } // A field was submitted that is part of the quota if ($matched_fields == true) { // Check the status of the quota, is it full or not $sQuery = "SELECT count(id) FROM {{survey_".$surveyid."}} WHERE ".implode(' AND ',$querycond)." "." AND submitdate IS NOT NULL"; $iRowCount = Yii::app()->db->createCommand($sQuery)->queryScalar(); if ($iRowCount >= $quota['Limit']) // Quota is full!! { // Now we have to check if the quota matches in the current session // This will let us know if this person is going to exceed the quota $counted_matches = 0; foreach($quota_info[$x]['members'] as $member) { if (isset($member['insession']) && $member['insession'] == "true") $counted_matches++; } if($counted_matches == count($quota['members'])) { // They are going to exceed the quota if data is submitted $quota_info[$x]['status']="matched"; } else { $quota_info[$x]['status']="notmatched"; } } else { // Quota is no in danger of being exceeded. $quota_info[$x]['status']="notmatched"; } } } $x++; } } else { return false; } // Now we have all the information we need about the quotas and their status. // Lets see what we should do now if ($checkaction == 'return') { return $quota_info; } elseif ($global_matched == true && $checkaction == 'enforce') { // Need to add Quota action enforcement here. reset($quota_info); $tempmsg =""; $found = false; $redata = compact(array_keys(get_defined_vars())); foreach($quota_info as $quota) { $quota['Message'] = templatereplace($quota['Message'],array(),$redata); $quota['Url'] = passthruReplace($quota['Url'], $thissurvey); $quota['Url'] = templatereplace($quota['Url'],array(),$redata); $quota['UrlDescrip'] = templatereplace($quota['UrlDescrip'],array(),$redata); if ((isset($quota['status']) && $quota['status'] == "matched") && (isset($quota['Action']) && $quota['Action'] == "1")) { // If a token is used then mark the token as completed if (isset($clienttoken) && $clienttoken) { submittokens(true); } sendCacheHeaders(); if($quota['AutoloadUrl'] == 1 && $quota['Url'] != "") { header("Location: ".$quota['Url']); killSurveySession($surveyid); } doHeader(); echo templatereplace(file_get_contents($sTemplatePath."/startpage.pstpl"),array(),$redata,'frontend_helper[2617]'); echo "\t
\n"; echo "\t".$quota['Message']."

\n"; echo "\t".$quota['UrlDescrip']."
\n"; echo "\t
\n"; echo templatereplace(file_get_contents($sTemplatePath."/endpage.pstpl"),array(),$redata,'frontend_helper[2622]'); doFooter(); killSurveySession($surveyid); exit; } if ((isset($quota['status']) && $quota['status'] == "matched") && (isset($quota['Action']) && $quota['Action'] == "2")) { sendCacheHeaders(); doHeader(); $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath."/startpage.pstpl"),array(),$redata,'frontend_helper[2634]'); echo "\t
\n"; echo "\t".$quota['Message']."

\n"; echo "\t".$quota['UrlDescrip']."
\n"; echo CHtml::form(array("/survey/index"), 'post', array('id'=>'limesurvey','name'=>'limesurvey'))." \n"; echo "\t
\n"; echo templatereplace(file_get_contents($sTemplatePath."/endpage.pstpl"),array(),$redata,'frontend_helper[2644]'); doFooter(); exit; } } } else { // Unknown value return false; } } /** * encodeEmail : encode admin email in public part * * @param mixed $mail * @param mixed $text * @param mixed $class * @param mixed $params */ function encodeEmail($mail, $text="", $class="", $params=array()) { $encmail =""; for($i=0; $ilang; // read it from server variable if(isset($_SERVER["HTTP_REFERER"])) { if(!preg_match('/'.$_SERVER["SERVER_NAME"].'/', $_SERVER["HTTP_REFERER"])) { if (!Yii::app()->getConfig('strip_query_from_referer_url')) { return $_SERVER["HTTP_REFERER"]; } else { $aRefurl = explode("?",$_SERVER["HTTP_REFERER"]); return $aRefurl[0]; } } else { return '-'; } } else { return null; } } /** * Shows the welcome page, used in group by group and question by question mode */ function display_first_page() { global $token, $surveyid, $thissurvey, $navigator; $totalquestions = $_SESSION['survey_'.$surveyid]['totalquestions']; $clang = Yii::app()->lang; // Fill some necessary var for template $navigator = surveymover(); $sitename = Yii::app()->getConfig('sitename'); $languagechanger=makeLanguageChangerSurvey($clang->langcode); sendCacheHeaders(); doHeader(); LimeExpressionManager::StartProcessingPage(); LimeExpressionManager::StartProcessingGroup(-1, false, $surveyid); // start on welcome page $redata = compact(array_keys(get_defined_vars())); $sTemplatePath=$_SESSION['survey_'.$surveyid]['templatepath']; echo templatereplace(file_get_contents($sTemplatePath."startpage.pstpl"),array(),$redata,'frontend_helper[2757]'); echo CHtml::form(array("/survey/index"), 'post', array('id'=>'limesurvey','name'=>'limesurvey','autocomplete'=>'off')); echo "\n\n\n"; echo templatereplace(file_get_contents($sTemplatePath."welcome.pstpl"),array(),$redata,'frontend_helper[2762]')."\n"; if ($thissurvey['anonymized'] == "Y") { echo templatereplace(file_get_contents($sTemplatePath."/privacy.pstpl"),array(),$redata,'frontend_helper[2765]')."\n"; } echo templatereplace(file_get_contents($sTemplatePath."navigator.pstpl"),array(),$redata,'frontend_helper[2767]'); if ($thissurvey['active'] != "Y") { echo "

".$clang->gT("This survey is currently not active. You will not be able to save your responses.")."

\n"; } echo "\n\n"; if (isset($token) && !empty($token)) { echo "\n\n"; } echo "\n\n"; //This is to ensure consistency with mandatory checks, and new group test $loadsecurity = returnGlobal('loadsecurity',true); if (isset($loadsecurity)) { echo "\n\n"; } $_SESSION['survey_'.$surveyid]['LEMpostKey'] = mt_rand(); echo "\n"; echo "\n"; echo "\n\n"; echo templatereplace(file_get_contents($sTemplatePath."endpage.pstpl"),array(),$redata,'frontend_helper[2782]'); echo LimeExpressionManager::GetRelevanceAndTailoringJavaScript(); LimeExpressionManager::FinishProcessingPage(); doFooter(); } /** * killSurveySession : reset $_SESSION part for the survey * @param int $iSurveyID */ function killSurveySession($iSurveyID) { // Unset the session unset($_SESSION['survey_'.$iSurveyID]); // Force EM to refresh LimeExpressionManager::SetDirtyFlag(); } /** * Resets all question timers by expiring the related cookie - this needs to be called before any output is done * @todo Make cookie survey ID aware */ function resetTimers() { $cookie=new CHttpCookie('limesurvey_timers', ''); $cookie->expire = time()- 3600; Yii::app()->request->cookies['limesurvey_timers'] = $cookie; } /** * Set the public survey language * Control if language exist in this survey, else set to survey default language * if $surveyid <= 0 : set the language to default site language * @param int $surveyid * @param string $language */ function SetSurveyLanguage($surveyid, $language) { $surveyid=sanitize_int($surveyid); $default_language = Yii::app()->getConfig('defaultlang'); if (isset($surveyid) && $surveyid>0) { $default_survey_language= Survey::model()->findByPk($surveyid)->language; $additional_survey_languages = Survey::model()->findByPk($surveyid)->getAdditionalLanguages(); if (!isset($language) || ($language=='') || !( in_array($language,$additional_survey_languages) || $language==$default_survey_language) ) { // Language not supported, fall back to survey's default language $_SESSION['survey_'.$surveyid]['s_lang'] = $default_survey_language; } else { $_SESSION['survey_'.$surveyid]['s_lang'] = $language; } Yii::import('application.libraries.Limesurvey_lang', true); $clang = new limesurvey_lang($_SESSION['survey_'.$surveyid]['s_lang']); $thissurvey=getSurveyInfo($surveyid, @$_SESSION['survey_'.$surveyid]['s_lang']); Yii::app()->loadHelper('surveytranslator'); $_SESSION['dateformats'] = getDateFormatData($thissurvey['surveyls_dateformat'],$_SESSION['survey_'.$surveyid]['s_lang']); LimeExpressionManager::SetEMLanguage($_SESSION['survey_'.$surveyid]['s_lang']); } else { if(!$language) { $language=$default_language; } $_SESSION['survey_'.$surveyid]['s_lang'] = $language; Yii::import('application.libraries.Limesurvey_lang', true); $clang = new Limesurvey_lang($language); } $oApplication=Yii::app(); $oApplication->lang=$clang; return $clang; } /** * getMove get move button clicked **/ function getMove() { # $clang = Yii::app()->lang; $aAcceptedMove=array('default','movenext','movesubmit','moveprev','saveall','loadall','clearall','changelang'); // We can control is save and load are OK : todo fix according to survey settings // Maybe allow $aAcceptedMove in Plugin $move=Yii::app()->request->getParam('move'); foreach($aAcceptedMove as $sAccepteMove) { if(Yii::app()->request->getParam($sAccepteMove)) $move=$sAccepteMove; } if($move=='clearall' && App()->request->getPost('confirm-clearall')!='confirm'){ $move="clearcancel"; } if($move=='default') { $surveyid=Yii::app()->getConfig('surveyID'); $thissurvey=getsurveyinfo($surveyid); $iSessionStep=(isset($_SESSION['survey_'.$surveyid]['step']))?$_SESSION['survey_'.$surveyid]['step']:false; $iSessionTotalSteps=(isset($_SESSION['survey_'.$surveyid]['totalsteps']))?$_SESSION['survey_'.$surveyid]['totalsteps']:false; if ($iSessionStep && ($iSessionStep == $iSessionTotalSteps)|| $thissurvey['format'] == 'A') { $move="movesubmit"; } else { $move="movenext"; } } return $move; }