/** * Loads a survey from the database that has the given ID. If no matching * survey is found then null is returned. Note that no results are loaded * from this function call, only survey structure/definition. * * In the future it would be nice to load all languages from the db at * once and have the infrastructure be able to return responses based * on language codes. * * @param int $id * @return SurveyObj */ public function loadSurveyById($id, $lang = null) { $survey = new SurveyObj(); $clang = Yii::app()->lang; $intId = sanitize_int($id); $survey->id = $intId; $survey->info = getSurveyInfo($survey->id); $availableLanguages = Survey::model()->findByPk($intId)->getAllLanguages(); if (is_null($lang) || in_array($lang, $availableLanguages) === false) { // use base language when requested language is not found or no specific language is requested $lang = Survey::model()->findByPk($intId)->language; } $clang = new limesurvey_lang($lang); $survey->fieldMap = createFieldMap($intId, 'full', true, false, $lang); // Check to see if timings are present and add to fieldmap if needed if ($survey->info['savetimings'] == "Y") { $survey->fieldMap = $survey->fieldMap + createTimingsFieldMap($intId, 'full', true, false, $lang); } if (empty($intId)) { //The id given to us is not an integer, croak. safeDie("An invalid survey ID was encountered: {$sid}"); } //Load groups $sQuery = 'SELECT g.* FROM {{groups}} AS g ' . 'WHERE g.sid = ' . $intId . ' AND g.language = \'' . $lang . '\' ' . 'ORDER BY g.group_order;'; $recordSet = Yii::app()->db->createCommand($sQuery)->query()->readAll(); $survey->groups = $recordSet; //Load questions $sQuery = 'SELECT q.* FROM {{questions}} AS q ' . 'JOIN {{groups}} AS g ON (q.gid = g.gid and q.language = g.language) ' . 'WHERE q.sid = ' . $intId . ' AND q.language = \'' . $lang . '\' ' . 'ORDER BY g.group_order, q.question_order;'; $survey->questions = Yii::app()->db->createCommand($sQuery)->query()->readAll(); //Load answers $sQuery = 'SELECT DISTINCT a.* FROM {{answers}} AS a ' . 'JOIN {{questions}} AS q ON a.qid = q.qid ' . 'WHERE q.sid = ' . $intId . ' AND a.language = \'' . $lang . '\' ' . 'ORDER BY a.qid, a.sortorder;'; //$survey->answers = Yii::app()->db->createCommand($sQuery)->queryAll(); $aAnswers = Yii::app()->db->createCommand($sQuery)->queryAll(); foreach ($aAnswers as $aAnswer) { if (Yii::app()->controller->action->id != 'remotecontrol') { $aAnswer['answer'] = stripTagsFull($aAnswer['answer']); } $survey->answers[$aAnswer['qid']][$aAnswer['scale_id']][$aAnswer['code']] = $aAnswer; } //Load language settings for requested language $sQuery = 'SELECT * FROM {{surveys_languagesettings}} WHERE surveyls_survey_id = ' . $intId . ' AND surveyls_language = \'' . $lang . '\';'; $recordSet = Yii::app()->db->createCommand($sQuery)->query(); $survey->languageSettings = $recordSet->read(); $recordSet->close(); if (tableExists('tokens_' . $survey->id) && array_key_exists('token', SurveyDynamic::model($survey->id)->attributes) && Permission::model()->hasSurveyPermission($survey->id, 'tokens', 'read')) { // Now add the tokenFields $survey->tokenFields = getTokenFieldsAndNames($survey->id); unset($survey->tokenFields['token']); } return $survey; }
function tokensExport($iSurveyID) { $sEmailFiter = trim(App()->request->getPost('filteremail')); $iTokenStatus = App()->request->getPost('tokenstatus'); $iInvitationStatus = App()->request->getPost('invitationstatus'); $iReminderStatus = App()->request->getPost('reminderstatus'); $sTokenLanguage = App()->request->getPost('tokenlanguage'); $oSurvey = Survey::model()->findByPk($iSurveyID); $bIsNotAnonymous = $oSurvey->anonymized == 'N' && $oSurvey->active == 'Y'; // db table exist (survey_$iSurveyID) ? $bquery = "SELECT * FROM {{tokens_{$iSurveyID}}} where 1=1"; $databasetype = Yii::app()->db->getDriverName(); if (trim($sEmailFiter) != '') { if (in_array($databasetype, array('mssql', 'sqlsrv', 'dblib'))) { $bquery .= ' and CAST(email as varchar) like ' . dbQuoteAll('%' . $_POST['filteremail'] . '%', true); } else { $bquery .= ' and email like ' . dbQuoteAll('%' . $_POST['filteremail'] . '%', true); } } if ($_POST['tokenstatus'] == 1) { $bquery .= " and completed<>'N'"; } elseif ($iTokenStatus == 2) { $bquery .= " and completed='N'"; } elseif ($iTokenStatus == 3 && $bIsNotAnonymous) { $bquery .= " and completed='N' and token not in (select token from {{survey_{$iSurveyID}}} group by token)"; } elseif ($iTokenStatus == 4 && $bIsNotAnonymous) { $bquery .= " and completed='N' and token in (select token from {{survey_{$iSurveyID}}} group by token)"; } if ($iInvitationStatus == 1) { $bquery .= " and sent<>'N'"; } if ($iInvitationStatus == 2) { $bquery .= " and sent='N'"; } if ($iReminderStatus == 1) { $bquery .= " and remindersent<>'N'"; } if ($iReminderStatus == 2) { $bquery .= " and remindersent='N'"; } if ($sTokenLanguage != '') { $bquery .= " and language=" . dbQuoteAll($sTokenLanguage); } $bquery .= " ORDER BY tid"; Yii::app()->loadHelper('database'); $bresult = Yii::app()->db->createCommand($bquery)->query(); //dbExecuteAssoc($bquery) is faster but deprecated! //HEADERS should be after the above query else timeout errors in case there are lots of tokens! header("Content-Disposition: attachment; filename=tokens_" . $iSurveyID . ".csv"); header("Content-type: text/comma-separated-values; charset=UTF-8"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Pragma: cache"); // Export UTF8 WITH BOM $tokenoutput = chr(hexdec('EF')) . chr(hexdec('BB')) . chr(hexdec('BF')); $tokenoutput .= "tid,firstname,lastname,email,emailstatus,token,language,validfrom,validuntil,invited,reminded,remindercount,completed,usesleft"; $attrfieldnames = getAttributeFieldNames($iSurveyID); $attrfielddescr = getTokenFieldsAndNames($iSurveyID, true); foreach ($attrfieldnames as $attr_name) { $tokenoutput .= ", {$attr_name}"; if (isset($attrfielddescr[$attr_name])) { $tokenoutput .= " <" . str_replace(",", " ", $attrfielddescr[$attr_name]['description']) . ">"; } } $tokenoutput .= "\n"; echo $tokenoutput; $tokenoutput = ""; // Export token line by line and fill $aExportedTokens with token exported Yii::import('application.libraries.Date_Time_Converter', true); $aExportedTokens = array(); while ($brow = $bresult->read()) { if (trim($brow['validfrom'] != '')) { $datetimeobj = new Date_Time_Converter($brow['validfrom'], "Y-m-d H:i:s"); $brow['validfrom'] = $datetimeobj->convert('Y-m-d H:i'); } if (trim($brow['validuntil'] != '')) { $datetimeobj = new Date_Time_Converter($brow['validuntil'], "Y-m-d H:i:s"); $brow['validuntil'] = $datetimeobj->convert('Y-m-d H:i'); } $tokenoutput .= '"' . trim($brow['tid']) . '",'; $tokenoutput .= '"' . trim($brow['firstname']) . '",'; $tokenoutput .= '"' . trim($brow['lastname']) . '",'; $tokenoutput .= '"' . trim($brow['email']) . '",'; $tokenoutput .= '"' . trim($brow['emailstatus']) . '",'; $tokenoutput .= '"' . trim($brow['token']) . '",'; $tokenoutput .= '"' . trim($brow['language']) . '",'; $tokenoutput .= '"' . trim($brow['validfrom']) . '",'; $tokenoutput .= '"' . trim($brow['validuntil']) . '",'; $tokenoutput .= '"' . trim($brow['sent']) . '",'; $tokenoutput .= '"' . trim($brow['remindersent']) . '",'; $tokenoutput .= '"' . trim($brow['remindercount']) . '",'; $tokenoutput .= '"' . trim($brow['completed']) . '",'; $tokenoutput .= '"' . trim($brow['usesleft']) . '",'; foreach ($attrfieldnames as $attr_name) { $tokenoutput .= '"' . trim($brow[$attr_name]) . '",'; } $tokenoutput = substr($tokenoutput, 0, -1); // remove last comma $tokenoutput .= "\n"; echo $tokenoutput; $tokenoutput = ''; $aExportedTokens[] = $brow['tid']; } if (Yii::app()->request->getPost('tokendeleteexported') && !empty($aExportedTokens)) { Token::model($iSurveyID)->deleteByPk($aExportedTokens); } }
function attributeMapToken() { Yii::app()->loadHelper('common'); App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . "attributeMapToken.js"); App()->getClientScript()->registerCssFile(Yii::app()->getConfig('adminstyleurl') . "attributeMapToken.css"); $iSurveyID = (int) Yii::app()->request->getQuery('sid'); $aCPDBAttributes = ParticipantAttributeName::model()->getCPDBAttributes(); $aTokenAttributes = getTokenFieldsAndNames($iSurveyID, TRUE); $selectedattribute = array(); $selectedcentralattribute = array(); $alreadymappedattid = array(); $alreadymappedattdisplay = array(); $alreadymappedattnames = array(); $i = 0; $j = 0; foreach ($aTokenAttributes as $key => $value) { if ($value['cpdbmap'] == '') { $selectedattribute[$value['description']] = $key; } else { $attributeid = $value['cpdbmap']; $continue = false; foreach ($aCPDBAttributes as $attribute) { if ($attribute['attribute_id'] == $attributeid) { $continue = true; } } if ($continue) { $alreadymappedattid[] = $attributeid; $alreadymappedattdisplay[] = $key; $alreadymappedattnames[$key] = $value['description']; } else { $selectedattribute[$value['description']] = $key; } } } foreach ($aCPDBAttributes as $row) { if (!in_array($row['attribute_id'], $alreadymappedattid)) { $selectedcentralattribute[$row['attribute_id']] = $row['attribute_name']; } } $aData = array('attribute' => $selectedcentralattribute, 'tokenattribute' => $selectedattribute, 'alreadymappedattributename' => $alreadymappedattdisplay, 'alreadymappedattdescription' => $alreadymappedattnames); $this->_renderWrappedTemplate('participants', 'attributeMapToken', $aData); }
function attributeMapToken() { Yii::app()->loadHelper('common'); $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . "attributeMapToken.js"); $this->getController()->_css_admin_includes(Yii::app()->getConfig('adminstyleurl') . "attributeMapToken.css"); $iSurveyId = Yii::app()->request->getQuery('sid'); $attributes = ParticipantAttributeNames::model()->getAttributes(); $tokenattributefieldnames = getTokenFieldsAndNames($iSurveyId, TRUE); $selectedattribute = array(); $selectedcentralattribute = array(); $alreadymappedattid = array(); $alreadymappedattdisplay = array(); $alreadymappedattnames = array(); $i = 0; $j = 0; foreach ($tokenattributefieldnames as $key => $value) { if (is_numeric($key[10])) { $selectedattribute[$value['description']] = $key; } else { $attributeid = substr($key, 15); $continue = false; foreach ($attributes as $attribute) { if ($attribute['attribute_id'] == $attributeid) { $continue = true; } } if ($continue) { array_push($alreadymappedattid, $attributeid); array_push($alreadymappedattdisplay, $key); $alreadymappedattnames[$key] = $value['description']; } else { $selectedattribute[$value['description']] = $key; } } } foreach ($attributes as $row) { if (!in_array($row['attribute_id'], $alreadymappedattid)) { $selectedcentralattribute[$row['attribute_id']] = $row['attribute_name']; } } $aData = array('attribute' => $selectedcentralattribute, 'tokenattribute' => $selectedattribute, 'alreadymappedattributename' => $alreadymappedattdisplay, 'alreadymappedattdescription' => $alreadymappedattnames); $this->_renderWrappedTemplate('participants', 'attributeMapToken', $aData); }
/** * Handle email action */ function email($iSurveyId, $tokenids = null) { /* Check permissions */ if (!hasSurveyPermission($iSurveyId, 'tokens', 'read')) { die("You do not have permission to view this page"); // TODO Replace } $aTokenIds = $tokenids; if (empty($tokenids)) { $aTokenIds = Yii::app()->request->getPost('tokenids', false); } if (!empty($aTokenIds)) { $aTokenIds = explode('|', $aTokenIds); $aTokenIds = array_filter($aTokenIds); $aTokenIds = array_map('sanitize_int', $aTokenIds); } $aTokenIds = array_unique(array_filter((array) $aTokenIds)); // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) { self::_newtokentable($iSurveyId); } $clang = $this->getController()->lang; $iSurveyId = sanitize_int($iSurveyId); if (!hasSurveyPermission($iSurveyId, 'tokens', 'update')) { die("no permissions"); // TODO Replace } $sSubAction = Yii::app()->request->getParam('action'); $sSubAction = !in_array($sSubAction, array('email', 'remind')) ? 'email' : $sSubAction; $bEmail = $sSubAction == 'email'; Yii::app()->loadHelper('surveytranslator'); Yii::app()->loadHelper('/admin/htmleditor'); Yii::app()->loadHelper('replacements'); $query = Tokens_dynamic::model($iSurveyId)->find(); $aExampleRow = empty($query) ? array() : $query->attributes; $aSurveyLangs = Survey::model()->findByPk($iSurveyId)->additionalLanguages; $sBaseLanguage = Survey::model()->findByPk($iSurveyId)->language; array_unshift($aSurveyLangs, $sBaseLanguage); $aTokenFields = getTokenFieldsAndNames($iSurveyId, true); $iAttributes = 0; $bHtml = getEmailFormat($iSurveyId) == 'html'; $timeadjust = Yii::app()->getConfig("timeadjust"); $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['surveyid'] = $iSurveyId; $aData['sSubAction'] = $sSubAction; $aData['bEmail'] = $bEmail; $aData['aSurveyLangs'] = $aData['surveylangs'] = $aSurveyLangs; $aData['baselang'] = $sBaseLanguage; $aData['tokenfields'] = $aTokenFields; $aData['nrofattributes'] = $iAttributes; $aData['examplerow'] = $aExampleRow; $aData['tokenids'] = $aTokenIds; $aData['ishtml'] = $bHtml; $iMaxEmails = Yii::app()->getConfig('maxemails'); if (Yii::app()->request->getPost('bypassbademails') == 'Y') { $SQLemailstatuscondition = "emailstatus = 'OK'"; } else { $SQLemailstatuscondition = "emailstatus <> 'OptOut'"; } if (!Yii::app()->request->getPost('ok')) { if (empty($aData['tokenids'])) { $aTokens = Tokens_dynamic::model($iSurveyId)->findUninvited($aTokenIds, 0, $bEmail, $SQLemailstatuscondition); foreach ($aTokens as $aToken) { $aData['tokenids'][] = $aToken['tid']; } } $this->_renderWrappedTemplate('token', array('tokenbar', $sSubAction), $aData); } else { $SQLremindercountcondition = ""; $SQLreminderdelaycondition = ""; if (!$bEmail) { if (Yii::app()->request->getPost('maxremindercount') && Yii::app()->request->getPost('maxremindercount') != '' && intval(Yii::app()->request->getPost('maxremindercount')) != 0) { $SQLremindercountcondition = "remindercount < " . intval(Yii::app()->request->getPost('maxremindercount')); } if (Yii::app()->request->getPost('minreminderdelay') && Yii::app()->request->getPost('minreminderdelay') != '' && intval(Yii::app()->request->getPost('minreminderdelay')) != 0) { // Yii::app()->request->getPost('minreminderdelay') in days (86400 seconds per day) $compareddate = dateShift(date("Y-m-d H:i:s", time() - 86400 * intval(Yii::app()->request->getPost('minreminderdelay'))), "Y-m-d H:i", $timeadjust); $SQLreminderdelaycondition = " ( " . " (remindersent = 'N' AND sent < '" . $compareddate . "') " . " OR " . " (remindersent < '" . $compareddate . "'))"; } } $ctresult = Tokens_dynamic::model($iSurveyId)->findUninvited($aTokenIds, 0, $bEmail, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition); $ctcount = count($ctresult); $emresult = Tokens_dynamic::model($iSurveyId)->findUninvited($aTokenIds, $iMaxEmails, $bEmail, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition); $emcount = count($emresult); foreach ($aSurveyLangs as $language) { $_POST['message_' . $language] = autoUnescape(Yii::app()->request->getPost('message_' . $language)); $_POST['subject_' . $language] = autoUnescape(Yii::app()->request->getPost('subject_' . $language)); if ($bHtml) { $_POST['message_' . $language] = html_entity_decode(Yii::app()->request->getPost('message_' . $language), ENT_QUOTES, Yii::app()->getConfig("emailcharset")); } } $attributes = getTokenFieldsAndNames($iSurveyId); $tokenoutput = ""; if ($emcount > 0) { foreach ($emresult as $emrow) { $to = array(); $aEmailaddresses = explode(';', $emrow['email']); foreach ($aEmailaddresses as $sEmailaddress) { $to[] = $emrow['firstname'] . " " . $emrow['lastname'] . " <{$sEmailaddress}>"; } $fieldsarray["{EMAIL}"] = $emrow['email']; $fieldsarray["{FIRSTNAME}"] = $emrow['firstname']; $fieldsarray["{LASTNAME}"] = $emrow['lastname']; $fieldsarray["{TOKEN}"] = $emrow['token']; $fieldsarray["{LANGUAGE}"] = $emrow['language']; foreach ($attributes as $attributefield => $attributedescription) { $fieldsarray['{' . strtoupper($attributefield) . '}'] = $emrow[$attributefield]; $fieldsarray['{TOKEN:' . strtoupper($attributefield) . '}'] = $emrow[$attributefield]; } $emrow['language'] = trim($emrow['language']); $found = array_search($emrow['language'], $aSurveyLangs); if ($emrow['language'] == '' || $found == false) { $emrow['language'] = $sBaseLanguage; } $from = Yii::app()->request->getPost('from_' . $emrow['language']); $fieldsarray["{OPTOUTURL}"] = $this->getController()->createAbsoluteUrl("/optout/tokens/langcode/" . trim($emrow['language']) . "/surveyid/{$iSurveyId}/token/{$emrow['token']}"); $fieldsarray["{OPTINURL}"] = $this->getController()->createAbsoluteUrl("/optin/tokens/langcode/" . trim($emrow['language']) . "/surveyid/{$iSurveyId}/token/{$emrow['token']}"); $fieldsarray["{SURVEYURL}"] = $this->getController()->createAbsoluteUrl("/survey/index/sid/{$iSurveyId}/token/{$emrow['token']}/langcode/" . trim($emrow['language']) . "/"); foreach (array('OPTOUT', 'OPTIN', 'SURVEY') as $key) { $url = $fieldsarray["{{$key}URL}"]; if ($bHtml) { $fieldsarray["{{$key}URL}"] = "<a href='{$url}'>" . htmlspecialchars($url) . '</a>'; } if ($key == 'SURVEY') { $barebone_link = $url; } } $customheaders = array('1' => "X-surveyid: " . $iSurveyId, '2' => "X-tokenid: " . $fieldsarray["{TOKEN}"]); global $maildebug; $modsubject = Replacefields(Yii::app()->request->getPost('subject_' . $emrow['language']), $fieldsarray); $modmessage = Replacefields(Yii::app()->request->getPost('message_' . $emrow['language']), $fieldsarray); if (isset($barebone_link)) { $modsubject = str_replace("@@SURVEYURL@@", $barebone_link, $modsubject); $modmessage = str_replace("@@SURVEYURL@@", $barebone_link, $modmessage); } if (trim($emrow['validfrom']) != '' && convertDateTimeFormat($emrow['validfrom'], 'Y-m-d H:i:s', 'U') * 1 > date('U') * 1) { $tokenoutput .= $emrow['tid'] . " " . ReplaceFields($clang->gT("Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) delayed: Token is not yet valid.") . "<br />", $fieldsarray); } elseif (trim($emrow['validuntil']) != '' && convertDateTimeFormat($emrow['validuntil'], 'Y-m-d H:i:s', 'U') * 1 < date('U') * 1) { $tokenoutput .= $emrow['tid'] . " " . ReplaceFields($clang->gT("Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) skipped: Token is not valid anymore.") . "<br />", $fieldsarray); } else { if (SendEmailMessage($modmessage, $modsubject, $to, $from, Yii::app()->getConfig("sitename"), $bHtml, getBounceEmail($iSurveyId), null, $customheaders)) { // Put date into sent $udequery = Tokens_dynamic::model($iSurveyId)->findByPk($emrow['tid']); if ($bEmail) { $tokenoutput .= $clang->gT("Invitation sent to:"); $udequery->sent = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust")); } else { $tokenoutput .= $clang->gT("Reminder sent to:"); $udequery->remindersent = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust")); $udequery->remindercount = $udequery->remindercount + 1; } $udequery->save(); //Update central participant survey_links if (!empty($emrow['participant_id'])) { $slquery = Survey_links::model()->find('participant_id = "' . $emrow['participant_id'] . '" AND survey_id = ' . $iSurveyId . ' AND token_id = ' . $emrow['tid']); $slquery->date_invited = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust")); $slquery->save(); } $tokenoutput .= "{$emrow['tid']}: {$emrow['firstname']} {$emrow['lastname']} ({$emrow['email']})<br />\n"; if (Yii::app()->getConfig("emailsmtpdebug") == 2) { $tokenoutput .= $maildebug; } } else { $tokenoutput .= ReplaceFields($clang->gT("Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) failed. Error Message:") . " " . $maildebug . "<br />", $fieldsarray); } } unset($fieldsarray); } $aViewUrls = array('tokenbar', 'emailpost'); $aData['tokenoutput'] = $tokenoutput; if ($ctcount > $emcount) { $i = 0; if (isset($aTokenIds)) { while ($i < $iMaxEmails) { array_shift($aTokenIds); $i++; } $aData['tids'] = implode('|', $aTokenIds); } $aData['lefttosend'] = $ctcount - $iMaxEmails; $aViewUrls[] = 'emailwarning'; } $this->_renderWrappedTemplate('token', $aViewUrls, $aData); } else { $this->_renderWrappedTemplate('token', array('tokenbar', 'message' => array('title' => $clang->gT("Warning"), 'message' => $clang->gT("There were no eligible emails to send. This will be because none satisfied the criteria of:") . "<br/> <ul><li>" . $clang->gT("having a valid email address") . "</li>" . "<li>" . $clang->gT("not having been sent an invitation already") . "</li>" . "<li>" . $clang->gT("having already completed the survey") . "</li>" . "<li>" . $clang->gT("having a token") . "</li></ul>")), $aData); } } }
/** * Sends email to tokens - invitation and reminders * * @param mixed $iSurveyID * @param array $aResultTokens * @param string $sType type of notification invite|register|remind * @return array of results */ function emailTokens($iSurveyID, $aResultTokens, $sType) { Yii::app()->loadHelper('common'); $oSurvey = Survey::model()->findByPk($iSurveyID); if (getEmailFormat($iSurveyID) == 'html') { $bHtml = true; } else { $bHtml = false; } $attributes = array_keys(getTokenFieldsAndNames($iSurveyID)); $oSurveyLocale = SurveyLanguageSetting::model()->findAllByAttributes(array('surveyls_survey_id' => $iSurveyID)); $oTokens = Token::model($iSurveyID); $aSurveyLangs = $oSurvey->additionalLanguages; array_unshift($aSurveyLangs, $oSurvey->language); //Convert result to associative array to minimize SurveyLocale access attempts foreach ($oSurveyLocale as $rows) { $oTempObject = array(); foreach ($rows as $k => $v) { $oTempObject[$k] = $v; } $aSurveyLocaleData[$rows['surveyls_language']] = $oTempObject; } foreach ($aResultTokens as $aTokenRow) { //Select language $aTokenRow['language'] = trim($aTokenRow['language']); $found = array_search($aTokenRow['language'], $aSurveyLangs); if ($aTokenRow['language'] == '' || $found == false) { $aTokenRow['language'] = $oSurvey['language']; } $sTokenLanguage = $aTokenRow['language']; //Build recipient $to = array(); $aEmailaddresses = explode(';', $aTokenRow['email']); foreach ($aEmailaddresses as $sEmailaddress) { $to[] = $aTokenRow['firstname'] . " " . $aTokenRow['lastname'] . " <{$sEmailaddress}>"; } //Populate attributes $fieldsarray["{SURVEYNAME}"] = $aSurveyLocaleData[$sTokenLanguage]['surveyls_title']; if ($fieldsarray["{SURVEYNAME}"] == '') { $fieldsarray["{SURVEYNAME}"] = $aSurveyLocaleData[$oSurvey['language']]['surveyls_title']; } $fieldsarray["{SURVEYDESCRIPTION}"] = $aSurveyLocaleData[$sTokenLanguage]['surveyls_description']; if ($fieldsarray["{SURVEYDESCRIPTION}"] == '') { $fieldsarray["{SURVEYDESCRIPTION}"] = $aSurveyLocaleData[$oSurvey['language']]['surveyls_description']; } $fieldsarray["{ADMINNAME}"] = $oSurvey['admin']; $fieldsarray["{ADMINEMAIL}"] = $oSurvey['adminemail']; $from = $fieldsarray["{ADMINNAME}"] . ' <' . $fieldsarray["{ADMINEMAIL}"] . '>'; if ($from == '') { $from = Yii::app()->getConfig('siteadminemail'); } foreach ($attributes as $attributefield) { $fieldsarray['{' . strtoupper($attributefield) . '}'] = $aTokenRow[$attributefield]; $fieldsarray['{TOKEN:' . strtoupper($attributefield) . '}'] = $aTokenRow[$attributefield]; } //create urls $fieldsarray["{OPTOUTURL}"] = Yii::app()->getController()->createAbsoluteUrl("/optout/tokens/langcode/" . trim($aTokenRow['language']) . "/surveyid/{$iSurveyID}/token/{$aTokenRow['token']}"); $fieldsarray["{OPTINURL}"] = Yii::app()->getController()->createAbsoluteUrl("/optin/tokens/langcode/" . trim($aTokenRow['language']) . "/surveyid/{$iSurveyID}/token/{$aTokenRow['token']}"); $fieldsarray["{SURVEYURL}"] = Yii::app()->getController()->createAbsoluteUrl("/survey/index/sid/{$iSurveyID}/token/{$aTokenRow['token']}/lang/" . trim($aTokenRow['language']) . "/"); if ($bHtml) { foreach (array('OPTOUT', 'OPTIN', 'SURVEY') as $key) { $url = $fieldsarray["{{$key}URL}"]; $fieldsarray["{{$key}URL}"] = "<a href='{$url}'>" . htmlspecialchars($url) . '</a>'; if ($key == 'SURVEY') { $barebone_link = $url; } } } //mail headers $customheaders = array('1' => "X-surveyid: " . $iSurveyID, '2' => "X-tokenid: " . $fieldsarray["{TOKEN}"]); global $maildebug; //choose appriopriate email message if ($sType == 'invite') { $sSubject = $aSurveyLocaleData[$sTokenLanguage]['surveyls_email_invite_subj']; $sMessage = $aSurveyLocaleData[$sTokenLanguage]['surveyls_email_invite']; } else { if ($sType == 'register') { $sSubject = $aSurveyLocaleData[$sTokenLanguage]['surveyls_email_register_subj']; $sMessage = $aSurveyLocaleData[$sTokenLanguage]['surveyls_email_register']; } else { $sSubject = $aSurveyLocaleData[$sTokenLanguage]['surveyls_email_remind_subj']; $sMessage = $aSurveyLocaleData[$sTokenLanguage]['surveyls_email_remind']; } } $modsubject = Replacefields($sSubject, $fieldsarray); $modmessage = Replacefields($sMessage, $fieldsarray); if (isset($barebone_link)) { $modsubject = str_replace("@@SURVEYURL@@", $barebone_link, $modsubject); $modmessage = str_replace("@@SURVEYURL@@", $barebone_link, $modmessage); } if (isset($aTokenRow['validfrom']) && trim($aTokenRow['validfrom']) != '' && convertDateTimeFormat($aTokenRow['validfrom'], 'Y-m-d H:i:s', 'U') * 1 > date('U') * 1) { $aResult[$aTokenRow['tid']] = array('name' => $fieldsarray["{FIRSTNAME}"] . " " . $fieldsarray["{LASTNAME}"], 'email' => $fieldsarray["{EMAIL}"], 'status' => 'fail', 'error' => 'Token not valid yet'); } elseif (isset($aTokenRow['validuntil']) && trim($aTokenRow['validuntil']) != '' && convertDateTimeFormat($aTokenRow['validuntil'], 'Y-m-d H:i:s', 'U') * 1 < date('U') * 1) { $aResult[$aTokenRow['tid']] = array('name' => $fieldsarray["{FIRSTNAME}"] . " " . $fieldsarray["{LASTNAME}"], 'email' => $fieldsarray["{EMAIL}"], 'status' => 'fail', 'error' => 'Token not valid anymore'); } else { if (SendEmailMessage($modmessage, $modsubject, $to, $from, Yii::app()->getConfig("sitename"), $bHtml, getBounceEmail($iSurveyID), null, $customheaders)) { $aResult[$aTokenRow['tid']] = array('name' => $fieldsarray["{FIRSTNAME}"] . " " . $fieldsarray["{LASTNAME}"], 'email' => $fieldsarray["{EMAIL}"], 'status' => 'OK'); if ($sType == 'invite' || $sType == 'register') { $oTokens->updateByPk($aTokenRow['tid'], array('sent' => dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust")))); } if ($sType == 'remind') { $iRCount = $oTokens->findByPk($aTokenRow['tid'])->remindercount + 1; $oTokens->updateByPk($aTokenRow['tid'], array('remindersent' => dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust")))); $oTokens->updateByPk($aTokenRow['tid'], array('remindercount' => $iRCount)); } } else { $aResult[$aTokenRow['tid']] = array('name' => $fieldsarray["{FIRSTNAME}"] . " " . $fieldsarray["{LASTNAME}"], 'email' => $fieldsarray["{EMAIL}"], 'status' => 'fail', 'error' => $maildebug); } } unset($fieldsarray); } return $aResult; }
/** * import from csv */ function import($iSurveyId) { $clang = $this->getController()->lang; $iSurveyId = (int) $iSurveyId; if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'import')) { Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page."); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); } // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) { self::_newtokentable($iSurveyId); } App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . 'tokensimport.js'); $aEncodings = aEncodingsArray(); if (Yii::app()->request->getPost('submit')) { if (Yii::app()->request->getPost('csvcharset') && Yii::app()->request->getPost('csvcharset')) { $uploadcharset = Yii::app()->request->getPost('csvcharset'); if (!array_key_exists($uploadcharset, $aEncodings)) { $uploadcharset = 'auto'; } $filterduplicatetoken = Yii::app()->request->getPost('filterduplicatetoken') && Yii::app()->request->getPost('filterduplicatetoken') == 'on'; $filterblankemail = Yii::app()->request->getPost('filterblankemail') && Yii::app()->request->getPost('filterblankemail') == 'on'; } $attrfieldnames = getAttributeFieldNames($iSurveyId); $duplicatelist = array(); $invalidemaillist = array(); $invalidformatlist = array(); $firstline = array(); $sPath = Yii::app()->getConfig('tempdir'); $sFileTmpName = $_FILES['the_file']['tmp_name']; $sFilePath = $sPath . '/' . randomChars(20); if (!@move_uploaded_file($sFileTmpName, $sFilePath)) { $aData['sError'] = $clang->gT("Upload file not found. Check your permissions and path ({$sFilePath}) for the upload directory"); $aData['aEncodings'] = $aEncodings; $aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $this->_renderWrappedTemplate('token', array('tokenbar', 'csvupload'), $aData); } else { $xz = 0; $recordcount = 0; $xv = 0; // This allows to read file with MAC line endings too @ini_set('auto_detect_line_endings', true); // open it and trim the ednings $tokenlistarray = file($sFilePath); $sBaseLanguage = Survey::model()->findByPk($iSurveyId)->language; if (!Yii::app()->request->getPost('filterduplicatefields') || Yii::app()->request->getPost('filterduplicatefields') && count(Yii::app()->request->getPost('filterduplicatefields')) == 0) { $filterduplicatefields = array('firstname', 'lastname', 'email'); } else { $filterduplicatefields = Yii::app()->request->getPost('filterduplicatefields'); } $separator = returnGlobal('separator'); foreach ($tokenlistarray as $buffer) { $buffer = @mb_convert_encoding($buffer, "UTF-8", $uploadcharset); if ($recordcount == 0) { // Parse first line (header) from CSV $buffer = removeBOM($buffer); // We alow all field except tid because this one is really not needed. $allowedfieldnames = array('participant_id', 'firstname', 'lastname', 'email', 'emailstatus', 'token', 'language', 'blacklisted', 'sent', 'remindersent', 'remindercount', 'validfrom', 'validuntil', 'completed', 'usesleft'); $allowedfieldnames = array_merge($attrfieldnames, $allowedfieldnames); // Some header don't have same column name $aReplacedFields = array('invited' => 'sent'); switch ($separator) { case 'comma': $separator = ','; break; case 'semicolon': $separator = ';'; break; default: $comma = substr_count($buffer, ','); $semicolon = substr_count($buffer, ';'); if ($semicolon > $comma) { $separator = ';'; } else { $separator = ','; } } $firstline = str_getcsv($buffer, $separator, '"'); $firstline = array_map('trim', $firstline); $ignoredcolumns = array(); // Now check the first line for invalid fields foreach ($firstline as $index => $fieldname) { $firstline[$index] = preg_replace("/(.*) <[^,]*>\$/", "\$1", $fieldname); $fieldname = $firstline[$index]; if (!in_array($fieldname, $allowedfieldnames)) { $ignoredcolumns[] = $fieldname; } if (array_key_exists($fieldname, $aReplacedFields)) { $firstline[$index] = $aReplacedFields[$fieldname]; } } if (!in_array('firstname', $firstline) || !in_array('lastname', $firstline) || !in_array('email', $firstline)) { $recordcount = count($tokenlistarray); break; } } else { $line = str_getcsv($buffer, $separator, '"'); if (count($firstline) != count($line)) { $invalidformatlist[] = $recordcount; $recordcount++; continue; } $writearray = array_combine($firstline, $line); //kick out ignored columns foreach ($ignoredcolumns as $column) { unset($writearray[$column]); } $dupfound = false; $invalidemail = false; if ($filterduplicatetoken != false) { $dupquery = "SELECT count(tid) from {{tokens_" . intval($iSurveyId) . "}} where 1=1"; foreach ($filterduplicatefields as $field) { if (isset($writearray[$field])) { $dupquery .= " and " . Yii::app()->db->quoteColumnName($field) . " = " . Yii::app()->db->quoteValue($writearray[$field]); } } $dupresult = Yii::app()->db->createCommand($dupquery)->queryScalar(); if ($dupresult > 0) { $dupfound = true; $duplicatelist[] = Yii::app()->db->quoteValue($writearray['firstname']) . " " . Yii::app()->db->quoteValue($writearray['lastname']) . " (" . Yii::app()->db->quoteValue($writearray['email']) . ")"; } } $writearray['email'] = trim($writearray['email']); //treat blank emails if ($filterblankemail && $writearray['email'] == '') { $invalidemail = true; $invalidemaillist[] = $line[0] . " " . $line[1] . " ( )"; } if ($writearray['email'] != '') { $aEmailAddresses = explode(';', $writearray['email']); foreach ($aEmailAddresses as $sEmailaddress) { if (!validateEmailAddress($sEmailaddress)) { $invalidemail = true; $invalidemaillist[] = $line[0] . " " . $line[1] . " (" . $line[2] . ")"; } } } if (isset($writearray['token'])) { $writearray['token'] = sanitize_token($writearray['token']); } if (!$dupfound && !$invalidemail) { // unset all empty value foreach ($writearray as $key => $value) { if ($writearray[$key] == "") { unset($writearray[$key]); } if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { // Fix CSV quote $value = substr($value, 1, -1); } } // Some default value : to be moved to Token model rules in future release ? // But think we have to accept invalid email etc ... then use specific scenario $writearray['emailstatus'] = isset($writearray['emailstatus']) ? $writearray['emailstatus'] : "OK"; $writearray['language'] = isset($writearray['language']) ? $writearray['language'] : $sBaseLanguage; $oToken = Token::create($iSurveyId); foreach ($writearray as $key => $value) { //if(in_array($key,$oToken->attributes)) Not needed because we filter attributes before $oToken->{$key} = $value; } $ir = $oToken->save(); if (!$ir) { $duplicatelist[] = $writearray['firstname'] . " " . $writearray['lastname'] . " (" . $writearray['email'] . ")"; } else { $xz++; } } $xv++; } $recordcount++; } $recordcount = $recordcount - 1; unlink($sFilePath); $aData['tokenlistarray'] = $tokenlistarray; $aData['xz'] = $xz; $aData['xv'] = $xv; $aData['recordcount'] = $recordcount; $aData['firstline'] = $firstline; $aData['duplicatelist'] = $duplicatelist; $aData['invalidformatlist'] = $invalidformatlist; $aData['invalidemaillist'] = $invalidemaillist; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId; $this->_renderWrappedTemplate('token', array('tokenbar', 'csvpost'), $aData); } } else { $aData['aEncodings'] = $aEncodings; $aData['iSurveyId'] = $iSurveyId; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['surveyid'] = $iSurveyId; $aTokenTableFields = getTokenFieldsAndNames($iSurveyId); unset($aTokenTableFields['sent']); unset($aTokenTableFields['remindersent']); unset($aTokenTableFields['remindercount']); unset($aTokenTableFields['usesleft']); foreach ($aTokenTableFields as $sKey => $sValue) { if ($sValue['description'] != $sKey) { $sValue['description'] .= ' - ' . $sKey; } $aNewTokenTableFields[$sKey] = $sValue['description']; } $aData['aTokenTableFields'] = $aNewTokenTableFields; $this->_renderWrappedTemplate('token', array('tokenbar', 'csvupload'), $aData); } }
<select name='attribute_select[]' multiple size='20' class="form-control" id="attribute_select"> <option value='first_name' id='first_name'><?php eT("First name"); ?> </option> <option value='last_name' id='last_name'><?php eT("Last name"); ?> </option> <option value='email_address' id='email_address'><?php eT("Email address"); ?> </option> <?php $attrfieldnames = getTokenFieldsAndNames($surveyid, true); foreach ($attrfieldnames as $attr_name => $attr_desc) { echo "<option value='{$attr_name}' id='{$attr_name}' />" . $attr_desc['description'] . "</option>\n"; } ?> </select> </div> </div> </div> <?php } ?> </div> </div> </div>
/** * This function is responsible for attribute mapping while copying participants from tokens to CPDB */ public function attributeMapToken() { Yii::app()->loadHelper('common'); $this->registerScriptFile('ADMIN_SCRIPT_PATH', 'attributeMapToken.js'); $this->registerCssFile('ADMIN', 'attributeMapToken.css'); $iSurveyID = (int) Yii::app()->request->getQuery('sid'); $aCPDBAttributes = ParticipantAttributeName::model()->getCPDBAttributes(); $aTokenAttributes = getTokenFieldsAndNames($iSurveyID, TRUE); $selectedattribute = array(); $selectedcentralattribute = array(); $alreadymappedattid = array(); $alreadymappedattdisplay = array(); $alreadymappedattnames = array(); foreach ($aTokenAttributes as $key => $value) { if ($value['cpdbmap'] == '') { $selectedattribute[$value['description']] = $key; } else { $attributeid = $value['cpdbmap']; $continue = false; foreach ($aCPDBAttributes as $attribute) { if ($attribute['attribute_id'] == $attributeid) { $continue = true; } } if ($continue) { $alreadymappedattid[] = $attributeid; $alreadymappedattdisplay[] = $key; $alreadymappedattnames[$key] = $value['description']; } else { $selectedattribute[$value['description']] = $key; } } } foreach ($aCPDBAttributes as $row) { if (!in_array($row['attribute_id'], $alreadymappedattid)) { $selectedcentralattribute[$row['attribute_id']] = $row['attribute_name']; } } if (count($selectedattribute) === 0) { Yii::app()->setFlashMessage(gT("There are no unmapped attributes"), 'warning'); } $aData = array('attribute' => $selectedcentralattribute, 'tokenattribute' => $selectedattribute, 'alreadymappedattributename' => $alreadymappedattdisplay, 'alreadymappedattdescription' => $alreadymappedattnames); $this->_renderWrappedTemplate('participants', 'attributeMapToken', $aData); }
private function _getReplacementFields($fieldtype, $surveyid) { $clang = Yii::app()->lang; $replFields = array(); switch ($fieldtype) { case 'survey-desc': case 'survey-welc': case 'survey-endtext': case 'edittitle': // for translation // for translation case 'editdescription': // for translation // for translation case 'editwelcome': // for translation // for translation case 'editend': // for translation $replFields[] = array('TOKEN:FIRSTNAME', $clang->gT("Firstname from token")); $replFields[] = array('TOKEN:LASTNAME', $clang->gT("Lastname from token")); $replFields[] = array('TOKEN:EMAIL', $clang->gT("Email from the token")); $attributes = getTokenFieldsAndNames($surveyid, true); foreach ($attributes as $attributefield => $attributedescription) { $replFields[] = array('TOKEN:' . strtoupper($attributefield), sprintf($clang->gT("Token attribute: %s"), $attributedescription['description'])); } $replFields[] = array('EXPIRY', $clang->gT("Survey expiration date")); return array($replFields, false); case 'email-admin-notification': $replFields[] = array('RELOADURL', $clang->gT("Reload URL")); $replFields[] = array('VIEWRESPONSEURL', $clang->gT("View response URL")); $replFields[] = array('EDITRESPONSEURL', $clang->gT("Edit response URL")); $replFields[] = array('STATISTICSURL', $clang->gT("Statistics URL")); $replFields[] = array('TOKEN', $clang->gT("Token code for this participant")); $replFields[] = array('TOKEN:FIRSTNAME', $clang->gT("First name from token")); $replFields[] = array('TOKEN:LASTNAME', $clang->gT("Last name from token")); $replFields[] = array('SURVEYNAME', $clang->gT("Name of the survey")); $replFields[] = array('SURVEYDESCRIPTION', $clang->gT("Description of the survey")); $attributes = getTokenFieldsAndNames($surveyid, true); foreach ($attributes as $attributefield => $attributedescription) { $replFields[] = array(strtoupper($attributefield), sprintf($clang->gT("Token attribute: %s"), $attributedescription['description'])); } $replFields[] = array('ADMINNAME', $clang->gT("Name of the survey administrator")); $replFields[] = array('ADMINEMAIL', $clang->gT("Email address of the survey administrator")); return array($replFields, false); case 'email-admin-resp': $replFields[] = array('RELOADURL', $clang->gT("Reload URL")); $replFields[] = array('VIEWRESPONSEURL', $clang->gT("View response URL")); $replFields[] = array('EDITRESPONSEURL', $clang->gT("Edit response URL")); $replFields[] = array('STATISTICSURL', $clang->gT("Statistics URL")); $replFields[] = array('ANSWERTABLE', $clang->gT("Answers from this response")); $replFields[] = array('TOKEN', $clang->gT("Token code for this participant")); $replFields[] = array('TOKEN:FIRSTNAME', $clang->gT("First name from token")); $replFields[] = array('TOKEN:LASTNAME', $clang->gT("Last name from token")); $replFields[] = array('SURVEYNAME', $clang->gT("Name of the survey")); $replFields[] = array('SURVEYDESCRIPTION', $clang->gT("Description of the survey")); $attributes = getTokenFieldsAndNames($surveyid, true); foreach ($attributes as $attributefield => $attributedescription) { $replFields[] = array(strtoupper($attributefield), sprintf($clang->gT("Token attribute: %s"), $attributedescription['description'])); } $replFields[] = array('ADMINNAME', $clang->gT("Name of the survey administrator")); $replFields[] = array('ADMINEMAIL', $clang->gT("Email address of the survey administrator")); return array($replFields, false); case 'email-inv': case 'email-rem': // these 2 fields are supported by email-inv and email-rem // but not email-reg for the moment $replFields[] = array('EMAIL', $clang->gT("Email from the token")); $replFields[] = array('TOKEN', $clang->gT("Token code for this participant")); $replFields[] = array('OPTOUTURL', $clang->gT("URL for a respondent to opt-out this survey")); $replFields[] = array('OPTINURL', $clang->gT("URL for a respondent to opt-in this survey")); case 'email-reg': $replFields[] = array('FIRSTNAME', $clang->gT("Firstname from token")); $replFields[] = array('LASTNAME', $clang->gT("Lastname from token")); $replFields[] = array('SURVEYNAME', $clang->gT("Name of the survey")); $replFields[] = array('SURVEYDESCRIPTION', $clang->gT("Description of the survey")); $attributes = getTokenFieldsAndNames($surveyid, true); foreach ($attributes as $attributefield => $attributedescription) { $replFields[] = array(strtoupper($attributefield), sprintf($clang->gT("Token attribute: %s"), $attributedescription['description'])); } $replFields[] = array('ADMINNAME', $clang->gT("Name of the survey administrator")); $replFields[] = array('ADMINEMAIL', $clang->gT("Email address of the survey administrator")); $replFields[] = array('SURVEYURL', $clang->gT("URL of the survey")); $replFields[] = array('EXPIRY', $clang->gT("Survey expiration date")); return array($replFields, false); case 'email-conf': $replFields[] = array('TOKEN', $clang->gT("Token code for this participant")); $replFields[] = array('FIRSTNAME', $clang->gT("Firstname from token")); $replFields[] = array('LASTNAME', $clang->gT("Lastname from token")); $replFields[] = array('SURVEYNAME', $clang->gT("Name of the survey")); $replFields[] = array('SURVEYDESCRIPTION', $clang->gT("Description of the survey")); $attributes = getTokenFieldsAndNames($surveyid, true); foreach ($attributes as $attributefield => $attributedescription) { $replFields[] = array(strtoupper($attributefield), sprintf($clang->gT("Token attribute: %s"), $attributedescription['description'])); } $replFields[] = array('ADMINNAME', $clang->gT("Name of the survey administrator")); $replFields[] = array('ADMINEMAIL', $clang->gT("Email address of the survey administrator")); $replFields[] = array('SURVEYURL', $clang->gT("URL of the survey")); $replFields[] = array('EXPIRY', $clang->gT("Survey expiration date")); // email-conf can accept insertans fields for non anonymous surveys if (isset($surveyid)) { $surveyInfo = getSurveyInfo($surveyid); if ($surveyInfo['anonymized'] == "N") { return array($replFields, true); } } return array($replFields, false); case 'group-desc': case 'question-text': case 'question-help': case 'editgroup': // for translation // for translation case 'editgroup_desc': // for translation // for translation case 'editquestion': // for translation // for translation case 'editquestion_help': // for translation $replFields[] = array('TOKEN:FIRSTNAME', $clang->gT("Firstname from token")); $replFields[] = array('TOKEN:LASTNAME', $clang->gT("Lastname from token")); $replFields[] = array('TOKEN:EMAIL', $clang->gT("Email from the token")); $replFields[] = array('SID', $clang->gT("This question's survey ID number")); $replFields[] = array('GID', $clang->gT("This question's group ID number")); $replFields[] = array('QID', $clang->gT("This question's question ID number")); $replFields[] = array('SGQ', $clang->gT("This question's SGQA code")); $attributes = getTokenFieldsAndNames($surveyid, true); foreach ($attributes as $attributefield => $attributedescription) { $replFields[] = array('TOKEN:' . strtoupper($attributefield), sprintf($clang->gT("Token attribute: %s"), $attributedescription['description'])); } $replFields[] = array('EXPIRY', $clang->gT("Survey expiration date")); case 'editanswer': return array($replFields, true); case 'assessment-text': $replFields[] = array('TOTAL', $clang->gT("Overall assessment score")); $replFields[] = array('PERC', $clang->gT("Assessment group score")); return array($replFields, false); } }
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; }
/** * import from csv */ public function import($iSurveyId) { $aData = array(); $iSurveyId = (int) $iSurveyId; if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'import')) { Yii::app()->session['flashmessage'] = gT("You do not have permission to access this page."); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); } // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) { self::_newtokentable($iSurveyId); } $surveyinfo = Survey::model()->findByPk($iSurveyId)->surveyinfo; $aData['sidemenu']['state'] = false; $aData["surveyinfo"] = $surveyinfo; $aData['title_bar']['title'] = $surveyinfo['surveyls_title'] . "(" . gT("ID") . ":" . $iSurveyId . ")"; $aData['sidemenu']["token_menu"] = TRUE; $aData['token_bar']['closebutton']['url'] = 'admin/tokens/sa/index/surveyid/' . $iSurveyId; $this->registerScriptFile('ADMIN_SCRIPT_PATH', 'tokensimport.js'); $aEncodings = aEncodingsArray(); if (Yii::app()->request->isPostRequest) { $sUploadCharset = Yii::app()->request->getPost('csvcharset'); if (!array_key_exists($sUploadCharset, $aEncodings)) { $sUploadCharset = 'auto'; } $bFilterDuplicateToken = Yii::app()->request->getPost('filterduplicatetoken'); $bFilterBlankEmail = Yii::app()->request->getPost('filterblankemail'); $bAllowInvalidEmail = Yii::app()->request->getPost('allowinvalidemail'); $aAttrFieldNames = getAttributeFieldNames($iSurveyId); $aDuplicateList = array(); $aInvalidTokenList = array(); $aInvalidEmailList = array(); $aInvalidFormatList = array(); $aModelErrorList = array(); $aFirstLine = array(); $oFile = CUploadedFile::getInstanceByName("the_file"); $sPath = Yii::app()->getConfig('tempdir'); $sFileName = $sPath . '/' . randomChars(20); if ($_FILES['the_file']['error'] == 1 || $_FILES['the_file']['error'] == 2) { Yii::app()->setFlashMessage(sprintf(gT("Sorry, this file is too large. Only files up to %01.2f MB are allowed."), getMaximumFileUploadSize() / 1024 / 1024), 'error'); } elseif (strtolower($oFile->getExtensionName()) != 'csv') { Yii::app()->setFlashMessage(gT("Only CSV files are allowed."), 'error'); } elseif (!@$oFile->saveAs($sFileName)) { Yii::app()->setFlashMessage(sprintf(gT("Upload file not found. Check your permissions and path (%s) for the upload directory"), $sPath), 'error'); } else { $iRecordImported = 0; $iRecordCount = 0; $iRecordOk = 0; $iInvalidEmailCount = 0; // Count invalid email imported // This allows to read file with MAC line endings too @ini_set('auto_detect_line_endings', true); // open it and trim the ednings $aTokenListArray = file($sFileName); $sBaseLanguage = Survey::model()->findByPk($iSurveyId)->language; if (!Yii::app()->request->getPost('filterduplicatefields') || Yii::app()->request->getPost('filterduplicatefields') && count(Yii::app()->request->getPost('filterduplicatefields')) == 0) { $aFilterDuplicateFields = array('firstname', 'lastname', 'email'); } else { $aFilterDuplicateFields = Yii::app()->request->getPost('filterduplicatefields'); } $sSeparator = Yii::app()->request->getPost('separator'); $aMissingAttrFieldName = $aInvalideAttrFieldName = array(); foreach ($aTokenListArray as $buffer) { $buffer = @mb_convert_encoding($buffer, "UTF-8", $sUploadCharset); if ($iRecordCount == 0) { // Parse first line (header) from CSV $buffer = removeBOM($buffer); // We alow all field except tid because this one is really not needed. $aAllowedFieldNames = Token::model($iSurveyId)->tableSchema->getColumnNames(); if (($kTid = array_search('tid', $aAllowedFieldNames)) !== false) { unset($aAllowedFieldNames[$kTid]); } // Some header don't have same column name $aReplacedFields = array('invited' => 'sent', 'reminded' => 'remindersent'); switch ($sSeparator) { case 'comma': $sSeparator = ','; break; case 'semicolon': $sSeparator = ';'; break; default: $comma = substr_count($buffer, ','); $semicolon = substr_count($buffer, ';'); if ($semicolon > $comma) { $sSeparator = ';'; } else { $sSeparator = ','; } } $aFirstLine = str_getcsv($buffer, $sSeparator, '"'); $aFirstLine = array_map('trim', $aFirstLine); $aIgnoredColumns = array(); // Now check the first line for invalid fields foreach ($aFirstLine as $index => $sFieldname) { $aFirstLine[$index] = preg_replace("/(.*) <[^,]*>\$/", "\$1", $sFieldname); $sFieldname = $aFirstLine[$index]; if (!in_array($sFieldname, $aAllowedFieldNames)) { $aIgnoredColumns[] = $sFieldname; } if (array_key_exists($sFieldname, $aReplacedFields)) { $aFirstLine[$index] = $aReplacedFields[$sFieldname]; } // Attribute not in list if (strpos($aFirstLine[$index], 'attribute_') !== false and !in_array($aFirstLine[$index], $aAttrFieldNames) and Yii::app()->request->getPost('showwarningtoken')) { $aInvalideAttrFieldName[] = $aFirstLine[$index]; } } //compare attributes with source csv if (Yii::app()->request->getPost('showwarningtoken')) { $aMissingAttrFieldName = array_diff($aAttrFieldNames, $aFirstLine); // get list of mandatory attributes $allAttrFieldNames = GetParticipantAttributes($iSurveyId); //if it isn't mandantory field we don't need to show in warning if (!empty($aAttrFieldNames)) { if (!empty($aMissingAttrFieldName)) { foreach ($aMissingAttrFieldName as $index => $AttrFieldName) { if (isset($allAttrFieldNames[$AttrFieldName]) and strtolower($allAttrFieldNames[$AttrFieldName]["mandatory"]) != "y") { unset($aMissingAttrFieldName[$index]); } } } if (isset($aInvalideAttrFieldName) and !empty($aInvalideAttrFieldName)) { foreach ($aInvalideAttrFieldName as $index => $AttrFieldName) { if (isset($allAttrFieldNames[$AttrFieldName]) and strtolower($allAttrFieldNames[$AttrFieldName]["mandatory"]) != "y") { unset($aInvalideAttrFieldName[$index]); } } } } } } else { $line = str_getcsv($buffer, $sSeparator, '"'); if (count($aFirstLine) != count($line)) { $aInvalidFormatList[] = sprintf(gT("Line %s"), $iRecordCount); $iRecordCount++; continue; } $aWriteArray = array_combine($aFirstLine, $line); //kick out ignored columns foreach ($aIgnoredColumns as $column) { unset($aWriteArray[$column]); } $bDuplicateFound = false; $bInvalidEmail = false; $bInvalidToken = false; $aWriteArray['email'] = isset($aWriteArray['email']) ? trim($aWriteArray['email']) : ""; $aWriteArray['firstname'] = isset($aWriteArray['firstname']) ? $aWriteArray['firstname'] : ""; $aWriteArray['lastname'] = isset($aWriteArray['lastname']) ? $aWriteArray['lastname'] : ""; $aWriteArray['language'] = isset($aWriteArray['language']) ? $aWriteArray['language'] : $sBaseLanguage; if ($bFilterDuplicateToken) { $aParams = array(); $oCriteria = new CDbCriteria(); $oCriteria->condition = ""; foreach ($aFilterDuplicateFields as $field) { if (isset($aWriteArray[$field])) { $oCriteria->addCondition("{$field} = :{$field}"); $aParams[":{$field}"] = $aWriteArray[$field]; } } if (!empty($aParams)) { $oCriteria->params = $aParams; } $dupresult = TokenDynamic::model($iSurveyId)->count($oCriteria); if ($dupresult > 0) { $bDuplicateFound = true; $aDuplicateList[] = sprintf(gT("Line %s : %s %s (%s)"), $iRecordCount, $aWriteArray['firstname'], $aWriteArray['lastname'], $aWriteArray['email']); } } //treat blank emails if (!$bDuplicateFound && $bFilterBlankEmail && $aWriteArray['email'] == '') { $bInvalidEmail = true; $aInvalidEmailList[] = sprintf(gT("Line %s : %s %s"), $iRecordCount, CHtml::encode($aWriteArray['firstname']), CHtml::encode($aWriteArray['lastname'])); } if (!$bDuplicateFound && $aWriteArray['email'] != '') { $aEmailAddresses = preg_split("/(,|;)/", $aWriteArray['email']); foreach ($aEmailAddresses as $sEmailaddress) { if (!validateEmailAddress($sEmailaddress)) { if ($bAllowInvalidEmail) { $iInvalidEmailCount++; if (empty($aWriteArray['emailstatus']) || strtoupper($aWriteArray['emailstatus'] == "OK")) { $aWriteArray['emailstatus'] = "invalid"; } } else { $bInvalidEmail = true; $aInvalidEmailList[] = sprintf(gT("Line %s : %s %s (%s)"), $iRecordCount, CHtml::encode($aWriteArray['firstname']), CHtml::encode($aWriteArray['lastname']), CHtml::encode($aWriteArray['email'])); } } } } if (!$bDuplicateFound && !$bInvalidEmail && isset($aWriteArray['token']) && trim($aWriteArray['token']) != '') { if (trim($aWriteArray['token']) != sanitize_token($aWriteArray['token'])) { $aInvalidTokenList[] = sprintf(gT("Line %s : %s %s (%s) - token : %s"), $iRecordCount, CHtml::encode($aWriteArray['firstname']), CHtml::encode($aWriteArray['lastname']), CHtml::encode($aWriteArray['email']), CHtml::encode($aWriteArray['token'])); $bInvalidToken = true; } // We allways search for duplicate token (it's in model. Allow to reset or update token ? if (Token::model($iSurveyId)->count("token=:token", array(":token" => $aWriteArray['token']))) { $bDuplicateFound = true; $aDuplicateList[] = sprintf(gT("Line %s : %s %s (%s) - token : %s"), $iRecordCount, CHtml::encode($aWriteArray['firstname']), CHtml::encode($aWriteArray['lastname']), CHtml::encode($aWriteArray['email']), CHtml::encode($aWriteArray['token'])); } } if (!$bDuplicateFound && !$bInvalidEmail && !$bInvalidToken) { // unset all empty value foreach ($aWriteArray as $key => $value) { if ($aWriteArray[$key] == "") { unset($aWriteArray[$key]); } if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { // Fix CSV quote $value = substr($value, 1, -1); } } // Some default value : to be moved to Token model rules in future release ? // But think we have to accept invalid email etc ... then use specific scenario $oToken = Token::create($iSurveyId); if ($bAllowInvalidEmail) { $oToken->scenario = 'allowinvalidemail'; } foreach ($aWriteArray as $key => $value) { $oToken->{$key} = $value; } if (!$oToken->save()) { $errors = $oToken->getErrors(); $aModelErrorList[] = sprintf(gT("Line %s : %s"), $iRecordCount, print_r($errors, true)); } else { $iRecordImported++; } } $iRecordOk++; } $iRecordCount++; } $iRecordCount = $iRecordCount - 1; unlink($sFileName); $aData['aTokenListArray'] = $aTokenListArray; // Big array in memory, just for success ? $aData['iRecordImported'] = $iRecordImported; $aData['iRecordOk'] = $iRecordOk; $aData['iRecordCount'] = $iRecordCount; $aData['aFirstLine'] = $aFirstLine; // Seem not needed $aData['aDuplicateList'] = $aDuplicateList; $aData['aInvalidTokenList'] = $aInvalidTokenList; $aData['aInvalidFormatList'] = $aInvalidFormatList; $aData['aInvalidEmailList'] = $aInvalidEmailList; $aData['aModelErrorList'] = $aModelErrorList; $aData['iInvalidEmailCount'] = $iInvalidEmailCount; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId; $aData['aInvalideAttrFieldName'] = $aInvalideAttrFieldName; $aData['aMissingAttrFieldName'] = $aMissingAttrFieldName; $this->_renderWrappedTemplate('token', array('csvimportresult'), $aData); Yii::app()->end(); } } // If there are error with file : show the form $aData['aEncodings'] = $aEncodings; asort($aData['aEncodings']); $aData['iSurveyId'] = $iSurveyId; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['surveyid'] = $iSurveyId; $aTokenTableFields = getTokenFieldsAndNames($iSurveyId); unset($aTokenTableFields['sent']); unset($aTokenTableFields['remindersent']); unset($aTokenTableFields['remindercount']); unset($aTokenTableFields['usesleft']); foreach ($aTokenTableFields as $sKey => $sValue) { if ($sValue['description'] != $sKey) { $sValue['description'] .= ' - ' . $sKey; } $aNewTokenTableFields[$sKey] = $sValue['description']; } $aData['aTokenTableFields'] = $aNewTokenTableFields; // Get default character set from global settings $thischaracterset = getGlobalSetting('characterset'); // If no encoding was set yet, use the old "auto" default if ($thischaracterset == "") { $thischaracterset = "auto"; } $aData['thischaracterset'] = $thischaracterset; $this->_renderWrappedTemplate('token', array('csvupload'), $aData); }
/** * import from csv */ function import($iSurveyId) { $iSurveyId = (int) $iSurveyId; if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'import')) { Yii::app()->session['flashmessage'] = gT("You do not have sufficient rights to access this page."); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); } // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) { self::_newtokentable($iSurveyId); } App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . 'tokensimport.js'); $aEncodings = aEncodingsArray(); if (Yii::app()->request->isPostRequest) { $sUploadCharset = Yii::app()->request->getPost('csvcharset'); if (!array_key_exists($sUploadCharset, $aEncodings)) { $sUploadCharset = 'auto'; } $bFilterDuplicateToken = Yii::app()->request->getPost('filterduplicatetoken'); $bFilterBlankEmail = Yii::app()->request->getPost('filterblankemail'); $bAllowInvalidEmail = Yii::app()->request->getPost('allowinvalidemail'); $aAttrFieldNames = getAttributeFieldNames($iSurveyId); $aDuplicateList = array(); $aInvalidEmailList = array(); $aInvalidFormatList = array(); $aModelErrorList = array(); $aFirstLine = array(); $oFile = CUploadedFile::getInstanceByName("the_file"); $sPath = Yii::app()->getConfig('tempdir'); $sFileName = $sPath . '/' . randomChars(20); //$sFileTmpName=$oFile->getTempName(); /* More way to validate CSV ? $aCsvMimetypes = array( 'text/csv', 'text/plain', 'application/csv', 'text/comma-separated-values', 'application/excel', 'application/vnd.ms-excel', 'application/vnd.msexcel', 'text/anytext', 'application/octet-stream', 'application/txt', ); */ if (strtolower($oFile->getExtensionName()) != 'csv') { Yii::app()->setFlashMessage(gT("Only CSV files are allowed."), 'error'); } elseif (!@$oFile->saveAs($sFileName)) { Yii::app()->setFlashMessage(sprintf(gT("Upload file not found. Check your permissions and path (%s) for the upload directory"), $sPath), 'error'); } else { $iRecordImported = 0; $iRecordCount = 0; $iRecordOk = 0; $iInvalidEmailCount = 0; // Count invalid email imported // This allows to read file with MAC line endings too @ini_set('auto_detect_line_endings', true); // open it and trim the ednings $aTokenListArray = file($sFileName); $sBaseLanguage = Survey::model()->findByPk($iSurveyId)->language; if (!Yii::app()->request->getPost('filterduplicatefields') || Yii::app()->request->getPost('filterduplicatefields') && count(Yii::app()->request->getPost('filterduplicatefields')) == 0) { $aFilterDuplicateFields = array('firstname', 'lastname', 'email'); } else { $aFilterDuplicateFields = Yii::app()->request->getPost('filterduplicatefields'); } $sSeparator = Yii::app()->request->getPost('separator'); foreach ($aTokenListArray as $buffer) { $buffer = @mb_convert_encoding($buffer, "UTF-8", $sUploadCharset); if ($iRecordCount == 0) { // Parse first line (header) from CSV $buffer = removeBOM($buffer); // We alow all field except tid because this one is really not needed. $aAllowedFieldNames = Token::model($iSurveyId)->tableSchema->getColumnNames(); if (($kTid = array_search('tid', $aAllowedFieldNames)) !== false) { unset($aAllowedFieldNames[$kTid]); } // Some header don't have same column name $aReplacedFields = array('invited' => 'sent', 'reminded' => 'remindersent'); switch ($sSeparator) { case 'comma': $sSeparator = ','; break; case 'semicolon': $sSeparator = ';'; break; default: $comma = substr_count($buffer, ','); $semicolon = substr_count($buffer, ';'); if ($semicolon > $comma) { $sSeparator = ';'; } else { $sSeparator = ','; } } $aFirstLine = str_getcsv($buffer, $sSeparator, '"'); $aFirstLine = array_map('trim', $aFirstLine); $aIgnoredColumns = array(); // Now check the first line for invalid fields foreach ($aFirstLine as $index => $sFieldname) { $aFirstLine[$index] = preg_replace("/(.*) <[^,]*>\$/", "\$1", $sFieldname); $sFieldname = $aFirstLine[$index]; if (!in_array($sFieldname, $aAllowedFieldNames)) { $aIgnoredColumns[] = $sFieldname; } if (array_key_exists($sFieldname, $aReplacedFields)) { $aFirstLine[$index] = $aReplacedFields[$sFieldname]; } } } else { $line = str_getcsv($buffer, $sSeparator, '"'); if (count($aFirstLine) != count($line)) { $aInvalidFormatList[] = sprintf(gt("Line %s"), $iRecordCount); $iRecordCount++; continue; } $aWriteArray = array_combine($aFirstLine, $line); //kick out ignored columns foreach ($aIgnoredColumns as $column) { unset($aWriteArray[$column]); } $bDuplicateFound = false; $bInvalidEmail = false; $aWriteArray['email'] = isset($aWriteArray['email']) ? trim($aWriteArray['email']) : ""; $aWriteArray['firstname'] = isset($aWriteArray['firstname']) ? $aWriteArray['firstname'] : ""; $aWriteArray['lastname'] = isset($aWriteArray['lastname']) ? $aWriteArray['lastname'] : ""; $aWriteArray['language'] = isset($aWriteArray['language']) ? $aWriteArray['language'] : $sBaseLanguage; if ($bFilterDuplicateToken) { $aParams = array(); $oCriteria = new CDbCriteria(); $oCriteria->condition = ""; foreach ($aFilterDuplicateFields as $field) { if (isset($aWriteArray[$field])) { $oCriteria->addCondition("{$field} = :{$field}"); $aParams[":{$field}"] = $aWriteArray[$field]; } } if (!empty($aParams)) { $oCriteria->params = $aParams; } $dupresult = TokenDynamic::model($iSurveyId)->count($oCriteria); if ($dupresult > 0) { $bDuplicateFound = true; $aDuplicateList[] = sprintf(gt("Line %s : %s %s (%s)"), $iRecordCount, $aWriteArray['firstname'], $aWriteArray['lastname'], $aWriteArray['email']); } } //treat blank emails if (!$bDuplicateFound && $bFilterBlankEmail && $aWriteArray['email'] == '') { $bInvalidEmail = true; $aInvalidEmailList[] = sprintf(gt("Line %s : %s %s"), $iRecordCount, CHtml::encode($aWriteArray['firstname']), CHtml::encode($aWriteArray['lastname'])); } if (!$bDuplicateFound && $aWriteArray['email'] != '') { $aEmailAddresses = explode(';', $aWriteArray['email']); foreach ($aEmailAddresses as $sEmailaddress) { if (!validateEmailAddress($sEmailaddress)) { if ($bAllowInvalidEmail) { $iInvalidEmailCount++; if (empty($aWriteArray['emailstatus']) || strtoupper($aWriteArray['emailstatus'] == "OK")) { $aWriteArray['emailstatus'] = "invalid"; } } else { $bInvalidEmail = true; $aInvalidEmailList[] = sprintf(gt("Line %s : %s %s (%s)"), $iRecordCount, CHtml::encode($aWriteArray['firstname']), CHtml::encode($aWriteArray['lastname']), CHtml::encode($aWriteArray['email'])); } } } } if (!$bDuplicateFound && !$bInvalidEmail && isset($aWriteArray['token'])) { $aWriteArray['token'] = sanitize_token($aWriteArray['token']); // We allways search for duplicate token (it's in model. Allow to reset or update token ? if (Token::model($iSurveyId)->count("token=:token", array(":token" => $aWriteArray['token']))) { $bDuplicateFound = true; $aDuplicateList[] = sprintf(gt("Line %s : %s %s (%s) - token : %s"), $iRecordCount, CHtml::encode($aWriteArray['firstname']), CHtml::encode($aWriteArray['lastname']), CHtml::encode($aWriteArray['email']), CHtml::encode($aWriteArray['token'])); } } if (!$bDuplicateFound && !$bInvalidEmail) { // unset all empty value foreach ($aWriteArray as $key => $value) { if ($aWriteArray[$key] == "") { unset($aWriteArray[$key]); } if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { // Fix CSV quote $value = substr($value, 1, -1); } } // Some default value : to be moved to Token model rules in future release ? // But think we have to accept invalid email etc ... then use specific scenario $oToken = Token::create($iSurveyId); if ($bAllowInvalidEmail) { $oToken->scenario = 'allowinvalidemail'; } foreach ($aWriteArray as $key => $value) { $oToken->{$key} = $value; } if (!$oToken->save()) { tracevar($oToken->getErrors()); $aModelErrorList[] = sprintf(gt("Line %s : %s"), $iRecordCount, Chtml::errorSummary($oToken)); } else { $iRecordImported++; } } $iRecordOk++; } $iRecordCount++; } $iRecordCount = $iRecordCount - 1; unlink($sFileName); $aData['aTokenListArray'] = $aTokenListArray; // Big array in memory, just for success ? $aData['iRecordImported'] = $iRecordImported; $aData['iRecordOk'] = $iRecordOk; $aData['iRecordCount'] = $iRecordCount; $aData['aFirstLine'] = $aFirstLine; // Seem not needed $aData['aDuplicateList'] = $aDuplicateList; $aData['aInvalidFormatList'] = $aInvalidFormatList; $aData['aInvalidEmailList'] = $aInvalidEmailList; $aData['aModelErrorList'] = $aModelErrorList; $aData['iInvalidEmailCount'] = $iInvalidEmailCount; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId; $this->_renderWrappedTemplate('token', array('tokenbar', 'csvpost'), $aData); Yii::app()->end(); } } // If there are error with file : show the form $aData['aEncodings'] = $aEncodings; $aData['iSurveyId'] = $iSurveyId; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['surveyid'] = $iSurveyId; $aTokenTableFields = getTokenFieldsAndNames($iSurveyId); unset($aTokenTableFields['sent']); unset($aTokenTableFields['remindersent']); unset($aTokenTableFields['remindercount']); unset($aTokenTableFields['usesleft']); foreach ($aTokenTableFields as $sKey => $sValue) { if ($sValue['description'] != $sKey) { $sValue['description'] .= ' - ' . $sKey; } $aNewTokenTableFields[$sKey] = $sValue['description']; } $aData['aTokenTableFields'] = $aNewTokenTableFields; $this->_renderWrappedTemplate('token', array('tokenbar', 'csvupload'), $aData); }
$aTokenColumns[$aTokenColumn]['search'] = false; $aTokenColumns[$aTokenColumn]['add'] = false; } else { $aTokenColumns[$aTokenColumn]['editable'] = true; $aTokenColumns[$aTokenColumn]['search'] = true; $aTokenColumns[$aTokenColumn]['add'] = true; } if (in_array($aTokenColumn, $aNotQuickFilter)) { $aTokenColumns[$aTokenColumn]['quickfilter'] = false; } else { $aTokenColumns[$aTokenColumn]['quickfilter'] = true; } } // Build the columnNames for the extra attributes // and, build the columnModel $attributes = getTokenFieldsAndNames($surveyid, true); $uidNames = $columnNames = $aColumnHeader = array(); if (count($attributes) > 0) { foreach ($attributes as $sFieldname => $aData) { $customEdit = ''; if ($aData['mandatory'] == 'Y') { $customEdit = ', editrules:{custom:true, custom_func:checkMandatoryAttr}'; } $uidNames[] = '{ "name":"' . $sFieldname . '", "index":"' . $sFieldname . '", "sorttype":"string", "sortable": true, "align":"left", "editable":true, "width":75' . $customEdit . '}'; $aColumnHeaders[] = $aData['description']; } $columnNames = '"' . implode('","', $aColumnHeaders) . '"'; } $sJsonColumnInformation = json_encode($aTokenColumns); // Build the javasript variables to pass to the jqGrid ?>
/** * This function loads the relevant data about tokens for a survey. * If specific token is not given it loads empty values, this is used for * question previewing and the like. * * @param int $iSurveyId * @param string $sToken * @param boolean $bAnonymize * @return void */ public function loadTokenInformation($iSurveyId, $sToken = null, $bAnonymize = false) { if (!Survey::model()->hasTokens($iSurveyId)) { return; } if ($sToken == null && isset($_SESSION[$this->sessid]['token'])) { $sToken = $_SESSION[$this->sessid]['token']; } $token = Token::model($iSurveyId)->findByAttributes(array('token' => $sToken)); $this->knownVars['TOKEN:TOKEN'] = array('code' => $sToken, 'jsName_on' => '', 'jsName' => '', 'readWrite' => 'N'); if (isset($token)) { foreach ($token->attributes as $key => $val) { if ($bAnonymize) { $val = ""; } $key = "TOKEN:" . strtoupper($key); $this->knownVars[$key] = array('code' => $val, 'jsName_on' => '', 'jsName' => '', 'readWrite' => 'N'); } } else { // Read list of available tokens from the tokens table so that preview and error checking works correctly $blankVal = array('code' => '', 'jsName_on' => '', 'jsName' => '', 'readWrite' => 'N'); foreach (getTokenFieldsAndNames($surveyId) as $field => $details) { if (preg_match('/^(firstname|lastname|email|usesleft|token|attribute_\\d+)$/', $field)) { $this->knownVars['TOKEN:' . strtoupper($field)] = $blankVal; } } } }
/** * RPC Routine to send reminder for participants in a survey * Returns array of results of sending * * @access public * @param string $sSessionKey Auth credentials * @param int $iSurveyID ID of the survey that participants belong * @param int $iMinDaysBetween Optional parameter days from last reminder * @param int $iMaxReminders Optional parameter Maximum reminders count * @return array Result of the action */ public function remind_participants($sSessionKey, $iSurveyID, $iMinDaysBetween = null, $iMaxReminders = null) { Yii::app()->loadHelper('admin/token'); if (!$this->_checkSessionKey($sSessionKey)) { return array('status' => 'Invalid session key'); } $oSurvey = Survey::model()->findByPk($iSurveyID); if (!isset($oSurvey)) { return array('status' => 'Error: Invalid survey ID'); } if (hasSurveyPermission($iSurveyID, 'tokens', 'update')) { $timeadjust = Yii::app()->getConfig("timeadjust"); if (!tableExists("{{tokens_{$iSurveyID}}}")) { return array('status' => 'Error: No token table'); } if (getEmailFormat($iSurveyID) == 'html') { $bHtml = true; } else { $bHtml = false; } $SQLemailstatuscondition = "emailstatus = 'OK'"; $SQLremindercountcondition = ''; $SQLreminderdelaycondition = ''; $attributes = getTokenFieldsAndNames($iSurveyID); $iMaxEmails = (int) Yii::app()->getConfig("maxemails"); if (!is_null($iMinDaysBetween)) { $compareddate = dateShift(date("Y-m-d H:i:s", time() - 86400 * $iMinDaysBetween), "Y-m-d H:i", $timeadjust); $SQLreminderdelaycondition = " ((remindersent = 'N' AND sent < '" . $compareddate . "') OR (remindersent < '" . $compareddate . "'))"; } if (!is_null($iMaxReminders)) { $SQLremindercountcondition = "remindercount < " . $iMaxReminders; } $oTokens = Tokens_dynamic::model($iSurveyID); $aResultTokens = $oTokens->findUninvited(false, $iMaxEmails, false, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition); $aAllTokens = $oTokens->findUninvited(false, 0, false, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition); if (empty($aResultTokens)) { return array('status' => 'Error: No candidate tokens'); } $aResult = emailTokens($iSurveyID, $aResultTokens, 'remind'); $iLeft = count($aAllTokens) - count($aResultTokens); $aResult['status'] = $iLeft . " left to send"; return $aResult; } else { return array('status' => 'No permission'); } }
/** * Create the arrays needed by ExpressionManager to process LimeSurvey strings. * The long part of this function should only be called once per page display (e.g. only if $fieldMap changes) * * @param <integer> $surveyid * @param <Boolean> $forceRefresh * @param <Boolean> $anonymized * @param <Boolean> $allOnOnePage - if true (like for survey_format), uses certain optimizations * @return boolean - true if $fieldmap had been re-created, so ExpressionManager variables need to be re-set */ private function setVariableAndTokenMappingsForExpressionManager($surveyid, $forceRefresh = false, $anonymized = false, $allOnOnePage = false) { if (isset($_SESSION['LEMforceRefresh'])) { unset($_SESSION['LEMforceRefresh']); $forceRefresh = true; } else { if (!$forceRefresh && isset($this->knownVars) && !$this->sPreviewMode) { return false; // means that those variables have been cached and no changes needed } } $now = microtime(true); $this->em->SetSurveyMode($this->surveyMode); // TODO - do I need to force refresh, or trust that createFieldMap will cache langauges properly? $fieldmap = createFieldMap($surveyid, $style = 'full', $forceRefresh, false, $_SESSION['LEMlang']); $this->sid = $surveyid; $this->runtimeTimings[] = array(__METHOD__ . '.createFieldMap', microtime(true) - $now); // LimeExpressionManager::ShowStackTrace(); $now = microtime(true); if (!isset($fieldmap)) { return false; // implies an error occurred } $this->knownVars = array(); // mapping of VarName to Value $this->qcode2sgqa = array(); $this->tempVars = array(); $this->qid2code = array(); // List of codes for each question - needed to know which to NULL if a question is irrelevant $this->jsVar2qid = array(); $this->qcode2sgq = array(); $this->alias2varName = array(); $this->varNameAttr = array(); $this->questionId2questionSeq = array(); $this->questionId2groupSeq = array(); $this->questionSeq2relevance = array(); $this->groupId2groupSeq = array(); $this->qid2validationEqn = array(); $this->groupSeqInfo = array(); $this->gseq2relevanceStatus = array(); // Since building array of allowable answers, need to know preset values for certain question types $presets = array(); $presets['G'] = array('M' => $this->gT("Male"), 'F' => $this->gT("Female")); $presets['Y'] = array('Y' => $this->gT("Yes"), 'N' => $this->gT("No")); $presets['C'] = array('Y' => $this->gT("Yes"), 'N' => $this->gT("No"), 'U' => $this->gT("Uncertain")); $presets['E'] = array('I' => $this->gT("Increase"), 'S' => $this->gT("Same"), 'D' => $this->gT("Decrease")); $this->gseq2info = $this->getGroupInfoForEM($surveyid, $_SESSION['LEMlang']); foreach ($this->gseq2info as $aGroupInfo) { $this->groupId2groupSeq[$aGroupInfo['gid']] = $aGroupInfo['group_order']; } $qattr = $this->getQuestionAttributesForEM($surveyid, 0, $_SESSION['LEMlang']); $this->qattr = $qattr; $this->runtimeTimings[] = array(__METHOD__ . ' - question_attributes_model->getQuestionAttributesForEM', microtime(true) - $now); $now = microtime(true); $this->qans = $this->getAnswerSetsForEM($surveyid, NULL, $_SESSION['LEMlang']); $this->runtimeTimings[] = array(__METHOD__ . ' - answers_model->getAnswerSetsForEM', microtime(true) - $now); $now = microtime(true); $q2subqInfo = array(); $this->multiflexiAnswers = array(); foreach ($fieldmap as $fielddata) { if (!isset($fielddata['fieldname']) || !preg_match('#^\\d+X\\d+X\\d+#', $fielddata['fieldname'])) { continue; // not an SGQA value } $sgqa = $fielddata['fieldname']; $type = $fielddata['type']; $mandatory = $fielddata['mandatory']; $fieldNameParts = explode('X', $sgqa); $groupNum = $fieldNameParts[1]; $aid = isset($fielddata['aid']) ? $fielddata['aid'] : ''; $sqid = isset($fielddata['sqid']) ? $fielddata['sqid'] : ''; if ($this->sPreviewMode == 'question') { $fielddata['relevance'] = 1; } if ($this->sPreviewMode == 'group') { $fielddata['grelevance'] = 1; } $questionId = $fieldNameParts[2]; $questionNum = $fielddata['qid']; $relevance = isset($fielddata['relevance']) ? $fielddata['relevance'] : 1; $SQrelevance = isset($fielddata['SQrelevance']) ? $fielddata['SQrelevance'] : 1; $grelevance = isset($fielddata['grelevance']) ? $fielddata['grelevance'] : 1; $hidden = isset($qattr[$questionNum]['hidden']) ? $qattr[$questionNum]['hidden'] == '1' : false; $scale_id = isset($fielddata['scale_id']) ? $fielddata['scale_id'] : '0'; $preg = isset($fielddata['preg']) ? $fielddata['preg'] : NULL; // a perl regular exrpession validation function $defaultValue = isset($fielddata['defaultvalue']) ? $fielddata['defaultvalue'] : NULL; if (trim($preg) == '') { $preg = NULL; } $help = isset($fielddata['help']) ? $fielddata['help'] : ''; $other = isset($fielddata['other']) ? $fielddata['other'] : ''; if (isset($this->questionId2groupSeq[$questionNum])) { $groupSeq = $this->questionId2groupSeq[$questionNum]; } else { $groupSeq = isset($fielddata['groupSeq']) ? $fielddata['groupSeq'] : -1; $this->questionId2groupSeq[$questionNum] = $groupSeq; } if (isset($this->questionId2questionSeq[$questionNum])) { $questionSeq = $this->questionId2questionSeq[$questionNum]; } else { $questionSeq = isset($fielddata['questionSeq']) ? $fielddata['questionSeq'] : -1; $this->questionId2questionSeq[$questionNum] = $questionSeq; } if (!isset($this->groupSeqInfo[$groupSeq])) { $this->groupSeqInfo[$groupSeq] = array('qstart' => $questionSeq, 'qend' => $questionSeq); } else { $this->groupSeqInfo[$groupSeq]['qend'] = $questionSeq; // with each question, update so know ending value } // Create list of codes associated with each question $codeList = isset($this->qid2code[$questionNum]) ? $this->qid2code[$questionNum] : ''; if ($codeList == '') { $codeList = $sgqa; } else { $codeList .= '|' . $sgqa; } $this->qid2code[$questionNum] = $codeList; $readWrite = 'Y'; // Set $ansArray switch ($type) { case '!': //List - dropdown //List - dropdown case 'L': //LIST drop-down/radio-button list //LIST drop-down/radio-button list case 'O': //LIST WITH COMMENT drop-down/radio-button list + textarea //LIST WITH COMMENT drop-down/radio-button list + textarea case '1': //Array (Flexible Labels) dual scale // need scale //Array (Flexible Labels) dual scale // need scale case 'H': //ARRAY (Flexible) - Column Format //ARRAY (Flexible) - Column Format case 'F': //ARRAY (Flexible) - Row Format //ARRAY (Flexible) - Row Format case 'R': //RANKING STYLE $ansArray = isset($this->qans[$questionNum]) ? $this->qans[$questionNum] : NULL; if ($other == 'Y' && ($type == 'L' || $type == '!')) { if (preg_match('/other$/', $sgqa)) { $ansArray = NULL; // since the other variable doesn't need it } else { $_qattr = isset($qattr[$questionNum]) ? $qattr[$questionNum] : array(); if (isset($_qattr['other_replace_text']) && trim($_qattr['other_replace_text']) != '') { $othertext = trim($_qattr['other_replace_text']); } else { $othertext = $this->gT('Other:'); } $ansArray['0~-oth-'] = '0|' . $othertext; } } break; case 'A': //ARRAY (5 POINT CHOICE) radio-buttons //ARRAY (5 POINT CHOICE) radio-buttons case 'B': //ARRAY (10 POINT CHOICE) radio-buttons //ARRAY (10 POINT CHOICE) radio-buttons case ':': //ARRAY (Multi Flexi) 1 to 10 //ARRAY (Multi Flexi) 1 to 10 case '5': //5 POINT CHOICE radio-buttons $ansArray = NULL; break; case 'N': //NUMERICAL QUESTION TYPE //NUMERICAL QUESTION TYPE case 'K': //MULTIPLE NUMERICAL QUESTION //MULTIPLE NUMERICAL QUESTION case 'Q': //MULTIPLE SHORT TEXT //MULTIPLE SHORT TEXT case ';': //ARRAY (Multi Flexi) Text //ARRAY (Multi Flexi) Text case 'S': //SHORT FREE TEXT //SHORT FREE TEXT case 'T': //LONG FREE TEXT //LONG FREE TEXT case 'U': //HUGE FREE TEXT //HUGE FREE TEXT case 'M': //Multiple choice checkbox //Multiple choice checkbox case 'P': //Multiple choice with comments checkbox + text //Multiple choice with comments checkbox + text case 'D': //DATE //DATE case '*': //Equation //Equation case 'I': //Language Question //Language Question case '|': //File Upload //File Upload case 'X': //BOILERPLATE QUESTION $ansArray = NULL; break; case 'G': //GENDER drop-down list //GENDER drop-down list case 'Y': //YES/NO radio-buttons //YES/NO radio-buttons case 'C': //ARRAY (YES/UNCERTAIN/NO) radio-buttons //ARRAY (YES/UNCERTAIN/NO) radio-buttons case 'E': //ARRAY (Increase/Same/Decrease) radio-buttons $ansArray = $presets[$type]; break; } // set $subqtext text - for display of primary sub-question $subqtext = ''; switch ($type) { default: $subqtext = isset($fielddata['subquestion']) ? $fielddata['subquestion'] : ''; break; case ':': //ARRAY (Multi Flexi) 1 to 10 //ARRAY (Multi Flexi) 1 to 10 case ';': //ARRAY (Multi Flexi) Text $subqtext = isset($fielddata['subquestion1']) ? $fielddata['subquestion1'] : ''; $ansList = array(); if (isset($fielddata['answerList'])) { foreach ($fielddata['answerList'] as $ans) { $ansList['1~' . $ans['code']] = $ans['code'] . '|' . $ans['answer']; } $this->multiflexiAnswers[$questionNum] = $ansList; } break; } // Set $varName (question code / questions.title), $rowdivid, $csuffix, $sqsuffix, and $question $rowdivid = NULL; // so that blank for types not needing it. $sqsuffix = ''; switch ($type) { case '!': //List - dropdown //List - dropdown case '5': //5 POINT CHOICE radio-buttons //5 POINT CHOICE radio-buttons case 'D': //DATE //DATE case 'G': //GENDER drop-down list //GENDER drop-down list case 'I': //Language Question //Language Question case 'L': //LIST drop-down/radio-button list //LIST drop-down/radio-button list case 'N': //NUMERICAL QUESTION TYPE //NUMERICAL QUESTION TYPE case 'O': //LIST WITH COMMENT drop-down/radio-button list + textarea //LIST WITH COMMENT drop-down/radio-button list + textarea case 'S': //SHORT FREE TEXT //SHORT FREE TEXT case 'T': //LONG FREE TEXT //LONG FREE TEXT case 'U': //HUGE FREE TEXT //HUGE FREE TEXT case 'X': //BOILERPLATE QUESTION //BOILERPLATE QUESTION case 'Y': //YES/NO radio-buttons //YES/NO radio-buttons case '|': //File Upload //File Upload case '*': //Equation $csuffix = ''; $sqsuffix = ''; $varName = $fielddata['title']; if ($fielddata['aid'] != '') { $varName .= '_' . $fielddata['aid']; } $question = $fielddata['question']; break; case '1': //Array (Flexible Labels) dual scale $csuffix = $fielddata['aid'] . '#' . $fielddata['scale_id']; $sqsuffix = '_' . $fielddata['aid']; $varName = $fielddata['title'] . '_' . $fielddata['aid'] . '_' . $fielddata['scale_id']; $question = $fielddata['subquestion'] . '[' . $fielddata['scale'] . ']'; // $question = $fielddata['question'] . ': ' . $fielddata['subquestion'] . '[' . $fielddata['scale'] . ']'; $rowdivid = substr($sgqa, 0, -2); break; case 'A': //ARRAY (5 POINT CHOICE) radio-buttons //ARRAY (5 POINT CHOICE) radio-buttons case 'B': //ARRAY (10 POINT CHOICE) radio-buttons //ARRAY (10 POINT CHOICE) radio-buttons case 'C': //ARRAY (YES/UNCERTAIN/NO) radio-buttons //ARRAY (YES/UNCERTAIN/NO) radio-buttons case 'E': //ARRAY (Increase/Same/Decrease) radio-buttons //ARRAY (Increase/Same/Decrease) radio-buttons case 'F': //ARRAY (Flexible) - Row Format //ARRAY (Flexible) - Row Format case 'H': //ARRAY (Flexible) - Column Format // note does not have javatbd equivalent - so array filters don't work on it //ARRAY (Flexible) - Column Format // note does not have javatbd equivalent - so array filters don't work on it case 'K': //MULTIPLE NUMERICAL QUESTION // note does not have javatbd equivalent - so array filters don't work on it, but need rowdivid to process validations //MULTIPLE NUMERICAL QUESTION // note does not have javatbd equivalent - so array filters don't work on it, but need rowdivid to process validations case 'M': //Multiple choice checkbox //Multiple choice checkbox case 'P': //Multiple choice with comments checkbox + text //Multiple choice with comments checkbox + text case 'Q': //MULTIPLE SHORT TEXT // note does not have javatbd equivalent - so array filters don't work on it //MULTIPLE SHORT TEXT // note does not have javatbd equivalent - so array filters don't work on it case 'R': //RANKING STYLE // note does not have javatbd equivalent - so array filters don't work on it $csuffix = $fielddata['aid']; $varName = $fielddata['title'] . '_' . $fielddata['aid']; $question = $fielddata['subquestion']; // $question = $fielddata['question'] . ': ' . $fielddata['subquestion']; if ($type != 'H') { if ($type == 'P' && preg_match("/comment\$/", $sgqa)) { // $rowdivid = substr($sgqa,0,-7); } else { $sqsuffix = '_' . $fielddata['aid']; $rowdivid = $sgqa; } } break; case ':': //ARRAY (Multi Flexi) 1 to 10 //ARRAY (Multi Flexi) 1 to 10 case ';': //ARRAY (Multi Flexi) Text $csuffix = $fielddata['aid']; $sqsuffix = '_' . substr($fielddata['aid'], 0, strpos($fielddata['aid'], '_')); $varName = $fielddata['title'] . '_' . $fielddata['aid']; $question = $fielddata['subquestion1'] . '[' . $fielddata['subquestion2'] . ']'; // $question = $fielddata['question'] . ': ' . $fielddata['subquestion1'] . '[' . $fielddata['subquestion2'] . ']'; $rowdivid = substr($sgqa, 0, strpos($sgqa, '_')); break; } // $onlynum $onlynum = false; // the default switch ($type) { case 'K': //MULTIPLE NUMERICAL QUESTION //MULTIPLE NUMERICAL QUESTION case 'N': //NUMERICAL QUESTION TYPE //NUMERICAL QUESTION TYPE case ':': //ARRAY (Multi Flexi) 1 to 10 $onlynum = true; break; case '*': // Equation // Equation case ';': //ARRAY (Multi Flexi) Text //ARRAY (Multi Flexi) Text case 'Q': //MULTIPLE SHORT TEXT //MULTIPLE SHORT TEXT case 'S': //SHORT FREE TEXT if (isset($qattr[$questionNum]['numbers_only']) && $qattr[$questionNum]['numbers_only'] == '1') { $onlynum = true; } break; case 'L': //LIST drop-down/radio-button list //LIST drop-down/radio-button list case 'M': //Multiple choice checkbox //Multiple choice checkbox case 'P': //Multiple choice with comments checkbox + text if (isset($qattr[$questionNum]['other_numbers_only']) && $qattr[$questionNum]['other_numbers_only'] == '1' && preg_match('/other$/', $sgqa)) { $onlynum = true; } break; default: break; } // Set $jsVarName_on (for on-page variables - e.g. answerSGQA) and $jsVarName (for off-page variables; the primary name - e.g. javaSGQA) switch ($type) { case 'R': //RANKING STYLE $jsVarName_on = 'answer' . $sgqa; $jsVarName = 'java' . $sgqa; break; case 'D': //DATE //DATE case 'N': //NUMERICAL QUESTION TYPE //NUMERICAL QUESTION TYPE case 'S': //SHORT FREE TEXT //SHORT FREE TEXT case 'T': //LONG FREE TEXT //LONG FREE TEXT case 'U': //HUGE FREE TEXT //HUGE FREE TEXT case 'Q': //MULTIPLE SHORT TEXT //MULTIPLE SHORT TEXT case 'K': //MULTIPLE NUMERICAL QUESTION //MULTIPLE NUMERICAL QUESTION case 'X': //BOILERPLATE QUESTION $jsVarName_on = 'answer' . $sgqa; $jsVarName = 'java' . $sgqa; break; case '!': //List - dropdown if (preg_match("/other\$/", $sgqa)) { $jsVarName = 'java' . $sgqa; $jsVarName_on = 'othertext' . substr($sgqa, 0, -5); } else { $jsVarName = 'java' . $sgqa; $jsVarName_on = $jsVarName; } break; case 'L': //LIST drop-down/radio-button list if (preg_match("/other\$/", $sgqa)) { $jsVarName = 'java' . $sgqa; $jsVarName_on = 'answer' . $sgqa . "text"; } else { $jsVarName = 'java' . $sgqa; $jsVarName_on = $jsVarName; } break; case '5': //5 POINT CHOICE radio-buttons //5 POINT CHOICE radio-buttons case 'G': //GENDER drop-down list //GENDER drop-down list case 'I': //Language Question //Language Question case 'Y': //YES/NO radio-buttons //YES/NO radio-buttons case '*': //Equation //Equation case 'A': //ARRAY (5 POINT CHOICE) radio-buttons //ARRAY (5 POINT CHOICE) radio-buttons case 'B': //ARRAY (10 POINT CHOICE) radio-buttons //ARRAY (10 POINT CHOICE) radio-buttons case 'C': //ARRAY (YES/UNCERTAIN/NO) radio-buttons //ARRAY (YES/UNCERTAIN/NO) radio-buttons case 'E': //ARRAY (Increase/Same/Decrease) radio-buttons //ARRAY (Increase/Same/Decrease) radio-buttons case 'F': //ARRAY (Flexible) - Row Format //ARRAY (Flexible) - Row Format case 'H': //ARRAY (Flexible) - Column Format //ARRAY (Flexible) - Column Format case 'M': //Multiple choice checkbox //Multiple choice checkbox case 'O': //LIST WITH COMMENT drop-down/radio-button list + textarea if ($type == 'O' && preg_match('/_comment$/', $varName)) { $jsVarName_on = 'answer' . $sgqa; } else { $jsVarName_on = 'java' . $sgqa; } $jsVarName = 'java' . $sgqa; break; case '1': //Array (Flexible Labels) dual scale $jsVarName = 'java' . str_replace('#', '_', $sgqa); $jsVarName_on = $jsVarName; break; case ':': //ARRAY (Multi Flexi) 1 to 10 //ARRAY (Multi Flexi) 1 to 10 case ';': //ARRAY (Multi Flexi) Text $jsVarName = 'java' . $sgqa; $jsVarName_on = 'answer' . $sgqa; break; case '|': //File Upload $jsVarName = $sgqa; $jsVarName_on = $jsVarName; break; case 'P': //Multiple choice with comments checkbox + text if (preg_match("/(other|comment)\$/", $sgqa)) { $jsVarName_on = 'answer' . $sgqa; // is this true for survey.php and not for group.php? $jsVarName = 'java' . $sgqa; } else { $jsVarName = 'java' . $sgqa; $jsVarName_on = $jsVarName; } break; } // Hidden question are never on same page (except for equation) if ($hidden && $type != "*") { $jsVarName_on = ''; } if (!is_null($rowdivid) || $type == 'L' || $type == 'N' || $type == '!' || $type == 'O' || !is_null($preg) || $type == 'S' || $type == 'D' || $type == 'T' || $type == 'U' || $type == '|') { if (!isset($q2subqInfo[$questionNum])) { $q2subqInfo[$questionNum] = array('qid' => $questionNum, 'qseq' => $questionSeq, 'gseq' => $groupSeq, 'sgqa' => $surveyid . 'X' . $groupNum . 'X' . $questionNum, 'mandatory' => $mandatory, 'varName' => $varName, 'type' => $type, 'fieldname' => $sgqa, 'preg' => $preg, 'rootVarName' => $fielddata['title']); } if (!isset($q2subqInfo[$questionNum]['subqs'])) { $q2subqInfo[$questionNum]['subqs'] = array(); } switch ($type) { case 'L': // What using sq: it's only on question + one other if other is set. This don't set the other subq here. // What using sq: it's only on question + one other if other is set. This don't set the other subq here. case '!': if (!is_null($ansArray)) { foreach (array_keys($ansArray) as $key) { $parts = explode('~', $key); if ($parts[1] == '-oth-') { $parts[1] = 'other'; } $q2subqInfo[$questionNum]['subqs'][] = array('rowdivid' => $surveyid . 'X' . $groupNum . 'X' . $questionNum . $parts[1], 'varName' => $varName, 'sqsuffix' => '_' . $parts[1]); } } break; case 'O': if (strlen($varName) > 8 && substr_compare($varName, '_comment', -8) === 0) { $q2subqInfo[$questionNum]['subqs'][] = array('varName' => $varName, 'rowdivid' => $surveyid . 'X' . $groupNum . 'X' . $questionNum . 'comment', 'jsVarName' => $jsVarName, 'jsVarName_on' => $jsVarName_on, 'sqsuffix' => '_comment'); } else { $q2subqInfo[$questionNum]['subqs'][] = array('varName' => $varName, 'rowdivid' => $surveyid . 'X' . $groupNum . 'X' . $questionNum, 'jsVarName' => $jsVarName, 'jsVarName_on' => $jsVarName_on); } break; case 'N': case 'S': case 'D': case 'T': case 'U': $q2subqInfo[$questionNum]['subqs'][] = array('varName' => $varName, 'rowdivid' => $surveyid . 'X' . $groupNum . 'X' . $questionNum, 'jsVarName' => 'java' . $surveyid . 'X' . $groupNum . 'X' . $questionNum, 'jsVarName_on' => $jsVarName_on); break; default: $q2subqInfo[$questionNum]['subqs'][] = array('rowdivid' => $rowdivid, 'varName' => $varName, 'jsVarName_on' => $jsVarName_on, 'jsVarName' => $jsVarName, 'csuffix' => $csuffix, 'sqsuffix' => $sqsuffix); break; } } $ansList = ''; if (isset($ansArray) && !is_null($ansArray)) { $answers = array(); foreach ($ansArray as $key => $value) { $answers[] = "'" . $key . "':'" . htmlspecialchars(preg_replace('/[[:space:]]/', ' ', $value), ENT_QUOTES) . "'"; } $ansList = ",'answers':{ " . implode(",", $answers) . "}"; } // Set mappings of variable names to needed attributes $varInfo_Code = array('jsName_on' => $jsVarName_on, 'jsName' => $jsVarName, 'readWrite' => $readWrite, 'hidden' => $hidden, 'question' => $question, 'qid' => $questionNum, 'gid' => $groupNum, 'grelevance' => $grelevance, 'relevance' => $relevance, 'SQrelevance' => $SQrelevance, 'qcode' => $varName, 'qseq' => $questionSeq, 'gseq' => $groupSeq, 'type' => $type, 'sgqa' => $sgqa, 'ansList' => $ansList, 'ansArray' => $ansArray, 'scale_id' => $scale_id, 'default' => $defaultValue, 'rootVarName' => $fielddata['title'], 'subqtext' => $subqtext, 'rowdivid' => is_null($rowdivid) ? '' : $rowdivid, 'onlynum' => $onlynum); $this->questionSeq2relevance[$questionSeq] = array('relevance' => $relevance, 'grelevance' => $grelevance, 'qid' => $questionNum, 'qseq' => $questionSeq, 'gseq' => $groupSeq, 'jsResultVar_on' => $jsVarName_on, 'jsResultVar' => $jsVarName, 'type' => $type, 'hidden' => $hidden, 'gid' => $groupNum, 'mandatory' => $mandatory, 'eqn' => '', 'help' => $help, 'qtext' => $fielddata['question'], 'code' => $varName, 'other' => $other, 'default' => $defaultValue, 'rootVarName' => $fielddata['title'], 'rowdivid' => is_null($rowdivid) ? '' : $rowdivid, 'aid' => $aid, 'sqid' => $sqid); $this->knownVars[$sgqa] = $varInfo_Code; $this->qcode2sgqa[$varName] = $sgqa; $this->jsVar2qid[$jsVarName] = $questionNum; $this->qcode2sgq[$fielddata['title']] = $surveyid . 'X' . $groupNum . 'X' . $questionNum; // Create JavaScript arrays $this->alias2varName[$varName] = array('jsName' => $jsVarName, 'jsPart' => "'" . $varName . "':'" . $jsVarName . "'"); $this->alias2varName[$sgqa] = array('jsName' => $jsVarName, 'jsPart' => "'" . $sgqa . "':'" . $jsVarName . "'"); $this->varNameAttr[$jsVarName] = "'" . $jsVarName . "':{ " . "'jsName':'" . $jsVarName . "','jsName_on':'" . $jsVarName_on . "','sgqa':'" . $sgqa . "','qid':" . $questionNum . ",'gid':" . $groupNum . ",'type':'" . $type . "','default':'" . (is_null($defaultValue) ? '' : str_replace("'", "\\'", $defaultValue)) . "','rowdivid':'" . (is_null($rowdivid) ? '' : $rowdivid) . "','onlynum':'" . ($onlynum ? '1' : '') . "','gseq':" . $groupSeq . $ansList; if ($type == 'M' || $type == 'P') { $this->varNameAttr[$jsVarName] .= ",'question':'" . htmlspecialchars(preg_replace('/[[:space:]]/', ' ', $question), ENT_QUOTES) . "'"; } $this->varNameAttr[$jsVarName] .= "}"; } $this->q2subqInfo = $q2subqInfo; // Now set tokens if (Survey::model()->hasTokens($surveyid) && isset($_SESSION[$this->sessid]['token']) && $_SESSION[$this->sessid]['token'] != '') { //Gather survey data for tokenised surveys, for use in presenting questions $this->knownVars['TOKEN:TOKEN'] = array('code' => $_SESSION[$this->sessid]['token'], 'jsName_on' => '', 'jsName' => '', 'readWrite' => 'N'); $token = Token::model($surveyid)->findByToken($_SESSION[$this->sessid]['token']); foreach ($token as $key => $val) { $this->knownVars["TOKEN:" . strtoupper($key)] = array('code' => $anonymized ? '' : $val, 'jsName_on' => '', 'jsName' => '', 'readWrite' => 'N'); } } else { // Read list of available tokens from the tokens table so that preview and error checking works correctly $attrs = array_keys(getTokenFieldsAndNames($surveyid)); $blankVal = array('code' => '', 'type' => '', 'jsName_on' => '', 'jsName' => '', 'readWrite' => 'N'); foreach ($attrs as $key) { if (preg_match('/^(firstname|lastname|email|usesleft|token|attribute_\\d+)$/', $key)) { $this->knownVars['TOKEN:' . strtoupper($key)] = $blankVal; } } } // set default value for reserved 'this' variable $this->knownVars['this'] = array('jsName_on' => '', 'jsName' => '', 'readWrite' => '', 'hidden' => '', 'question' => 'this', 'qid' => '', 'gid' => '', 'grelevance' => '', 'relevance' => '', 'SQrelevance' => '', 'qcode' => 'this', 'qseq' => '', 'gseq' => '', 'type' => '', 'sgqa' => '', 'rowdivid' => '', 'ansList' => '', 'ansArray' => array(), 'scale_id' => '', 'default' => '', 'rootVarName' => 'this', 'subqtext' => '', 'rowdivid' => ''); $this->runtimeTimings[] = array(__METHOD__ . ' - process fieldMap', microtime(true) - $now); usort($this->questionSeq2relevance, 'cmpQuestionSeq'); $this->numQuestions = count($this->questionSeq2relevance); $this->numGroups = count($this->groupSeqInfo); return true; }
function index($subaction, $iSurveyID = null, $gid = null, $qid = null) { $iSurveyID = sanitize_int($iSurveyID); $gid = sanitize_int($gid); $qid = sanitize_int($qid); $clang = $this->getController()->lang; $imageurl = Yii::app()->getConfig("adminimageurl"); Yii::app()->loadHelper("database"); if (!empty($_POST['subaction'])) { $subaction = Yii::app()->request->getPost('subaction'); } //BEGIN Sanitizing POSTed data if (!isset($iSurveyID)) { $iSurveyID = returnGlobal('sid'); } if (!isset($qid)) { $qid = returnGlobal('qid'); } if (!isset($gid)) { $gid = returnGlobal('gid'); } if (!isset($p_scenario)) { $p_scenario = returnGlobal('scenario'); } if (!isset($p_cqid)) { $p_cqid = returnGlobal('cqid'); if ($p_cqid == '') { $p_cqid = 0; } // we are not using another question as source of condition } if (!isset($p_cid)) { $p_cid = returnGlobal('cid'); } if (!isset($p_subaction)) { if (isset($_POST['subaction'])) { $p_subaction = $_POST['subaction']; } else { $p_subaction = $subaction; } } if (!isset($p_cquestions)) { $p_cquestions = returnGlobal('cquestions'); } if (!isset($p_csrctoken)) { $p_csrctoken = returnGlobal('csrctoken'); } if (!isset($p_prevquestionsgqa)) { $p_prevquestionsgqa = returnGlobal('prevQuestionSGQA'); } if (!isset($p_canswers)) { if (isset($_POST['canswers']) && is_array($_POST['canswers'])) { foreach ($_POST['canswers'] as $key => $val) { $p_canswers[$key] = preg_replace("/[^_.a-zA-Z0-9]@/", "", $val); } } } // this array will be used soon, // to explain wich conditions is used to evaluate the question if (Yii::app()->getConfig('stringcomparizonoperators') == 1) { $method = array("<" => $clang->gT("Less than"), "<=" => $clang->gT("Less than or equal to"), "==" => $clang->gT("equals"), "!=" => $clang->gT("Not equal to"), ">=" => $clang->gT("Greater than or equal to"), ">" => $clang->gT("Greater than"), "RX" => $clang->gT("Regular expression"), "a<b" => $clang->gT("Less than (Strings)"), "a<=b" => $clang->gT("Less than or equal to (Strings)"), "a>=b" => $clang->gT("Greater than or equal to (Strings)"), "a>b" => $clang->gT("Greater than (Strings)")); } else { $method = array("<" => $clang->gT("Less than"), "<=" => $clang->gT("Less than or equal to"), "==" => $clang->gT("equals"), "!=" => $clang->gT("Not equal to"), ">=" => $clang->gT("Greater than or equal to"), ">" => $clang->gT("Greater than"), "RX" => $clang->gT("Regular expression")); } if (isset($_POST['method'])) { if (!in_array($_POST['method'], array_keys($method))) { $p_method = "=="; } else { $p_method = trim($_POST['method']); } } if (isset($_POST['newscenarionum'])) { $p_newscenarionum = sanitize_int($_POST['newscenarionum']); } //END Sanitizing POSTed data //include_once("login_check.php"); include_once "database.php"; // Caution (lemeur): database.php uses autoUnescape on all entries in $_POST // Take care to not use autoUnescape on $_POST variables after this $br = CHtml::openTag('br /'); //MAKE SURE THAT THERE IS A SID if (!isset($iSurveyID) || !$iSurveyID) { $conditionsoutput = $clang->gT("You have not selected a survey") . str_repeat($br, 2); $conditionsoutput .= CHtml::submitButton($clang->gT("Main admin screen"), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/") . "', '_top')")) . $br; safeDie($conditionsoutput); return; } if (isset($p_subaction) && $p_subaction == "resetsurveylogic") { $clang = $this->getController()->lang; $resetsurveylogicoutput = $br; $resetsurveylogicoutput .= CHtml::openTag('table', array('class' => 'alertbox')); $resetsurveylogicoutput .= CHtml::openTag('tr') . CHtml::openTag('td', array('colspan' => '2')); $resetsurveylogicoutput .= CHtml::tag('font', array('size' => '1'), CHtml::tag('strong', array(), $clang->gT("Reset Survey Logic"))); $resetsurveylogicoutput .= CHtml::closeTag('td') . CHtml::closeTag('tr'); if (!isset($_GET['ok'])) { $button_yes = CHtml::submitButton($clang->gT("Yes"), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/conditions/sa/index/subaction/resetsurveylogic/surveyid/{$iSurveyID}") . "?ok=Y" . "', '_top')")); $button_cancel = CHtml::submitButton($clang->gT("Cancel"), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/survey/sa/view/surveyid/{$iSurveyID}") . "', '_top')")); $messagebox_content = $clang->gT("You are about to delete all conditions on this survey's questions") . "({$iSurveyID})" . $br . $clang->gT("We recommend that before you proceed, you export the entire survey from the main administration screen.") . $br . $clang->gT("Continue?") . $br . $button_yes . $button_cancel; $this->_renderWrappedTemplate('conditions', array('message' => array('title' => $clang->gT("Warning"), 'message' => $messagebox_content))); exit; } else { LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID); Conditions::model()->deleteRecords("qid in (select qid from {{questions}} where sid={$iSurveyID})"); Yii::app()->session['flashmessage'] = $clang->gT("All conditions in this survey have been deleted."); $this->getController()->redirect($this->getController()->createUrl('admin/survey/sa/view/surveyid/' . $iSurveyID)); } } // MAKE SURE THAT THERE IS A QID if (!isset($qid) || !$qid) { $conditionsoutput = $clang->gT("You have not selected a question") . str_repeat($br, 2); $conditionsoutput .= CHtml::submitButton($clang->gT("Main admin screen"), array('onclick' => "window.open('" . $this->getController()->createUrl("admin/") . "', '_top')")) . $br; safeDie($conditionsoutput); return; } // If we made it this far, then lets develop the menu items // add the conditions container table $extraGetParams = ""; if (isset($qid) && isset($gid)) { $extraGetParams = "/gid/{$gid}/qid/{$qid}"; } $conditionsoutput_action_error = ""; // defined during the actions $markcidarray = array(); if (isset($_GET['markcid'])) { $markcidarray = explode("-", $_GET['markcid']); } //BEGIN PROCESS ACTIONS // ADD NEW ENTRY IF THIS IS AN ADD if (isset($p_subaction) && $p_subaction == "insertcondition") { if (!isset($p_canswers) && !isset($_POST['ConditionConst']) && !isset($_POST['prevQuestionSGQA']) && !isset($_POST['tokenAttr']) && !isset($_POST['ConditionRegexp']) || !isset($p_cquestions) && !isset($p_csrctoken)) { $conditionsoutput_action_error .= CHtml::script("\n<!--\n alert(\"" . $clang->gT("Your condition could not be added! It did not include the question and/or answer upon which the condition was based. Please ensure you have selected a question and an answer.", "js") . "\")\n //-->\n"); } else { if (isset($p_cquestions) && $p_cquestions != '') { $conditionCfieldname = $p_cquestions; } elseif (isset($p_csrctoken) && $p_csrctoken != '') { $conditionCfieldname = $p_csrctoken; } $condition_data = array('qid' => $qid, 'scenario' => $p_scenario, 'cqid' => $p_cqid, 'cfieldname' => $conditionCfieldname, 'method' => $p_method); if (isset($p_canswers)) { foreach ($p_canswers as $ca) { //First lets make sure there isn't already an exact replica of this condition $condition_data['value'] = $ca; $result = Conditions::model()->findAllByAttributes($condition_data); $count_caseinsensitivedupes = count($result); if ($count_caseinsensitivedupes == 0) { $result = Conditions::model()->insertRecords($condition_data); } } } unset($posted_condition_value); // Please note that autoUnescape is already applied in database.php included above // so we only need to db_quote _POST variables if (isset($_POST['ConditionConst']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#CONST") { $posted_condition_value = Yii::app()->request->getPost('ConditionConst'); } elseif (isset($_POST['prevQuestionSGQA']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#PREVQUESTIONS") { $posted_condition_value = Yii::app()->request->getPost('prevQuestionSGQA'); } elseif (isset($_POST['tokenAttr']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#TOKENATTRS") { $posted_condition_value = Yii::app()->request->getPost('tokenAttr'); } elseif (isset($_POST['ConditionRegexp']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#REGEXP") { $posted_condition_value = Yii::app()->request->getPost('ConditionRegexp'); } if (isset($posted_condition_value)) { $condition_data['value'] = $posted_condition_value; $result = Conditions::model()->insertRecords($condition_data); } } LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // UPDATE ENTRY IF THIS IS AN EDIT if (isset($p_subaction) && $p_subaction == "updatecondition") { if (!isset($p_canswers) && !isset($_POST['ConditionConst']) && !isset($_POST['prevQuestionSGQA']) && !isset($_POST['tokenAttr']) && !isset($_POST['ConditionRegexp']) || !isset($p_cquestions) && !isset($p_csrctoken)) { $conditionsoutput_action_error .= CHtml::script("\n<!--\n alert(\"" . $clang->gT("Your condition could not be added! It did not include the question and/or answer upon which the condition was based. Please ensure you have selected a question and an answer.", "js") . "\")\n //-->\n"); } else { if (isset($p_cquestions) && $p_cquestions != '') { $conditionCfieldname = $p_cquestions; } elseif (isset($p_csrctoken) && $p_csrctoken != '') { $conditionCfieldname = $p_csrctoken; } if (isset($p_canswers)) { foreach ($p_canswers as $ca) { // This is an Edit, there will only be ONE VALUE $updated_data = array('qid' => $qid, 'scenario' => $p_scenario, 'cqid' => $p_cqid, 'cfieldname' => $conditionCfieldname, 'method' => $p_method, 'value' => $ca); $result = Conditions::model()->insertRecords($updated_data, TRUE, array('cid' => $p_cid)); } } unset($posted_condition_value); // Please note that autoUnescape is already applied in database.php included above // so we only need to db_quote _POST variables if (isset($_POST['ConditionConst']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#CONST") { $posted_condition_value = Yii::app()->request->getPost('ConditionConst'); } elseif (isset($_POST['prevQuestionSGQA']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#PREVQUESTIONS") { $posted_condition_value = Yii::app()->request->getPost('prevQuestionSGQA'); } elseif (isset($_POST['tokenAttr']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#TOKENATTRS") { $posted_condition_value = Yii::app()->request->getPost('tokenAttr'); } elseif (isset($_POST['ConditionRegexp']) && isset($_POST['editTargetTab']) && $_POST['editTargetTab'] == "#REGEXP") { $posted_condition_value = Yii::app()->request->getPost('ConditionRegexp'); } if (isset($posted_condition_value)) { $updated_data = array('qid' => $qid, 'scenario' => $p_scenario, 'cqid' => $p_cqid, 'cfieldname' => $conditionCfieldname, 'method' => $p_method, 'value' => $posted_condition_value); $result = Conditions::model()->insertRecords($updated_data, TRUE, array('cid' => $p_cid)); } } LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // DELETE ENTRY IF THIS IS DELETE if (isset($p_subaction) && $p_subaction == "delete") { LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL, $qid); // in case deleted the last condition $result = Conditions::model()->deleteRecords(array('cid' => $p_cid)); LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // DELETE ALL CONDITIONS IN THIS SCENARIO if (isset($p_subaction) && $p_subaction == "deletescenario") { LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL, $qid); // in case deleted the last condition $result = Conditions::model()->deleteRecords(array('qid' => $qid, 'scenario' => $p_scenario)); LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // UPDATE SCENARIO if (isset($p_subaction) && $p_subaction == "updatescenario" && isset($p_newscenarionum)) { $result = Conditions::model()->insertRecords(array('scenario' => $p_newscenarionum), TRUE, array('qid' => $qid, 'scenario' => $p_scenario)); LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); } // DELETE ALL CONDITIONS FOR THIS QUESTION if (isset($p_subaction) && $p_subaction == "deleteallconditions") { LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL, $qid); // in case deleted the last condition $result = Conditions::model()->deleteRecords(array('qid' => $qid)); } // RENUMBER SCENARIOS if (isset($p_subaction) && $p_subaction == "renumberscenarios") { $query = "SELECT DISTINCT scenario FROM {{conditions}} WHERE qid=:qid ORDER BY scenario"; $result = Yii::app()->db->createCommand($query)->bindParam(":qid", $qid, PDO::PARAM_INT)->query() or safeDie("Couldn't select scenario<br />{$query}<br />"); $newindex = 1; foreach ($result->readAll() as $srow) { // new var $update_result == old var $result2 $update_result = Conditions::model()->insertRecords(array('scenario' => $newindex), TRUE, array('qid' => $qid, 'scenario' => $srow['scenario'])); $newindex++; } LimeExpressionManager::UpgradeConditionsToRelevance(NULL, $qid); Yii::app()->session['flashmessage'] = $clang->gT("All conditions scenarios were renumbered."); } // COPY CONDITIONS IF THIS IS COPY if (isset($p_subaction) && $p_subaction == "copyconditions") { $qid = returnGlobal('qid'); $copyconditionsfrom = returnGlobal('copyconditionsfrom'); $copyconditionsto = returnGlobal('copyconditionsto'); if (isset($copyconditionsto) && is_array($copyconditionsto) && isset($copyconditionsfrom) && is_array($copyconditionsfrom)) { //Get the conditions we are going to copy foreach ($copyconditionsfrom as &$entry) { $entry = Yii::app()->db->quoteValue($entry); } $query = "SELECT * FROM {{conditions}}\n" . "WHERE cid in ("; $query .= implode(", ", $copyconditionsfrom); $query .= ")"; $result = Yii::app()->db->createCommand($query)->query() or safeDie("Couldn't get conditions for copy<br />{$query}<br />"); foreach ($result->readAll() as $row) { $proformaconditions[] = array("scenario" => $row['scenario'], "cqid" => $row['cqid'], "cfieldname" => $row['cfieldname'], "method" => $row['method'], "value" => $row['value']); } // while foreach ($copyconditionsto as $copyc) { list($newsid, $newgid, $newqid) = explode("X", $copyc); foreach ($proformaconditions as $pfc) { //TIBO //First lets make sure there isn't already an exact replica of this condition $conditions_data = array('qid' => $newqid, 'scenario' => $pfc['scenario'], 'cqid' => $pfc['cqid'], 'cfieldname' => $pfc['cfieldname'], 'method' => $pfc['method'], 'value' => $pfc['value']); $result = Conditions::model()->findAllByAttributes($conditions_data); $count_caseinsensitivedupes = count($result); $countduplicates = 0; if ($count_caseinsensitivedupes != 0) { foreach ($result as $ccrow) { if ($ccrow['value'] == $pfc['value']) { $countduplicates++; } } } if ($countduplicates == 0) { $result = Conditions::model()->insertRecords($conditions_data); $conditionCopied = true; } else { $conditionDuplicated = true; } } } if (isset($conditionCopied) && $conditionCopied === true) { if (isset($conditionDuplicated) && $conditionDuplicated == true) { $CopyConditionsMessage = CHtml::tag('div', array('class' => 'partialheader'), '(' . $clang->gT("Conditions successfully copied (some were skipped because they were duplicates)") . ')'); } else { $CopyConditionsMessage = CHtml::tag('div', array('class' => 'successheader'), '(' . $clang->gT("Conditions successfully copied") . ')'); } } else { $CopyConditionsMessage = CHtml::tag('div', array('class' => 'warningheader'), '(' . $clang->gT("No conditions could be copied (due to duplicates)") . ')'); } } LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID); // do for whole survey, since don't know which questions affected. } //END PROCESS ACTIONS $cquestions = array(); $canswers = array(); //BEGIN: GATHER INFORMATION // 1: Get information for this question if (!isset($qid)) { $qid = returnGlobal('qid'); } if (!isset($iSurveyID)) { $iSurveyID = returnGlobal('sid'); } $thissurvey = getSurveyInfo($iSurveyID); $qresult = Questions::model()->with('groups')->findByAttributes(array('qid' => $qid, 'parent_qid' => 0, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $questiongroupname = $qresult->groups->group_name; $questiontitle = $qresult['title']; $questiontext = $qresult['question']; $questiontype = $qresult['type']; // 2: Get all other questions that occur before this question that are pre-determined answer types // To avoid natural sort order issues, // first get all questions in natural sort order // , and find out which number in that order this question is $qresult = Questions::model()->with(array('groups' => array('condition' => 'groups.language = :lang', 'params' => array(':lang' => Survey::model()->findByPk($iSurveyID)->language))))->findAllByAttributes(array('parent_qid' => 0, 'sid' => $iSurveyID, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $qrows = array(); foreach ($qresult as $k => $v) { $qrows[$k] = array_merge($v->attributes, $v->groups->attributes); } // Perform a case insensitive natural sort on group name then question title (known as "code" in the form) of a multidimensional array usort($qrows, 'groupOrderThenQuestionOrder'); $position = "before"; // Go through each question until we reach the current one foreach ($qrows as $qrow) { if ($qrow["qid"] != $qid && $position == "before") { // remember all previous questions // all question types are supported. $questionlist[] = $qrow["qid"]; } elseif ($qrow["qid"] == $qid) { break; } } // Now, using the same array which is now properly sorted by group then question // Create an array of all the questions that appear AFTER the current one $position = "before"; foreach ($qrows as $qrow) { if ($qrow["qid"] == $qid) { $position = "after"; //break; } elseif ($qrow["qid"] != $qid && $position == "after") { $postquestionlist[] = $qrow['qid']; } } $theserows = array(); $postrows = array(); if (isset($questionlist) && is_array($questionlist)) { foreach ($questionlist as $ql) { $result = Questions::model()->with(array('groups' => array('condition' => 'groups.language = :lang', 'params' => array(':lang' => Survey::model()->findByPk($iSurveyID)->language))))->findAllByAttributes(array('qid' => $ql, 'parent_qid' => 0, 'sid' => $iSurveyID, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $thiscount = count($result); // And store again these questions in this array... foreach ($result as $myrows) { //key => value $theserows[] = array("qid" => $myrows['qid'], "sid" => $myrows['sid'], "gid" => $myrows['gid'], "question" => $myrows['question'], "type" => $myrows['type'], "mandatory" => $myrows['mandatory'], "other" => $myrows['other'], "title" => $myrows['title']); } } } if (isset($postquestionlist) && is_array($postquestionlist)) { foreach ($postquestionlist as $pq) { $result = Questions::model()->with(array('groups' => array('condition' => 'groups.language = :lang', 'params' => array(':lang' => Survey::model()->findByPk($iSurveyID)->language))))->findAllByAttributes(array('qid' => $pq, 'parent_qid' => 0, 'sid' => $iSurveyID, 'language' => Survey::model()->findByPk($iSurveyID)->language)); $postcount = count($result); foreach ($result as $myrows) { $postrows[] = array("qid" => $myrows['qid'], "sid" => $myrows['sid'], "gid" => $myrows['gid'], "question" => $myrows['question'], "type" => $myrows['type'], "mandatory" => $myrows['mandatory'], "other" => $myrows['other'], "title" => $myrows['title']); } // while } $postquestionscount = count($postrows); } $questionscount = count($theserows); if (isset($postquestionscount) && $postquestionscount > 0) { //Build the array used for the questionNav and copyTo select boxes foreach ($postrows as $pr) { $pquestions[] = array("text" => $pr['title'] . ": " . substr(strip_tags($pr['question']), 0, 80), "fieldname" => $pr['sid'] . "X" . $pr['gid'] . "X" . $pr['qid']); } } // Previous question parsing ==> building cquestions[] and canswers[] if ($questionscount > 0) { $X = "X"; foreach ($theserows as $rows) { $shortquestion = $rows['title'] . ": " . strip_tags($rows['question']); if ($rows['type'] == "A" || $rows['type'] == "B" || $rows['type'] == "C" || $rows['type'] == "E" || $rows['type'] == "F" || $rows['type'] == "H") { $aresult = Questions::model()->findAllByAttributes(array('parent_qid' => $rows['qid'], 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order ASC')); foreach ($aresult as $arows) { $shortanswer = "{$arows['title']}: [" . flattenText($arows['question']) . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . flattenText($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title']); switch ($rows['type']) { case "A": //Array 5 buttons for ($i = 1; $i <= 5; $i++) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], $i, $i); } break; case "B": //Array 10 buttons for ($i = 1; $i <= 10; $i++) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], $i, $i); } break; case "C": //Array Y/N/NA $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "Y", $clang->gT("Yes")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "U", $clang->gT("Uncertain")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "N", $clang->gT("No")); break; case "E": //Array >/=/< $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "I", $clang->gT("Increase")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "S", $clang->gT("Same")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "D", $clang->gT("Decrease")); break; case "F": //Array Flexible Row //Array Flexible Row case "H": //Array Flexible Column $fresult = Answers::model()->findAllByAttributes(array('qid' => $rows['qid'], "language" => Survey::model()->findByPk($iSurveyID)->language, 'scale_id' => 0), array('order' => 'sortorder, code')); foreach ($fresult as $frow) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], $frow['code'], $frow['answer']); } break; } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "", $clang->gT("No answer")); } } //while } elseif ($rows['type'] == ":" || $rows['type'] == ";") { // Multiflexi //Get question attribute for $canswers $qidattributes = getQuestionAttributeValues($rows['qid'], $rows['type']); if (isset($qidattributes['multiflexible_max']) && trim($qidattributes['multiflexible_max']) != '') { $maxvalue = floatval($qidattributes['multiflexible_max']); } else { $maxvalue = 10; } if (isset($qidattributes['multiflexible_min']) && trim($qidattributes['multiflexible_min']) != '') { $minvalue = floatval($qidattributes['multiflexible_min']); } else { $minvalue = 1; } if (isset($qidattributes['multiflexible_step']) && trim($qidattributes['multiflexible_step']) != '') { $stepvalue = floatval($qidattributes['multiflexible_step']); if ($stepvalue == 0) { $stepvalue = 1; } } else { $stepvalue = 1; } if (isset($qidattributes['multiflexible_checkbox']) && $qidattributes['multiflexible_checkbox'] != 0) { $minvalue = 0; $maxvalue = 1; $stepvalue = 1; } // Get the Y-Axis $fquery = "SELECT sq.*, q.other" . " FROM {{questions sq}}, {{questions q}}" . " WHERE sq.sid={$iSurveyID} AND sq.parent_qid=q.qid " . "AND q.language=:lang" . " AND sq.language=:lang" . " AND q.qid=:qid\n AND sq.scale_id=0\n ORDER BY sq.question_order"; $sLanguage = Survey::model()->findByPk($iSurveyID)->language; $y_axis_db = Yii::app()->db->createCommand($fquery)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->bindParam(":qid", $rows['qid'], PDO::PARAM_INT)->query(); // Get the X-Axis $aquery = "SELECT sq.*\n FROM {{questions q}}, {{questions sq}}\n WHERE q.sid={$iSurveyID}\n AND sq.parent_qid=q.qid\n AND q.language=:lang\n AND sq.language=:lang\n AND q.qid=:qid\n AND sq.scale_id=1\n ORDER BY sq.question_order"; $x_axis_db = Yii::app()->db->createCommand($aquery)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->bindParam(":qid", $rows['qid'], PDO::PARAM_INT)->query() or safeDie("Couldn't get answers to Array questions<br />{$aquery}<br />"); foreach ($x_axis_db->readAll() as $frow) { $x_axis[$frow['title']] = $frow['question']; } foreach ($y_axis_db->readAll() as $yrow) { foreach ($x_axis as $key => $val) { $shortquestion = $rows['title'] . ":{$yrow['title']}:{$key}: [" . strip_tags($yrow['question']) . "][" . strip_tags($val) . "] " . flattenText($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $yrow['title'] . "_" . $key); if ($rows['type'] == ":") { for ($ii = $minvalue; $ii <= $maxvalue; $ii += $stepvalue) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $yrow['title'] . "_" . $key, $ii, $ii); } } } } unset($x_axis); } elseif ($rows['type'] == "1") { $aresult = Questions::model()->findAllByAttributes(array('parent_qid' => $rows['qid'], 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order desc')); foreach ($aresult as $arows) { $attr = getQuestionAttributeValues($rows['qid']); $label1 = isset($attr['dualscale_headerA']) ? $attr['dualscale_headerA'] : 'Label1'; $label2 = isset($attr['dualscale_headerB']) ? $attr['dualscale_headerB'] : 'Label2'; $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "][{$label1}]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#0"); $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "][{$label2}]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#1"); // first label $lresult = Answers::model()->findAllByAttributes(array('qid' => $rows['qid'], 'scale_id' => 0, 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); foreach ($lresult as $lrows) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#0", "{$lrows['code']}", "{$lrows['code']}"); } // second label $lresult = Answers::model()->findAllByAttributes(array('qid' => $rows['qid'], 'scale_id' => 1, 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); foreach ($lresult as $lrows) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#1", "{$lrows['code']}", "{$lrows['code']}"); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#0", "", $clang->gT("No answer")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'] . "#1", "", $clang->gT("No answer")); } } //while } elseif ($rows['type'] == "K" || $rows['type'] == "Q") { $aresult = Questions::model()->findAllByAttributes(array("parent_qid" => $rows['qid'], "language" => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order desc')); foreach ($aresult as $arows) { $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title']); // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], "", $clang->gT("No answer")); } } //while } elseif ($rows['type'] == "R") { $aresult = Answers::model()->findAllByAttributes(array("qid" => $rows['qid'], "scale_id" => 0, "language" => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); $acount = count($aresult); foreach ($aresult as $arow) { $theanswer = addcslashes($arow['answer'], "'"); $quicky[] = array($arow['code'], $theanswer); } for ($i = 1; $i <= $acount; $i++) { $cquestions[] = array("{$rows['title']}: [RANK {$i}] " . strip_tags($rows['question']), $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $i); foreach ($quicky as $qck) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $i, $qck[0], $qck[1]); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $i, " ", $clang->gT("No answer")); } } unset($quicky); } elseif ($rows['type'] == "M" || $rows['type'] == "P") { $shortanswer = " [" . $clang->gT("Group of checkboxes") . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid']); $aresult = Questions::model()->findAllByAttributes(array("parent_qid" => $rows['qid'], "language" => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'question_order desc')); foreach ($aresult as $arows) { $theanswer = addcslashes($arows['question'], "'"); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], $arows['title'], $theanswer); $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "]"; $shortanswer .= "[" . $clang->gT("Single checkbox") . "]"; $shortquestion = $rows['title'] . ":{$shortanswer} " . strip_tags($rows['question']); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], "+" . $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title']); $canswers[] = array("+" . $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], 'Y', $clang->gT("checked")); $canswers[] = array("+" . $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'] . $arows['title'], '', $clang->gT("not checked")); } } elseif ($rows['type'] == "X") { //Just ignore this questiontype } else { $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'] . $X . $rows['gid'] . $X . $rows['qid']); switch ($rows['type']) { case "Y": // Y/N/NA $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "Y", $clang->gT("Yes")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "N", $clang->gT("No")); // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", $clang->gT("No answer")); } break; case "G": //Gender $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "F", $clang->gT("Female")); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "M", $clang->gT("Male")); // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", $clang->gT("No answer")); } break; case "5": // 5 choice for ($i = 1; $i <= 5; $i++) { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], $i, $i); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", $clang->gT("No answer")); } break; case "N": // Simple Numerical questions // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", $clang->gT("No answer")); } break; default: $aresult = Answers::model()->findAllByAttributes(array('qid' => $rows['qid'], 'scale_id' => 0, 'language' => Survey::model()->findByPk($iSurveyID)->language), array('order' => 'sortorder, answer')); foreach ($aresult as $arows) { $theanswer = addcslashes($arows['answer'], "'"); $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], $arows['code'], $theanswer); } if ($rows['type'] == "D") { // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", $clang->gT("No answer")); } } elseif ($rows['type'] != "M" && $rows['type'] != "P" && $rows['type'] != "J" && $rows['type'] != "I") { // For dropdown questions // optinnaly add the 'Other' answer if (($rows['type'] == "L" || $rows['type'] == "!") && $rows['other'] == "Y") { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], "-oth-", $clang->gT("Other")); } // Only Show No-Answer if question is not mandatory if ($rows['mandatory'] != 'Y') { $canswers[] = array($rows['sid'] . $X . $rows['gid'] . $X . $rows['qid'], " ", $clang->gT("No answer")); } } break; } //switch row type } //else } //foreach theserows } //if questionscount > 0 //END Gather Information for this question $questionNavOptions = CHtml::openTag('optgroup', array('class' => 'activesurveyselect', 'label' => $clang->gT("Before", "js"))); foreach ($theserows as $row) { $question = $row['question']; $question = strip_tags($question); if (strlen($question) < 35) { $questionselecter = $question; } else { //$questionselecter = substr($question, 0, 35).".."; $questionselecter = htmlspecialchars(mb_strcut(html_entity_decode($question, ENT_QUOTES, 'UTF-8'), 0, 35, 'UTF-8')) . "..."; } $questionNavOptions .= CHtml::tag('option', array('value' => $this->getController()->createUrl("/admin/conditions/sa/index/subaction/editconditionsform/surveyid/{$iSurveyID}/gid/{$row['gid']}/qid/{$row['qid']}")), $questionselecter); } $questionNavOptions .= CHtml::closeTag('optgroup'); $questionNavOptions .= CHtml::openTag('optgroup', array('class' => 'activesurveyselect', 'label' => $clang->gT("Current", "js"))); $question = strip_tags($questiontext); if (strlen($question) < 35) { $questiontextshort = $question; } else { //$questiontextshort = substr($question, 0, 35).".."; $questiontextshort = htmlspecialchars(mb_strcut(html_entity_decode($question, ENT_QUOTES, 'UTF-8'), 0, 35, 'UTF-8')) . "..."; } $questionNavOptions .= CHtml::tag('option', array('value' => $this->getController()->createUrl("/admin/conditions/sa/index/subaction/editconditionsform/surveyid/{$iSurveyID}/gid/{$gid}/qid/{$qid}"), 'selected' => 'selected'), $questiontitle . ': ' . $questiontextshort); $questionNavOptions .= CHtml::closeTag('optgroup'); $questionNavOptions .= CHtml::openTag('optgroup', array('class' => 'activesurveyselect', 'label' => $clang->gT("After", "js"))); foreach ($postrows as $row) { $question = $row['question']; $question = strip_tags($question); if (strlen($question) < 35) { $questionselecter = $question; } else { //$questionselecter = substr($question, 0, 35).".."; $questionselecter = htmlspecialchars(mb_strcut(html_entity_decode($question, ENT_QUOTES, 'UTF-8'), 0, 35, 'UTF-8')) . "..."; } $questionNavOptions .= CHtml::tag('option', array('value' => $this->getController()->createUrl("/admin/conditions/sa/index/subaction/editconditionsform/surveyid/{$iSurveyID}/gid/{$row['gid']}/qid/{$row['qid']}")), $row['title'] . ':' . $questionselecter); } $questionNavOptions .= CHtml::closeTag('optgroup'); //Now display the information and forms //BEGIN: PREPARE JAVASCRIPT TO SHOW MATCHING ANSWERS TO SELECTED QUESTION $javascriptpre = CHtml::openTag('script', array('type' => 'text/javascript')) . "<!--\n" . "\tvar Fieldnames = new Array();\n" . "\tvar Codes = new Array();\n" . "\tvar Answers = new Array();\n" . "\tvar QFieldnames = new Array();\n" . "\tvar Qcqids = new Array();\n" . "\tvar Qtypes = new Array();\n"; $jn = 0; if (isset($canswers)) { foreach ($canswers as $can) { $an = ls_json_encode(flattenText($can[2])); $javascriptpre .= "Fieldnames[{$jn}]='{$can['0']}';\n" . "Codes[{$jn}]='{$can['1']}';\n" . "Answers[{$jn}]={$an};\n"; $jn++; } } $jn = 0; if (isset($cquestions)) { foreach ($cquestions as $cqn) { $javascriptpre .= "QFieldnames[{$jn}]='{$cqn['3']}';\n" . "Qcqids[{$jn}]='{$cqn['1']}';\n" . "Qtypes[{$jn}]='{$cqn['2']}';\n"; $jn++; } } // record a JS variable to let jQuery know if survey is Anonymous if ($thissurvey['anonymized'] == 'Y') { $javascriptpre .= "isAnonymousSurvey = true;"; } else { $javascriptpre .= "isAnonymousSurvey = false;"; } $javascriptpre .= "//-->\n" . CHtml::closeTag('script'); //END: PREPARE JAVASCRIPT TO SHOW MATCHING ANSWERS TO SELECTED QUESTION $this->getController()->_css_admin_includes(Yii::app()->getConfig("publicstyleurl") . 'jquery.multiselect.css'); $aViewUrls = array(); $aData['clang'] = $clang; $aData['surveyid'] = $iSurveyID; $aData['qid'] = $qid; $aData['gid'] = $gid; $aData['imageurl'] = $imageurl; $aData['extraGetParams'] = $extraGetParams; $aData['quesitonNavOptions'] = $questionNavOptions; $aData['conditionsoutput_action_error'] = $conditionsoutput_action_error; $aData['javascriptpre'] = $javascriptpre; $aViewUrls['conditionshead_view'][] = $aData; //BEGIN DISPLAY CONDITIONS FOR THIS QUESTION if ($subaction == 'index' || $subaction == 'editconditionsform' || $subaction == 'insertcondition' || $subaction == "editthiscondition" || $subaction == "delete" || $subaction == "updatecondition" || $subaction == "deletescenario" || $subaction == "renumberscenarios" || $subaction == "deleteallconditions" || $subaction == "updatescenario" || $subaction == 'copyconditionsform' || $subaction == 'copyconditions' || $subaction == 'conditions') { //3: Get other conditions currently set for this question $conditionscount = 0; $s = 0; $criteria = new CDbCriteria(); $criteria->select = 'scenario'; // only select the 'scenario' column $criteria->condition = 'qid=:qid'; $criteria->params = array(':qid' => $qid); $criteria->order = 'scenario'; $criteria->group = 'scenario'; $scenarioresult = Conditions::model()->findAll($criteria); $scenariocount = count($scenarioresult); $showreplace = "{$questiontitle}" . $this->_showSpeaker($questiontext); $onlyshow = sprintf($clang->gT("Only show question %s IF"), $showreplace); $aData['conditionsoutput'] = ''; $aData['extraGetParams'] = $extraGetParams; $aData['quesitonNavOptions'] = $questionNavOptions; $aData['conditionsoutput_action_error'] = $conditionsoutput_action_error; $aData['javascriptpre'] = $javascriptpre; $aData['onlyshow'] = $onlyshow; $aData['subaction'] = $subaction; $aData['scenariocount'] = $scenariocount; $aViewUrls['conditionslist_view'][] = $aData; if ($scenariocount > 0) { //self::_js_admin_includes($this->config->item("generalscripts").'jquery/jquery.checkgroup.js'); $this->getController()->_js_admin_includes(Yii::app()->getConfig("generalscripts") . 'jquery/jquery.checkgroup.js'); foreach ($scenarioresult as $scenarionr) { $scenariotext = ""; if ($s == 0 && $scenariocount > 1) { $scenariotext = " -------- <i>Scenario {$scenarionr['scenario']}</i> --------"; } if ($s > 0) { $scenariotext = " -------- <i>" . $clang->gT("OR") . " Scenario {$scenarionr['scenario']}</i> --------"; } if ($subaction == "copyconditionsform" || $subaction == "copyconditions") { $initialCheckbox = "<td><input type='checkbox' id='scenarioCbx{$scenarionr['scenario']}' checked='checked'/>\n" . "<script type='text/javascript'>\$(document).ready(function () { \$('#scenarioCbx{$scenarionr['scenario']}').checkgroup({ groupName:'aConditionFromScenario{$scenarionr['scenario']}'}); });</script>" . "</td><td> </td>\n"; } else { $initialCheckbox = ""; } if ($scenariotext != "" && ($subaction == "editconditionsform" || $subaction == "insertcondition" || $subaction == "updatecondition" || $subaction == "editthiscondition" || $subaction == "renumberscenarios" || $subaction == "updatescenario" || $subaction == "deletescenario" || $subaction == "delete")) { $img_tag = CHtml::image($imageurl . '/scenario_delete.png', $clang->gT("Delete this scenario"), array('name' => 'DeleteWholeGroup')); $additional_main_content = CHtml::link($img_tag, '#', array('onclick' => "if ( confirm('" . $clang->gT("Are you sure you want to delete all conditions set in this scenario?", "js") . "')) { document.getElementById('deletescenario{$scenarionr['scenario']}').submit();}")); $img_tag = CHtml::image($imageurl . '/scenario_edit.png', $clang->gT("Edit scenario"), array('name' => 'DeleteWholeGroup')); $additional_main_content .= CHtml::link($img_tag, '#', array('id' => 'editscenariobtn' . $scenarionr['scenario'], 'onclick' => "\$('#editscenario{$scenarionr['scenario']}').toggle('slow');")); $aData['additional_content'] = $additional_main_content; } $aData['initialCheckbox'] = $initialCheckbox; $aData['scenariotext'] = $scenariotext; $aData['scenarionr'] = $scenarionr; if (!isset($aViewUrls['output'])) { $aViewUrls['output'] = ''; } $aViewUrls['output'] .= $this->getController()->render('/admin/conditions/includes/conditions_scenario', $aData, TRUE); unset($currentfield); $query = "SELECT count(*) as recordcount\n FROM {{conditions}} c, {{questions}} q, {{groups}} g\n WHERE c.cqid=q.qid " . "AND q.gid=g.gid " . "AND q.parent_qid=0 " . "AND q.language=:lang1 " . "AND g.language=:lang2 " . "AND c.qid=:qid " . "AND c.scenario=:scenario " . "AND c.cfieldname NOT LIKE '{%' "; // avoid catching SRCtokenAttr conditions $sLanguage = Survey::model()->findByPk($iSurveyID)->language; $result = Yii::app()->db->createCommand($query)->bindValue(":scenario", $scenarionr['scenario'])->bindValue(":qid", $qid, PDO::PARAM_INT)->bindValue(":lang1", $sLanguage, PDO::PARAM_STR)->bindValue(":lang2", $sLanguage, PDO::PARAM_STR)->queryRow(); $conditionscount = (int) $result['recordcount']; $query = "SELECT c.cid, c.scenario, c.cqid, c.cfieldname, c.method, c.value, q.type\n FROM {{conditions}} c, {{questions}} q, {{groups}} g\n WHERE c.cqid=q.qid " . "AND q.gid=g.gid " . "AND q.parent_qid=0 " . "AND q.language=:lang1 " . "AND g.language=:lang2 " . "AND c.qid=:qid " . "AND c.scenario=:scenario " . "AND c.cfieldname NOT LIKE '{%' " . "ORDER BY g.group_order, q.question_order, c.cfieldname"; $sLanguage = Survey::model()->findByPk($iSurveyID)->language; $result = Yii::app()->db->createCommand($query)->bindValue(":scenario", $scenarionr['scenario'])->bindValue(":qid", $qid, PDO::PARAM_INT)->bindValue(":lang1", $sLanguage, PDO::PARAM_STR)->bindValue(":lang2", $sLanguage, PDO::PARAM_STR)->query() or safeDie("Couldn't get other conditions for question {$qid}<br />{$query}<br />"); $querytoken = "SELECT count(*) as recordcount " . "FROM {{conditions}} " . "WHERE " . " {{conditions}}.qid=:qid " . "AND {{conditions}}.scenario=:scenario " . "AND {{conditions}}.cfieldname LIKE '{%' "; // only catching SRCtokenAttr conditions $resulttoken = Yii::app()->db->createCommand($querytoken)->bindValue(":scenario", $scenarionr['scenario'], PDO::PARAM_INT)->bindValue(":qid", $qid, PDO::PARAM_INT)->queryRow() or safeDie("Couldn't get other conditions for question {$qid}<br />{$query}<br />"); $conditionscounttoken = (int) $resulttoken['recordcount']; $querytoken = "SELECT {{conditions}}.cid, " . "{{conditions}}.scenario, " . "{{conditions}}.cqid, " . "{{conditions}}.cfieldname, " . "{{conditions}}.method, " . "{{conditions}}.value, " . "'' AS type " . "FROM {{conditions}} " . "WHERE " . " {{conditions}}.qid=:qid " . "AND {{conditions}}.scenario=:scenario " . "AND {{conditions}}.cfieldname LIKE '{%' " . "ORDER BY {{conditions}}.cfieldname"; $resulttoken = Yii::app()->db->createCommand($querytoken)->bindValue(":scenario", $scenarionr['scenario'], PDO::PARAM_INT)->bindValue(":qid", $qid, PDO::PARAM_INT)->query() or safeDie("Couldn't get other conditions for question {$qid}<br />{$query}<br />"); $conditionscount = $conditionscount + $conditionscounttoken; if ($conditionscount > 0) { $aConditionsMerged = array(); foreach ($resulttoken->readAll() as $arow) { $aConditionsMerged[] = $arow; } foreach ($result->readAll() as $arow) { $aConditionsMerged[] = $arow; } foreach ($aConditionsMerged as $rows) { if ($rows['method'] == "") { $rows['method'] = "=="; } //Fill in the empty method from previous versions $markcidstyle = "oddrow"; if (array_search($rows['cid'], $markcidarray) !== FALSE) { // This is the style used when the condition editor is called // in order to check which conditions prevent a question deletion $markcidstyle = "markedrow"; } if ($subaction == "editthiscondition" && isset($p_cid) && $rows['cid'] === $p_cid) { // Style used when editing a condition $markcidstyle = "editedrow"; } if (isset($currentfield) && $currentfield != $rows['cfieldname']) { $aViewUrls['output'] .= "<tr class='evenrow'>\n" . "\t<td colspan='2'>\n" . "<span><strong>" . $clang->gT("and") . "</strong></span></td></tr>"; } elseif (isset($currentfield)) { $aViewUrls['output'] .= "<tr class='evenrow'>\n" . "\t<td colspan='2'>\n" . "<span><strong>" . $clang->gT("or") . "</strong></span></td></tr>"; } $aViewUrls['output'] .= "\t<tr class='{$markcidstyle}'>\n" . "\t<td colspan='2'>" . CHtml::form(array("/admin/conditions/sa/index/subaction/{$subaction}/surveyid/{$iSurveyID}/gid/{$gid}/qid/{$qid}/"), 'post', array('id' => "conditionaction{$rows['cid']}", 'name' => "conditionaction{$rows['cid']}")) . "<table>\n" . "\t<tr>\n"; if ($subaction == "copyconditionsform" || $subaction == "copyconditions") { $aViewUrls['output'] .= "<td> </td>" . "<td>\n" . "\t<input type='checkbox' name='aConditionFromScenario{$scenarionr['scenario']}' id='cbox{$rows['cid']}' value='{$rows['cid']}' checked='checked'/>\n" . "</td>\n"; } $aViewUrls['output'] .= "" . "<td>\n" . "\t<span>\n"; $leftOperandType = 'unknown'; // prevquestion, tokenattr if ($thissurvey['anonymized'] != 'Y' && preg_match('/^{TOKEN:([^}]*)}$/', $rows['cfieldname'], $extractedTokenAttr) > 0) { $leftOperandType = 'tokenattr'; $aTokenAttrNames = getTokenFieldsAndNames($iSurveyID); if (count($aTokenAttrNames) != 0) { $thisAttrName = HTMLEscape($aTokenAttrNames[strtolower($extractedTokenAttr[1])]['description']) . " [" . $clang->gT("From token table") . "]"; } else { $thisAttrName = HTMLEscape($extractedTokenAttr[1]) . " [" . $clang->gT("Inexistant token table") . "]"; } $aViewUrls['output'] .= "\t{$thisAttrName}\n"; // TIBO not sure this is used anymore !! $conditionsList[] = array("cid" => $rows['cid'], "text" => $thisAttrName); } else { $leftOperandType = 'prevquestion'; foreach ($cquestions as $cqn) { if ($cqn[3] == $rows['cfieldname']) { $aViewUrls['output'] .= "\t{$cqn['0']} (qid{$rows['cqid']})\n"; $conditionsList[] = array("cid" => $rows['cid'], "text" => $cqn[0] . " ({$rows['value']})"); } else { //$aViewUrls['output'] .= "\t<font color='red'>ERROR: Delete this condition. It is out of order.</font>\n"; } } } $aViewUrls['output'] .= "\t</span></td>\n" . "\t<td>\n" . "<span>\n" . $method[trim($rows['method'])] . "</span>\n" . "\t</td>\n" . "\n" . "\t<td>\n" . "<span>\n"; // let's read the condition's right operand // determine its type and display it $rightOperandType = 'unknown'; // predefinedAnsw,constantVal, prevQsgqa, tokenAttr, regexp if ($rows['method'] == 'RX') { $rightOperandType = 'regexp'; $aViewUrls['output'] .= "" . HTMLEscape($rows['value']) . "\n"; } elseif (preg_match('/^@([0-9]+X[0-9]+X[^@]*)@$/', $rows['value'], $matchedSGQA) > 0) { // SGQA $rightOperandType = 'prevQsgqa'; $textfound = false; foreach ($cquestions as $cqn) { if ($cqn[3] == $matchedSGQA[1]) { $matchedSGQAText = $cqn[0]; $textfound = true; break; } } if ($textfound === false) { $matchedSGQAText = $rows['value'] . ' (' . $clang->gT("Not found") . ')'; } $aViewUrls['output'] .= "" . HTMLEscape($matchedSGQAText) . "\n"; } elseif ($thissurvey['anonymized'] != 'Y' && preg_match('/^{TOKEN:([^}]*)}$/', $rows['value'], $extractedTokenAttr) > 0) { $rightOperandType = 'tokenAttr'; $aTokenAttrNames = getTokenFieldsAndNames($iSurveyID); if (count($aTokenAttrNames) != 0) { $thisAttrName = HTMLEscape($aTokenAttrNames[strtolower($extractedTokenAttr[1])]['description']) . " [" . $clang->gT("From token table") . "]"; } else { $thisAttrName = HTMLEscape($extractedTokenAttr[1]) . " [" . $clang->gT("Inexistant token table") . "]"; } $aViewUrls['output'] .= "\t{$thisAttrName}\n"; } elseif (isset($canswers)) { foreach ($canswers as $can) { if ($can[0] == $rows['cfieldname'] && $can[1] == $rows['value']) { $aViewUrls['output'] .= "{$can['2']} ({$can['1']})\n"; $rightOperandType = 'predefinedAnsw'; } } } // if $rightOperandType is still unkown then it is a simple constant if ($rightOperandType == 'unknown') { $rightOperandType = 'constantVal'; if ($rows['value'] == ' ' || $rows['value'] == '') { $aViewUrls['output'] .= "" . $clang->gT("No answer") . "\n"; } else { $aViewUrls['output'] .= "" . HTMLEscape($rows['value']) . "\n"; } } $aViewUrls['output'] .= "\t</span></td>\n" . "\t<td>\n"; if ($subaction == "editconditionsform" || $subaction == "insertcondition" || $subaction == "updatecondition" || $subaction == "editthiscondition" || $subaction == "renumberscenarios" || $subaction == "deleteallconditions" || $subaction == "updatescenario" || $subaction == "deletescenario" || $subaction == "delete") { // show single condition action buttons in edit mode $aData['rows'] = $rows; $aData['sImageURL'] = Yii::app()->getConfig('adminimageurl'); //$aViewUrls['includes/conditions_edit'][] = $aData; $aViewUrls['output'] .= $this->getController()->render('/admin/conditions/includes/conditions_edit', $aData, TRUE); // now sets e corresponding hidden input field // depending on the leftOperandType if ($leftOperandType == 'tokenattr') { $aViewUrls['output'] .= CHtml::hiddenField('csrctoken', HTMLEscape($rows['cfieldname']), array('id' => 'csrctoken' . $rows['cid'])); } else { $aViewUrls['output'] .= CHtml::hiddenField('cquestions', HTMLEscape($rows['cfieldname']), array('id' => 'cquestions' . $rows['cid'])); } // now set the corresponding hidden input field // depending on the rightOperandType // This is used when Editting a condition if ($rightOperandType == 'predefinedAnsw') { $aViewUrls['output'] .= CHtml::hiddenField('EDITcanswers[]', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } elseif ($rightOperandType == 'prevQsgqa') { $aViewUrls['output'] .= CHtml::hiddenField('EDITprevQuestionSGQA', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } elseif ($rightOperandType == 'tokenAttr') { $aViewUrls['output'] .= CHtml::hiddenField('EDITtokenAttr', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } elseif ($rightOperandType == 'regexp') { $aViewUrls['output'] .= CHtml::hiddenField('EDITConditionRegexp', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } else { $aViewUrls['output'] .= CHtml::hiddenField('EDITConditionConst', HTMLEscape($rows['value']), array('id' => 'editModeTargetVal' . $rows['cid'])); } } $aViewUrls['output'] .= CHtml::closeTag('td') . CHtml::closeTag('tr') . CHtml::closeTag('table') . CHtml::closeTag('form') . CHtml::closeTag('td') . CHtml::closeTag('tr'); $currentfield = $rows['cfieldname']; } } $s++; } } else { // no condition ==> disable delete all conditions button, and display a simple comment $aViewUrls['output'] = CHtml::openTag('tr') . CHtml::tag('td', array(), $clang->gT("This question is always shown.")) . CHtml::tag('td', array(), ' ') . CHtml::closeTag('tr'); } $aViewUrls['output'] .= CHtml::closeTag('table'); } //END DISPLAY CONDITIONS FOR THIS QUESTION // BEGIN: DISPLAY THE COPY CONDITIONS FORM if ($subaction == "copyconditionsform" || $subaction == "copyconditions") { $aViewUrls['output'] .= "<tr class=''><td colspan='3'>\n" . CHtml::form(array("/admin/conditions/sa/index/subaction/copyconditions/surveyid/{$iSurveyID}/gid/{$gid}/qid/{$qid}/"), 'post', array('id' => "copyconditions", 'name' => "copyconditions")) . "<div class='header ui-widget-header'>" . $clang->gT("Copy conditions") . "</div>\n"; //CopyConditionsMessage if (isset($CopyConditionsMessage)) { $aViewUrls['output'] .= "<div class='messagebox ui-corner-all'>\n" . "{$CopyConditionsMessage}\n" . "</div>\n"; } if (isset($conditionsList) && is_array($conditionsList)) { //TIBO $this->getController()->_js_admin_includes(Yii::app()->getConfig("generalscripts") . 'jquery/jquery.multiselect.min.js'); // TODO $aViewUrls['output'] .= "<script type='text/javascript'>\$(document).ready(function () { \$('#copytomultiselect').multiselect( { autoOpen: true, noneSelectedText: '" . $clang->gT("No questions selected") . "', checkAllText: '" . $clang->gT("Check all") . "', uncheckAllText: '" . $clang->gT("Uncheck all") . "', selectedText: '# " . $clang->gT("selected") . "', beforeclose: function(){ return false;},height: 200 } ); });</script>"; $aViewUrls['output'] .= "\t<div class='conditioncopy-tbl-row'>\n" . "\t<div class='condition-tbl-left'>" . $clang->gT("Copy the selected conditions to") . ":</div>\n" . "\t<div class='condition-tbl-right'>\n" . "\t\t<select name='copyconditionsto[]' id='copytomultiselect' multiple='multiple' >\n"; if (isset($pquestions) && count($pquestions) != 0) { foreach ($pquestions as $pq) { $aViewUrls['output'] .= "\t\t<option value='{$pq['fieldname']}'>" . $pq['text'] . "</option>\n"; } } $aViewUrls['output'] .= "\t\t</select>\n" . "\t</div>\n" . "\t</div>\n"; if (!isset($pquestions) || count($pquestions) == 0) { $disableCopyCondition = " disabled='disabled'"; } else { $disableCopyCondition = " "; } $aViewUrls['output'] .= "\t<div class='condition-tbl-full'>\n" . "\t\t<input type='submit' value='" . $clang->gT("Copy conditions") . "' onclick=\"prepareCopyconditions(); return true;\" {$disableCopyCondition}/>\n" . "<input type='hidden' name='subaction' value='copyconditions' />\n" . "<input type='hidden' name='sid' value='{$iSurveyID}' />\n" . "<input type='hidden' name='gid' value='{$gid}' />\n" . "<input type='hidden' name='qid' value='{$qid}' />\n" . "</div>\n"; $aViewUrls['output'] .= "<script type=\"text/javascript\">\n" . "function prepareCopyconditions()\n" . "{\n" . "\t\$(\"input:checked[name^='aConditionFromScenario']\").each(function(i,val)\n" . "\t{\n" . "var thecid = val.value;\n" . "var theform = document.getElementById('copyconditions');\n" . "addHiddenElement(theform,'copyconditionsfrom[]',thecid);\n" . "return true;\n" . "\t});\n" . "}\n" . "</script>\n"; } else { $aViewUrls['output'] .= "<div class='messagebox ui-corner-all'>\n" . "<div class='partialheader'>" . $clang->gT("There are no existing conditions in this survey.") . "</div><br />\n" . "</div>\n"; } $aViewUrls['output'] .= "</form></td></tr>\n"; } // END: DISPLAY THE COPY CONDITIONS FORM if (isset($cquestions)) { if (count($cquestions) > 0 && count($cquestions) <= 10) { $qcount = count($cquestions); } else { $qcount = 9; } } else { $qcount = 0; } //BEGIN: DISPLAY THE ADD or EDIT CONDITION FORM if ($subaction == "editconditionsform" || $subaction == "insertcondition" || $subaction == "updatecondition" || $subaction == "deletescenario" || $subaction == "renumberscenarios" || $subaction == "deleteallconditions" || $subaction == "updatescenario" || $subaction == "editthiscondition" || $subaction == "delete") { $aViewUrls['output'] .= CHtml::form(array("/admin/conditions/sa/index/subaction/{$subaction}/surveyid/{$iSurveyID}/gid/{$gid}/qid/{$qid}/"), 'post', array('id' => "editconditions", 'name' => "editconditions")); if ($subaction == "editthiscondition" && isset($p_cid)) { $mytitle = $clang->gT("Edit condition"); } else { $mytitle = $clang->gT("Add condition"); } $aViewUrls['output'] .= "<div class='header ui-widget-header'>" . $mytitle . "</div>\n"; /////////////////////////////////////////////////////////////////////////////////////////// // Begin "Scenario" row if ($subaction != "editthiscondition" && isset($scenariocount) && ($scenariocount == 1 || $scenariocount == 0) || $subaction == "editthiscondition" && isset($scenario) && $scenario == 1) { $scenarioAddBtn = "\t<a id='scenarioaddbtn' href='#' onclick=\"\$('#scenarioaddbtn').hide();\$('#defaultscenariotxt').hide('slow');\$('#scenario').show('slow');\">" . "<img src='{$imageurl}/plus.png' alt='" . $clang->gT('Add scenario') . "' /></a>\n"; $scenarioTxt = "<span id='defaultscenariotxt'>" . $clang->gT("Default scenario") . "</span>"; $scenarioInputStyle = "style = 'display: none;'"; } else { $scenarioAddBtn = ""; $scenarioTxt = ""; $scenarioInputStyle = "style = ''"; } $aViewUrls['output'] .= "<div class='condition-tbl-row'>\n" . "<div class='condition-tbl-left'>{$scenarioAddBtn} " . $clang->gT("Scenario") . "</div>\n" . "<div class='condition-tbl-right'><input type='text' name='scenario' id='scenario' value='1' size='2' {$scenarioInputStyle}/>" . "{$scenarioTxt}\n" . "</div>\n" . "</div>\n"; // Begin "Question" row $aViewUrls['output'] .= "<div class='condition-tbl-row'>\n" . "<div class='condition-tbl-left'>" . $clang->gT("Question") . "</div>\n" . "<div class='condition-tbl-right'>\n" . "\t<div id=\"conditionsource\" class=\"tabs-nav\">\n" . "\t<ul>\n" . "\t<li><a href=\"#SRCPREVQUEST\"><span>" . $clang->gT("Previous questions") . "</span></a></li>\n" . "\t<li><a href=\"#SRCTOKENATTRS\"><span>" . $clang->gT("Token fields") . "</span></a></li>\n" . "\t</ul>\n"; // Previous question tab $aViewUrls['output'] .= "<div id='SRCPREVQUEST'><select name='cquestions' id='cquestions' size='" . ($qcount + 1) . "' >\n"; if (isset($cquestions)) { $js_getAnswers_onload = ""; foreach ($cquestions as $cqn) { $aViewUrls['output'] .= "<option value='{$cqn['3']}' title=\"" . htmlspecialchars($cqn[0]) . "\""; if (isset($p_cquestions) && $cqn[3] == $p_cquestions) { $aViewUrls['output'] .= " selected"; if (isset($p_canswers)) { $canswersToSelect = ""; foreach ($p_canswers as $checkval) { $canswersToSelect .= ";{$checkval}"; } $canswersToSelect = substr($canswersToSelect, 1); $js_getAnswers_onload .= "\$('#canswersToSelect').val('{$canswersToSelect}');\n"; } } $aViewUrls['output'] .= ">{$cqn['0']}</option>\n"; } } $aViewUrls['output'] .= "</select>\n" . "</div>\n"; // Source token Tab $aViewUrls['output'] .= "<div id='SRCTOKENATTRS'><select name='csrctoken' id='csrctoken' size='" . ($qcount + 1) . "' >\n"; foreach (getTokenFieldsAndNames($iSurveyID) as $tokenattr => $tokenattrName) { // Check to select if (isset($p_csrctoken) && $p_csrctoken == '{TOKEN:' . strtoupper($tokenattr) . '}') { $selectThisSrcTokenAttr = "selected=\"selected\""; } else { $selectThisSrcTokenAttr = ""; } $aViewUrls['output'] .= "<option value='{TOKEN:" . strtoupper($tokenattr) . "}' {$selectThisSrcTokenAttr}>" . HTMLEscape($tokenattrName['description']) . "</option>\n"; } $aViewUrls['output'] .= "</select>\n" . "</div>\n\n"; $aViewUrls['output'] .= "\t</div>\n"; // end conditionsource div $aViewUrls['output'] .= "</div>\n" . "</div>\n"; // Begin "Comparison operator" row $aViewUrls['output'] .= "<div class='condition-tbl-row'>\n" . "<div class='condition-tbl-left'>" . $clang->gT("Comparison operator") . "</div>\n" . "<div class='condition-tbl-right'>\n" . "<select name='method' id='method'>\n"; foreach ($method as $methodCode => $methodTxt) { $selected = $methodCode == "==" ? " selected='selected'" : ""; $aViewUrls['output'] .= "\t<option value='" . $methodCode . "'{$selected}>" . $methodTxt . "</option>\n"; } $aViewUrls['output'] .= "</select>\n" . "</div>\n" . "</div>\n"; // Begin "Answer" row $aViewUrls['output'] .= "<div class='condition-tbl-row'>\n" . "<div class='condition-tbl-left'>" . $clang->gT("Answer") . "</div>\n"; if ($subaction == "editthiscondition") { $multipletext = ""; if (isset($_POST['EDITConditionConst']) && $_POST['EDITConditionConst'] != '') { $EDITConditionConst = HTMLEscape($_POST['EDITConditionConst']); } else { $EDITConditionConst = ""; } if (isset($_POST['EDITConditionRegexp']) && $_POST['EDITConditionRegexp'] != '') { $EDITConditionRegexp = HTMLEscape($_POST['EDITConditionRegexp']); } else { $EDITConditionRegexp = ""; } } else { $multipletext = "multiple"; if (isset($_POST['ConditionConst']) && $_POST['ConditionConst'] != '') { $EDITConditionConst = HTMLEscape($_POST['ConditionConst']); } else { $EDITConditionConst = ""; } if (isset($_POST['ConditionRegexp']) && $_POST['ConditionRegexp'] != '') { $EDITConditionRegexp = HTMLEscape($_POST['ConditionRegexp']); } else { $EDITConditionRegexp = ""; } } $aViewUrls['output'] .= "" . "<div class='condition-tbl-right'>\n" . "<div id=\"conditiontarget\" class=\"tabs-nav\">\n" . "\t<ul>\n" . "\t\t<li><a href=\"#CANSWERSTAB\"><span>" . $clang->gT("Predefined") . "</span></a></li>\n" . "\t\t<li><a href=\"#CONST\"><span>" . $clang->gT("Constant") . "</span></a></li>\n" . "\t\t<li><a href=\"#PREVQUESTIONS\"><span>" . $clang->gT("Questions") . "</span></a></li>\n" . "\t\t<li><a href=\"#TOKENATTRS\"><span>" . $clang->gT("Token fields") . "</span></a></li>\n" . "\t\t<li><a href=\"#REGEXP\"><span>" . $clang->gT("RegExp") . "</span></a></li>\n" . "\t</ul>\n"; // Predefined answers tab $aViewUrls['output'] .= "\t<div id='CANSWERSTAB'>\n" . "\t\t<select name='canswers[]' {$multipletext} id='canswers' size='7'>\n" . "\t\t</select>\n" . "\t\t<br /><span id='canswersLabel'>" . $clang->gT("Predefined answer options for this question") . "</span>\n" . "\t</div>\n"; // Constant tab $aViewUrls['output'] .= "\t<div id='CONST' style='display:block;' >\n" . "\t\t<textarea name='ConditionConst' id='ConditionConst' rows='5' cols='113'>{$EDITConditionConst}</textarea>\n" . "\t\t<br /><div id='ConditionConstLabel'>" . $clang->gT("Constant value") . "</div>\n" . "\t</div>\n"; // Previous answers tab @SGQA@ placeholders $aViewUrls['output'] .= "\t<div id='PREVQUESTIONS'>\n" . "\t\t<select name='prevQuestionSGQA' id='prevQuestionSGQA' size='7'>\n"; foreach ($cquestions as $cqn) { // building the @SGQA@ placeholders options if ($cqn[2] != 'M' && $cqn[2] != 'P') { // Type M or P aren't real fieldnames and thus can't be used in @SGQA@ placehodlers $aViewUrls['output'] .= "\t\t<option value='@{$cqn['3']}@' title=\"" . htmlspecialchars($cqn[0]) . "\""; if (isset($p_prevquestionsgqa) && $p_prevquestionsgqa == "@" . $cqn[3] . "@") { $aViewUrls['output'] .= " selected='selected'"; } $aViewUrls['output'] .= ">{$cqn['0']}</option>\n"; } } $aViewUrls['output'] .= "\t\t</select>\n" . "\t\t<br /><span id='prevQuestionSGQALabel'>" . $clang->gT("Answers from previous questions") . "</span>\n" . "\t</div>\n"; // Token tab $aViewUrls['output'] .= "\t<div id='TOKENATTRS'>\n" . "\t\t<select name='tokenAttr' id='tokenAttr' size='7'>\n"; foreach (getTokenFieldsAndNames($iSurveyID) as $tokenattr => $tokenattrName) { $aViewUrls['output'] .= "\t\t<option value='{TOKEN:" . strtoupper($tokenattr) . "}'>" . HTMLEscape($tokenattrName['description']) . "</option>\n"; } $aViewUrls['output'] .= "\t\t</select>\n" . "\t\t<br /><span id='tokenAttrLabel'>" . $clang->gT("Attributes values from the participant's token") . "</span>\n" . "\t</div>\n"; // Regexp Tab $aViewUrls['output'] .= "\t<div id='REGEXP' style='display:block;'>\n" . "\t\t<textarea name='ConditionRegexp' id='ConditionRegexp' rows='5' cols='113'>{$EDITConditionRegexp}</textarea>\n" . "\t\t<br /><div id='ConditionRegexpLabel'><a href=\"http://docs.limesurvey.org/tiki-index.php?page=Using+Regular+Expressions\" target=\"_blank\">" . $clang->gT("Regular expression") . "</a></div>\n" . "\t</div>\n"; $aViewUrls['output'] .= "</div>\n"; // end conditiontarget div $this->getController()->_js_admin_includes(Yii::app()->getConfig("adminscripts") . 'conditions.js'); $this->getController()->_js_admin_includes(Yii::app()->getConfig("generalscripts") . 'jquery/lime-conditions-tabs.js'); if ($subaction == "editthiscondition" && isset($p_cid)) { $submitLabel = $clang->gT("Update condition"); $submitSubaction = "updatecondition"; $submitcid = sanitize_int($p_cid); } else { $submitLabel = $clang->gT("Add condition"); $submitSubaction = "insertcondition"; $submitcid = ""; } $aViewUrls['output'] .= "</div>\n" . "</div>\n"; // Begin buttons row $aViewUrls['output'] .= "<div class='condition-tbl-full'>\n" . "\t<input type='reset' id='resetForm' value='" . $clang->gT("Clear") . "' />\n" . "\t<input type='submit' value='" . $submitLabel . "' />\n" . "<input type='hidden' name='sid' value='{$iSurveyID}' />\n" . "<input type='hidden' name='gid' value='{$gid}' />\n" . "<input type='hidden' name='qid' value='{$qid}' />\n" . "<input type='hidden' name='subaction' value='{$submitSubaction}' />\n" . "<input type='hidden' name='cqid' id='cqid' value='' />\n" . "<input type='hidden' name='cid' id='cid' value='" . $submitcid . "' />\n" . "<input type='hidden' name='editTargetTab' id='editTargetTab' value='' />\n" . "<input type='hidden' name='editSourceTab' id='editSourceTab' value='' />\n" . "<input type='hidden' name='canswersToSelect' id='canswersToSelect' value='' />\n" . "</div>\n" . "</form>\n"; if (!isset($js_getAnswers_onload)) { $js_getAnswers_onload = ''; } $aViewUrls['output'] .= "<script type='text/javascript'>\n" . "<!--\n" . "\t" . $js_getAnswers_onload . "\n"; if (isset($p_method)) { $aViewUrls['output'] .= "\tdocument.getElementById('method').value='" . $p_method . "';\n"; } if ($subaction == "editthiscondition") { // in edit mode we read previous values in order to dusplay them in the corresponding inputs if (isset($_POST['EDITConditionConst']) && $_POST['EDITConditionConst'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionConst').value='".HTMLEscape($_POST['EDITConditionConst'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CONST';\n"; } elseif (isset($_POST['EDITprevQuestionSGQA']) && $_POST['EDITprevQuestionSGQA'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('prevQuestionSGQA').value='" . HTMLEscape($_POST['EDITprevQuestionSGQA']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#PREVQUESTIONS';\n"; } elseif (isset($_POST['EDITtokenAttr']) && $_POST['EDITtokenAttr'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('tokenAttr').value='" . HTMLEscape($_POST['EDITtokenAttr']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#TOKENATTRS';\n"; } elseif (isset($_POST['EDITConditionRegexp']) && $_POST['EDITConditionRegexp'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionRegexp').value='".HTMLEscape($_POST['EDITConditionRegexp'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#REGEXP';\n"; } elseif (isset($_POST['EDITcanswers']) && is_array($_POST['EDITcanswers'])) { // was a predefined answers post $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CANSWERSTAB';\n"; $aViewUrls['output'] .= "\t\$('#canswersToSelect').val('" . $_POST['EDITcanswers'][0] . "');\n"; } if (isset($_POST['csrctoken']) && $_POST['csrctoken'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('csrctoken').value='" . HTMLEscape($_POST['csrctoken']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCTOKENATTRS';\n"; } else { if (isset($_POST['cquestions']) && $_POST['cquestions'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('cquestions').value='" . HTMLEscape($_POST['cquestions']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCPREVQUEST';\n"; } } } else { // in other modes, for the moment we do the same as for edit mode if (isset($_POST['ConditionConst']) && $_POST['ConditionConst'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionConst').value='".HTMLEscape($_POST['ConditionConst'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CONST';\n"; } elseif (isset($_POST['prevQuestionSGQA']) && $_POST['prevQuestionSGQA'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('prevQuestionSGQA').value='" . HTMLEscape($_POST['prevQuestionSGQA']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#PREVQUESTIONS';\n"; } elseif (isset($_POST['tokenAttr']) && $_POST['tokenAttr'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('tokenAttr').value='" . HTMLEscape($_POST['tokenAttr']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#TOKENATTRS';\n"; } elseif (isset($_POST['ConditionRegexp']) && $_POST['ConditionRegexp'] != '') { // In order to avoid issues with backslash escaping, I don't use javascript to set the value // Thus the value is directly set when creating the Textarea element //$aViewUrls['output'] .= "\tdocument.getElementById('ConditionRegexp').value='".HTMLEscape($_POST['ConditionRegexp'])."';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#REGEXP';\n"; } else { // was a predefined answers post if (isset($_POST['cquestions'])) { $aViewUrls['output'] .= "\tdocument.getElementById('cquestions').value='" . HTMLEscape($_POST['cquestions']) . "';\n"; } $aViewUrls['output'] .= "\tdocument.getElementById('editTargetTab').value='#CANSWERSTAB';\n"; } if (isset($_POST['csrctoken']) && $_POST['csrctoken'] != '') { $aViewUrls['output'] .= "\tdocument.getElementById('csrctoken').value='" . HTMLEscape($_POST['csrctoken']) . "';\n"; $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCTOKENATTRS';\n"; } else { if (isset($_POST['cquestions'])) { $aViewUrls['output'] .= "\tdocument.getElementById('cquestions').value='" . javascriptEscape($_POST['cquestions']) . "';\n"; } $aViewUrls['output'] .= "\tdocument.getElementById('editSourceTab').value='#SRCPREVQUEST';\n"; } } if (isset($p_scenario)) { $aViewUrls['output'] .= "\tdocument.getElementById('scenario').value='" . $p_scenario . "';\n"; } $aViewUrls['output'] .= "-->\n" . "</script>\n"; } //END: DISPLAY THE ADD or EDIT CONDITION FORM $conditionsoutput = $aViewUrls['output']; $aData['conditionsoutput'] = $conditionsoutput; $this->_renderWrappedTemplate('conditions', $aViewUrls, $aData); // TMSW Conditions->Relevance: Must call LEM->ConvertConditionsToRelevance() whenever Condition is added or updated - what is best location for that action? }
/** * Check the Expression in email * @param integer $iSurveyId : the survey id : can be sid/surveyid url GET parameters * @param string $lang : the mail language * * @author Denis Chenu * @version 1.1 */ public function email($iSurveyId, $lang) { if (!Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'read')) { throw new CHttpException(401, "401 Unauthorized"); } $sType = Yii::app()->request->getQuery('type'); $this->sLang = $sLang = $lang; $this->iSurveyId = $iSurveyId; // This start the survey before Expression : is this allways needed ? $aTypeAttributes = array('invitation' => array('subject' => array('attribute' => 'surveyls_email_invite_subj', 'title' => gt('Invitation email subject')), 'message' => array('attribute' => 'surveyls_email_invite', 'title' => gt('Invitation email body'))), 'reminder' => array('subject' => array('attribute' => 'surveyls_email_remind_subj', 'title' => gt('Reminder email subject')), 'message' => array('attribute' => 'surveyls_email_remind', 'title' => gt('Reminder email body'))), 'confirmation' => array('subject' => array('attribute' => 'surveyls_email_confirm_subj', 'title' => gt('Confirmation email subject')), 'message' => array('attribute' => 'surveyls_email_confirm', 'title' => gt('Confirmation email body'))), 'registration' => array('subject' => array('attribute' => 'surveyls_email_register_subj', 'title' => gt('Registration email subject')), 'message' => array('attribute' => 'surveyls_email_register', 'title' => gt('Registration email body'))), 'admin_notification' => array('subject' => array('attribute' => 'email_admin_notification_subj', 'title' => gt('Basic admin notification subject')), 'message' => array('attribute' => 'email_admin_notification', 'title' => gt('Basic admin notification body'))), 'admin_detailed_notification' => array('subject' => array('attribute' => 'email_admin_responses_subj', 'title' => gt('Detailed admin notification subject')), 'message' => array('attribute' => 'email_admin_responses', 'title' => gt('Detailed admin notification body')))); $aSurveyInfo = getSurveyInfo($iSurveyId, $sLang); // Replaced before email edit $aReplacement = array('ADMINNAME' => $aSurveyInfo['admin'], 'ADMINEMAIL' => $aSurveyInfo['adminemail']); // Not needed : templatereplace do the job : but this can/must be fixed for invitaton/reminder/registration (#9424) $aReplacement["SURVEYNAME"] = gT("Name of the survey"); $aReplacement["SURVEYDESCRIPTION"] = gT("Description of the survey"); // Replaced when sending email with Survey $aAttributes = getTokenFieldsAndNames($iSurveyId, true); $aReplacement["TOKEN"] = gt("Token code for this participant"); $aReplacement["TOKEN:EMAIL"] = gt("Email from the token"); $aReplacement["TOKEN:FIRSTNAME"] = gt("First name from token"); $aReplacement["TOKEN:LASTNAME"] = gt("Last name from token"); $aReplacement["TOKEN:TOKEN"] = gt("Token code for this participant"); $aReplacement["TOKEN:LANGUAGE"] = gt("language of token"); foreach ($aAttributes as $sAttribute => $aAttribute) { $aReplacement['TOKEN:' . strtoupper($sAttribute) . ''] = sprintf(gT("Token attribute: %s"), $aAttribute['description']); } switch ($sType) { case 'invitation': case 'reminder': case 'registration': // Replaced when sending email (registration too ?) $aReplacement["EMAIL"] = gt("Email from the token"); $aReplacement["FIRSTNAME"] = gt("First name from token"); $aReplacement["LASTNAME"] = gt("Last name from token"); $aReplacement["LANGUAGE"] = gt("language of token"); $aReplacement["OPTOUTURL"] = gt("URL for a respondent to opt-out of this survey"); $aReplacement["OPTINURL"] = gt("URL for a respondent to opt-in to this survey"); $aReplacement["SURVEYURL"] = gt("URL of the survey"); foreach ($aAttributes as $sAttribute => $aAttribute) { $aReplacement['' . strtoupper($sAttribute) . ''] = sprintf(gT("Token attribute: %s"), $aAttribute['description']); } break; case 'confirmation': $aReplacement["EMAIL"] = gt("Email from the token"); $aReplacement["FIRSTNAME"] = gt("First name from token"); $aReplacement["LASTNAME"] = gt("Last name from token"); $aReplacement["SURVEYURL"] = gt("URL of the survey"); foreach ($aAttributes as $sAttribute => $aAttribute) { $aReplacement['' . strtoupper($sAttribute) . ''] = sprintf(gT("Token attribute: %s"), $aAttribute['description']); } // $moveResult = LimeExpressionManager::NavigateForwards(); // Seems OK without, nut need $LEM::StartSurvey break; case 'admin_notification': case 'admin_detailed_notification': $aReplacement["RELOADURL"] = gT("Reload URL"); $aReplacement["VIEWRESPONSEURL"] = gT("View response URL"); $aReplacement["EDITRESPONSEURL"] = gT("Edit response URL"); $aReplacement["STATISTICSURL"] = gT("Statistics URL"); $aReplacement["ANSWERTABLE"] = gT("Answers from this response"); // $moveResult = LimeExpressionManager::NavigateForwards(); // Seems OK without, nut need $LEM::StartSurvey break; default: throw new CHttpException(400, gt('Invalid type.')); break; } $aData = array(); //$oSurveyLanguage=SurveyLanguageSetting::model()->find("surveyls_survey_id=:sid and surveyls_language=:language",array(":sid"=>$iSurveyId,":language"=>$sLang)); $aExpressions = array(); foreach ($aTypeAttributes[$sType] as $key => $aAttribute) { $sAttribute = $aAttribute['attribute']; // Email send do : templatereplace + ReplaceField to the Templatereplace done : we need 2 in one // $LEM::ProcessString($oSurveyLanguage->$sAttribute,null,$aReplacement,false,1,1,false,false,true); // This way : ProcessString don't replace coreReplacements $aExpressions[$key] = array('title' => $aAttribute['title'], 'expression' => $this->getHtmlExpression($aSurveyInfo[$sAttribute], $aReplacement, __METHOD__)); } $aData['aExpressions'] = $aExpressions; $this->getController()->layout = $this->layout; $this->getController()->pageTitle = sprintf(gt("Validate expression in email : %s"), $sType); $this->getController()->render("/admin/expressions/validationList", $aData); }
/** * Returns the full list of attribute token fields including the properties for each field * Use this instead of plain Survey::model()->findByPk($iSurveyID)->tokenAttributes calls because Survey::model()->findByPk($iSurveyID)->tokenAttributes may contain old descriptions where the fields does not physically exist * * @param integer $iSurveyID The Survey ID */ function GetParticipantAttributes($iSurveyID) { if (!tableExists("{{tokens_{$iSurveyID}}}") || !($table = Yii::app()->db->schema->getTable('{{tokens_' . $iSurveyID . '}}'))) { return array(); } return getTokenFieldsAndNames($iSurveyID, true); }
/** * Show printable survey */ function index($surveyid, $lang = null) { $surveyid = sanitize_int($surveyid); if (!Permission::model()->hasSurveyPermission($surveyid, 'surveycontent', 'read')) { $aData['surveyid'] = $surveyid; App()->getClientScript()->registerPackage('jquery-superfish'); $message['title'] = gT('Access denied!'); $message['message'] = gT('You do not have sufficient rights to access this page.'); $message['class'] = "error"; $this->_renderWrappedTemplate('survey', array("message" => $message), $aData); } else { $aSurveyInfo = getSurveyInfo($surveyid, $lang); if (!$aSurveyInfo) { $this->getController()->error('Invalid survey ID'); } SetSurveyLanguage($surveyid, $lang); $sLanguageCode = App()->language; $templatename = $aSurveyInfo['template']; $welcome = $aSurveyInfo['surveyls_welcometext']; $end = $aSurveyInfo['surveyls_endtext']; $surveyname = $aSurveyInfo['surveyls_title']; $surveydesc = $aSurveyInfo['surveyls_description']; $surveyactive = $aSurveyInfo['active']; $surveytable = "{{survey_" . $aSurveyInfo['sid'] . "}}"; $surveyexpirydate = $aSurveyInfo['expires']; $surveyfaxto = $aSurveyInfo['faxto']; $dateformattype = $aSurveyInfo['surveyls_dateformat']; Yii::app()->loadHelper('surveytranslator'); if (!is_null($surveyexpirydate)) { $dformat = getDateFormatData($dateformattype); $dformat = $dformat['phpdate']; $expirytimestamp = strtotime($surveyexpirydate); $expirytimeofday_h = date('H', $expirytimestamp); $expirytimeofday_m = date('i', $expirytimestamp); $surveyexpirydate = date($dformat, $expirytimestamp); if (!empty($expirytimeofday_h) || !empty($expirytimeofday_m)) { $surveyexpirydate .= ' – ' . $expirytimeofday_h . ':' . $expirytimeofday_m; } sprintf(gT("Please submit by %s"), $surveyexpirydate); } else { $surveyexpirydate = ''; } //Fix $templatename : control if print_survey.pstpl exist if (is_file(getTemplatePath($templatename) . DIRECTORY_SEPARATOR . 'print_survey.pstpl')) { $templatename = $templatename; // Change nothing } elseif (is_file(getTemplatePath(Yii::app()->getConfig("defaulttemplate")) . DIRECTORY_SEPARATOR . 'print_survey.pstpl')) { $templatename = Yii::app()->getConfig("defaulttemplate"); } else { $templatename = "default"; } $sFullTemplatePath = getTemplatePath($templatename) . DIRECTORY_SEPARATOR; $sFullTemplateUrl = getTemplateURL($templatename) . "/"; define('PRINT_TEMPLATE_DIR', $sFullTemplatePath, true); define('PRINT_TEMPLATE_URL', $sFullTemplateUrl, true); LimeExpressionManager::StartSurvey($surveyid, 'survey', NULL, false, LEM_PRETTY_PRINT_ALL_SYNTAX); $moveResult = LimeExpressionManager::NavigateForwards(); $condition = "sid = '{$surveyid}' AND language = '{$sLanguageCode}'"; $degresult = QuestionGroup::model()->getAllGroups($condition, array('group_order')); //xiao, if (!isset($surveyfaxto) || !$surveyfaxto and isset($surveyfaxnumber)) { $surveyfaxto = $surveyfaxnumber; //Use system fax number if none is set in survey. } $headelements = getPrintableHeader(); //if $showsgqacode is enabled at config.php show table name for reference $showsgqacode = Yii::app()->getConfig("showsgqacode"); if (isset($showsgqacode) && $showsgqacode == true) { $surveyname = $surveyname . "<br />[" . gT('Database') . " " . gT('table') . ": {$surveytable}]"; } else { $surveyname = $surveyname; } $survey_output = array('SITENAME' => Yii::app()->getConfig("sitename"), 'SURVEYNAME' => $surveyname, 'SURVEYDESCRIPTION' => $surveydesc, 'WELCOME' => $welcome, 'END' => $end, 'THEREAREXQUESTIONS' => 0, 'SUBMIT_TEXT' => gT("Submit Your Survey."), 'SUBMIT_BY' => $surveyexpirydate, 'THANKS' => gT("Thank you for completing this survey."), 'HEADELEMENTS' => $headelements, 'TEMPLATEURL' => PRINT_TEMPLATE_URL, 'FAXTO' => $surveyfaxto, 'PRIVACY' => '', 'GROUPS' => ''); $survey_output['FAX_TO'] = ''; if (!empty($surveyfaxto) && $surveyfaxto != '000-00000000') { $survey_output['FAX_TO'] = gT("Please fax your completed survey to:") . " {$surveyfaxto}"; } $total_questions = 0; $mapquestionsNumbers = array(); $answertext = ''; // otherwise can throw an error on line 1617 $fieldmap = createFieldMap($surveyid, 'full', false, false, $sLanguageCode); // ========================================================= // START doin the business: foreach ($degresult->readAll() as $degrow) { // --------------------------------------------------- // START doing groups $deqresult = Question::model()->getQuestions($surveyid, $degrow['gid'], $sLanguageCode, 0, '"I"'); $deqrows = array(); //Create an empty array in case FetchRow does not return any rows foreach ($deqresult->readAll() as $deqrow) { $deqrows[] = $deqrow; } // Get table output into array // Perform a case insensitive natural sort on group name then question title of a multidimensional array usort($deqrows, 'groupOrderThenQuestionOrder'); if ($degrow['description']) { $group_desc = $degrow['description']; } else { $group_desc = ''; } $group = array('GROUPNAME' => $degrow['group_name'], 'GROUPDESCRIPTION' => $group_desc, 'QUESTIONS' => ''); // A group can have only hidden questions. In that case you don't want to see the group's header/description either. $bGroupHasVisibleQuestions = false; $gid = $degrow['gid']; //Alternate bgcolor for different groups if (!isset($group['ODD_EVEN']) || $group['ODD_EVEN'] == ' g-row-even') { $group['ODD_EVEN'] = ' g-row-odd'; } else { $group['ODD_EVEN'] = ' g-row-even'; } //Loop through questions foreach ($deqrows as $deqrow) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // START doing questions $qidattributes = getQuestionAttributeValues($deqrow['qid'], $deqrow['type']); if ($qidattributes['hidden'] == 1 && $deqrow['type'] != '*') { continue; } $bGroupHasVisibleQuestions = true; //GET ANY CONDITIONS THAT APPLY TO THIS QUESTION $printablesurveyoutput = ''; $sExplanation = ''; //reset conditions explanation $s = 0; // TMSW Condition->Relevance: show relevance instead of this whole section to create $explanation $scenarioresult = Condition::model()->getScenarios($deqrow['qid']); $scenarioresult = $scenarioresult->readAll(); //Loop through distinct scenarios, thus grouping them together. foreach ($scenarioresult as $scenariorow) { if ($s == 0 && count($scenarioresult) > 1) { $sExplanation .= '<p class="scenario">' . " -------- Scenario {$scenariorow['scenario']} --------</p>\n\n"; } if ($s > 0) { $sExplanation .= '<p class="scenario">' . ' -------- ' . gT("or") . " Scenario {$scenariorow['scenario']} --------</p>\n\n"; } $x = 0; $conditions1 = "qid={$deqrow['qid']} AND scenario={$scenariorow['scenario']}"; $distinctresult = Condition::model()->getSomeConditions(array('cqid', 'method', 'cfieldname'), $conditions1, array('cqid'), array('cqid', 'method', 'cfieldname')); //Loop through each condition for a particular scenario. foreach ($distinctresult->readAll() as $distinctrow) { $condition = "qid = '{$distinctrow['cqid']}' AND parent_qid = 0 AND language = '{$sLanguageCode}'"; $subresult = Question::model()->find($condition); if ($x > 0) { $sExplanation .= ' <em class="scenario-and-separator">' . gT('and') . '</em> '; } if (trim($distinctrow['method']) == '') { $distinctrow['method'] = '=='; } if ($distinctrow['cqid']) { // cqid != 0 ==> previous answer match if ($distinctrow['method'] == '==') { $sExplanation .= gT("Answer was") . " "; } elseif ($distinctrow['method'] == '!=') { $sExplanation .= gT("Answer was NOT") . " "; } elseif ($distinctrow['method'] == '<') { $sExplanation .= gT("Answer was less than") . " "; } elseif ($distinctrow['method'] == '<=') { $sExplanation .= gT("Answer was less than or equal to") . " "; } elseif ($distinctrow['method'] == '>=') { $sExplanation .= gT("Answer was greater than or equal to") . " "; } elseif ($distinctrow['method'] == '>') { $sExplanation .= gT("Answer was greater than") . " "; } elseif ($distinctrow['method'] == 'RX') { $sExplanation .= gT("Answer matched (regexp)") . " "; } else { $sExplanation .= gT("Answer was") . " "; } } if (!$distinctrow['cqid']) { // cqid == 0 ==> token attribute match $tokenData = getTokenFieldsAndNames($surveyid); preg_match('/^{TOKEN:([^}]*)}$/', $distinctrow['cfieldname'], $extractedTokenAttr); $sExplanation .= "Your " . $tokenData[strtolower($extractedTokenAttr[1])]['description'] . " "; if ($distinctrow['method'] == '==') { $sExplanation .= gT("is") . " "; } elseif ($distinctrow['method'] == '!=') { $sExplanation .= gT("is NOT") . " "; } elseif ($distinctrow['method'] == '<') { $sExplanation .= gT("is less than") . " "; } elseif ($distinctrow['method'] == '<=') { $sExplanation .= gT("is less than or equal to") . " "; } elseif ($distinctrow['method'] == '>=') { $sExplanation .= gT("is greater than or equal to") . " "; } elseif ($distinctrow['method'] == '>') { $sExplanation .= gT("is greater than") . " "; } elseif ($distinctrow['method'] == 'RX') { $sExplanation .= gT("is matched (regexp)") . " "; } else { $sExplanation .= gT("is") . " "; } $answer_section = ' ' . $distinctrow['value'] . ' '; } $conresult = Condition::model()->getConditionsQuestions($distinctrow['cqid'], $deqrow['qid'], $scenariorow['scenario'], $sLanguageCode); $conditions = array(); foreach ($conresult->readAll() as $conrow) { $postans = ""; $value = $conrow['value']; switch ($conrow['type']) { case "Y": switch ($conrow['value']) { case "Y": $conditions[] = gT("Yes"); break; case "N": $conditions[] = gT("No"); break; } break; case "G": switch ($conrow['value']) { case "M": $conditions[] = gT("Male"); break; case "F": $conditions[] = gT("Female"); break; } // switch break; case "A": case "B": case ":": case ";": case "5": $conditions[] = $conrow['value']; break; case "C": switch ($conrow['value']) { case "Y": $conditions[] = gT("Yes"); break; case "U": $conditions[] = gT("Uncertain"); break; case "N": $conditions[] = gT("No"); break; } // switch break; case "E": switch ($conrow['value']) { case "I": $conditions[] = gT("Increase"); break; case "D": $conditions[] = gT("Decrease"); break; case "S": $conditions[] = gT("Same"); break; } case "1": $labelIndex = preg_match("/^[^#]+#([01]{1})\$/", $conrow['cfieldname']); if ($labelIndex == 0) { // TIBO $condition = "qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND scale_id=0 AND language='{$sLanguageCode}'"; $fresult = Answer::model()->getAllRecords($condition); foreach ($fresult->readAll() as $frow) { $postans = $frow['answer']; $conditions[] = $frow['answer']; } // while } elseif ($labelIndex == 1) { $condition = "qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND scale_id=1 AND language='{$sLanguageCode}'"; $fresult = Answer::model()->getAllRecords($condition); foreach ($fresult->readAll() as $frow) { $postans = $frow['answer']; $conditions[] = $frow['answer']; } // while } break; case "L": case "!": case "O": case "R": $condition = "qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND language='{$sLanguageCode}'"; $ansresult = Answer::model()->findAll($condition); foreach ($ansresult as $ansrow) { $conditions[] = $ansrow['answer']; } if ($conrow['value'] == "-oth-") { $conditions[] = gT("Other"); } $conditions = array_unique($conditions); break; case "M": case "P": $condition = " parent_qid='{$conrow['cqid']}' AND title='{$conrow['value']}' AND language='{$sLanguageCode}'"; $ansresult = Question::model()->findAll($condition); foreach ($ansresult as $ansrow) { $conditions[] = $ansrow['question']; } $conditions = array_unique($conditions); break; case "N": case "K": $conditions[] = $value; break; case "F": case "H": default: $value = substr($conrow['cfieldname'], strpos($conrow['cfieldname'], "X" . $conrow['cqid']) + strlen("X" . $conrow['cqid']), strlen($conrow['cfieldname'])); $condition = " qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND language='{$sLanguageCode}'"; $fresult = Answer::model()->getAllRecords($condition); foreach ($fresult->readAll() as $frow) { $postans = $frow['answer']; $conditions[] = $frow['answer']; } // while break; } // switch // Now let's complete the answer text with the answer_section $answer_section = ""; switch ($conrow['type']) { case "A": case "B": case "C": case "E": case "F": case "H": case "K": $thiscquestion = $fieldmap[$conrow['cfieldname']]; $condition = "parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$sLanguageCode}'"; $ansresult = Question::model()->findAll($condition); foreach ($ansresult as $ansrow) { $answer_section = " (" . $ansrow['question'] . ")"; } break; case "1": // dual: (Label 1), (Label 2) $labelIndex = substr($conrow['cfieldname'], -1); $thiscquestion = $fieldmap[$conrow['cfieldname']]; $condition = "parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$sLanguageCode}'"; $ansresult = Question::model()->findAll($condition); $cqidattributes = getQuestionAttributeValues($conrow['cqid']); if ($labelIndex == 0) { if (trim($cqidattributes['dualscale_headerA'][$sLanguageCode]) != '') { $header = gT($cqidattributes['dualscale_headerA'][$sLanguageCode]); } else { $header = '1'; } } elseif ($labelIndex == 1) { if (trim($cqidattributes['dualscale_headerB'][$sLanguageCode]) != '') { $header = gT($cqidattributes['dualscale_headerB'][$sLanguageCode]); } else { $header = '2'; } } foreach ($ansresult as $ansrow) { $answer_section = " (" . $ansrow->question . " " . sprintf(gT("Label %s"), $header) . ")"; } break; case ":": case ";": //multi flexi: ( answer [label] ) $thiscquestion = $fieldmap[$conrow['cfieldname']]; $condition = "parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$sLanguageCode}'"; $ansresult = Question::model()->findAll($condition); foreach ($ansresult as $ansrow) { $condition = "qid = '{$conrow['cqid']}' AND code = '{$conrow['value']}' AND language= '{$sLanguageCode}'"; $fresult = Answer::model()->findAll($condition); foreach ($fresult as $frow) { //$conditions[]=$frow['title']; $answer_section = " (" . $ansrow->question . "[" . $frow['answer'] . "])"; } // while } break; case "R": // (Rank 1), (Rank 2)... TIBO $thiscquestion = $fieldmap[$conrow['cfieldname']]; $rankid = $thiscquestion['aid']; $answer_section = " (" . gT("RANK") . " {$rankid})"; break; default: // nothing to add break; } } if (count($conditions) > 1) { $sExplanation .= "'" . implode("' <em class='scenario-or-separator'>" . gT("or") . "</em> '", $conditions) . "'"; } elseif (count($conditions) == 1) { $sExplanation .= "'" . $conditions[0] . "'"; } unset($conditions); // Following line commented out because answer_section was lost, but is required for some question types //$explanation .= " ".gT("to question")." '".$mapquestionsNumbers[$distinctrow['cqid']]."' $answer_section "; if ($distinctrow['cqid']) { $sExplanation .= " <span class='scenario-at-separator'>" . gT("at question") . "</span> '" . $mapquestionsNumbers[$distinctrow['cqid']] . " [" . $subresult['title'] . "]' (" . strip_tags($subresult['question']) . "{$answer_section})"; } else { $sExplanation .= " " . $distinctrow['value']; } //$distinctrow $x++; } $s++; } $qinfo = LimeExpressionManager::GetQuestionStatus($deqrow['qid']); $relevance = trim($qinfo['info']['relevance']); $sEquation = $qinfo['relEqn']; if (trim($relevance) != '' && trim($relevance) != '1') { if (isset($qidattributes['printable_help'][$sLanguageCode]) && $qidattributes['printable_help'][$sLanguageCode] != '') { $sExplanation = $qidattributes['printable_help'][$sLanguageCode]; } elseif ($sExplanation == '') { $sExplanation = $sEquation; $sEquation = ' '; // No need to show it twice } $sExplanation = "<b>" . gT('Only answer this question if the following conditions are met:') . "</b><br/> " . $sExplanation; if (Yii::app()->getConfig('showrelevance')) { $sExplanation .= "<span class='printable_equation'><br>" . $sEquation . "</span>"; } } else { $sExplanation = ''; } ++$total_questions; //TIBO map question qid to their q number $mapquestionsNumbers[$deqrow['qid']] = $total_questions; //END OF GETTING CONDITIONS $qid = $deqrow['qid']; $fieldname = "{$surveyid}" . "X" . "{$gid}" . "X" . "{$qid}"; if (isset($showsgqacode) && $showsgqacode == true) { $deqrow['question'] = $deqrow['question'] . "<br />" . gT("ID:") . " {$fieldname} <br />" . gT("Question code:") . " " . $deqrow['title']; } $question = array('QUESTION_NUMBER' => $total_questions, 'QUESTION_CODE' => $deqrow['title'], 'QUESTION_TEXT' => preg_replace('/(?:<br ?\\/?>|<\\/(?:p|h[1-6])>)$/is', '', $deqrow['question']), 'QUESTION_SCENARIO' => $sExplanation, 'QUESTION_MANDATORY' => '', 'QUESTION_ID' => $deqrow['qid'], 'QUESTION_CLASS' => getQuestionClass($deqrow['type']), 'QUESTION_TYPE_HELP' => $qinfo['validTip'], 'QUESTION_MAN_MESSAGE' => '', 'QUESTION_VALID_MESSAGE' => '', 'QUESTION_FILE_VALID_MESSAGE' => '', 'QUESTIONHELP' => '', 'ANSWER' => ''); $showqnumcode = Yii::app()->getConfig('showqnumcode'); if ($showqnumcode == 'choose' && ($aSurveyInfo['showqnumcode'] == 'N' || $aSurveyInfo['showqnumcode'] == 'X') || $showqnumcode == 'number' || $showqnumcode == 'none') { $question['QUESTION_CODE'] = ''; } if ($showqnumcode == 'choose' && ($aSurveyInfo['showqnumcode'] == 'C' || $aSurveyInfo['showqnumcode'] == 'X') || $showqnumcode == 'code' || $showqnumcode == 'none') { $question['QUESTION_NUMBER'] = ''; } if ($question['QUESTION_TYPE_HELP'] != "") { $question['QUESTION_TYPE_HELP'] .= "<br />\n"; } if ($deqrow['mandatory'] == 'Y') { $question['QUESTION_MANDATORY'] = gT('*'); $question['QUESTION_CLASS'] .= ' mandatory'; } //DIFFERENT TYPES OF DATA FIELD HERE if ($deqrow['help']) { $question['QUESTIONHELP'] = $deqrow['help']; } if (!empty($qidattributes['page_break'])) { $question['QUESTION_CLASS'] .= ' breakbefore '; } if (isset($qidattributes['maximum_chars']) && $qidattributes['maximum_chars'] != '') { $question['QUESTION_CLASS'] = "max-chars-{$qidattributes['maximum_chars']} " . $question['QUESTION_CLASS']; } switch ($deqrow['type']) { // ================================================================== case "5": //5 POINT CHOICE $question['QUESTION_TYPE_HELP'] .= gT('Please choose *only one* of the following:'); $question['ANSWER'] .= "\n\t<ul>\n"; for ($i = 1; $i <= 5; $i++) { $question['ANSWER'] .= "\t\t<li>\n\t\t\t" . self::_input_type_image('radio', $i) . "\n\t\t\t{$i} " . self::_addsgqacode("({$i})") . "\n\t\t</li>\n"; } $question['ANSWER'] .= "\t</ul>\n"; break; // ================================================================== // ================================================================== case "D": //DATE $question['QUESTION_TYPE_HELP'] .= gT('Please enter a date:'); $question['ANSWER'] .= "\t" . self::_input_type_image('text', $question['QUESTION_TYPE_HELP'], 30, 1); break; // ================================================================== // ================================================================== case "G": //GENDER $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:"); $question['ANSWER'] .= "\n\t<ul>\n"; $question['ANSWER'] .= "\t\t<li>\n\t\t\t" . self::_input_type_image('radio', gT("Female")) . "\n\t\t\t" . gT("Female") . " " . self::_addsgqacode("(F)") . "\n\t\t</li>\n"; $question['ANSWER'] .= "\t\t<li>\n\t\t\t" . self::_input_type_image('radio', gT("Male")) . "\n\t\t\t" . gT("Male") . " " . self::_addsgqacode("(M)") . "\n\t\t</li>\n"; $question['ANSWER'] .= "\t</ul>\n"; break; // ================================================================== // ================================================================== case "L": //LIST drop-down/radio-button list // ================================================================== //LIST drop-down/radio-button list // ================================================================== case "!": //List - dropdown if (isset($qidattributes['display_columns']) && trim($qidattributes['display_columns']) != '') { $dcols = $qidattributes['display_columns']; } else { $dcols = 0; } if (isset($qidattributes['category_separator']) && trim($qidattributes['category_separator']) != '') { $optCategorySeparator = $qidattributes['category_separator']; } else { unset($optCategorySeparator); } $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $dearesult = Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' ", array('sortorder', 'answer')); $dearesult = $dearesult->readAll(); $deacount = count($dearesult); if ($deqrow['other'] == "Y") { $deacount++; } $wrapper = setupColumns(0, $deacount); $question['ANSWER'] = $wrapper['whole-start']; $rowcounter = 0; $colcounter = 1; foreach ($dearesult as $dearow) { if (isset($optCategorySeparator)) { list($category, $answer) = explode($optCategorySeparator, $dearow['answer']); if ($category != '') { $dearow['answer'] = "({$category}) {$answer} " . self::_addsgqacode("(" . $dearow['code'] . ")"); } else { $dearow['answer'] = $answer . self::_addsgqacode(" (" . $dearow['code'] . ")"); } $question['ANSWER'] .= "\t" . $wrapper['item-start'] . "\t\t" . self::_input_type_image('radio', $dearow['answer']) . "\n\t\t\t" . $dearow['answer'] . "\n" . $wrapper['item-end']; } else { $question['ANSWER'] .= "\t" . $wrapper['item-start'] . "\t\t" . self::_input_type_image('radio', $dearow['answer']) . "\n\t\t\t" . $dearow['answer'] . self::_addsgqacode(" (" . $dearow['code'] . ")") . "\n" . $wrapper['item-end']; } ++$rowcounter; if ($rowcounter == $wrapper['maxrows'] && $colcounter < $wrapper['cols']) { if ($colcounter == $wrapper['cols'] - 1) { $question['ANSWER'] .= $wrapper['col-devide-last']; } else { $question['ANSWER'] .= $wrapper['col-devide']; } $rowcounter = 0; ++$colcounter; } } if ($deqrow['other'] == 'Y') { if (trim($qidattributes["other_replace_text"][$sLanguageCode]) == '') { $qidattributes["other_replace_text"][$sLanguageCode] = gT("Other"); } // $printablesurveyoutput .="\t".$wrapper['item-start']."\t\t".self::_input_type_image('radio' , gT("Other"))."\n\t\t\t".gT("Other")."\n\t\t\t<input type='text' size='30' readonly='readonly' />\n".$wrapper['item-end']; $question['ANSWER'] .= $wrapper['item-start-other'] . self::_input_type_image('radio', gT($qidattributes["other_replace_text"][$sLanguageCode])) . ' ' . gT($qidattributes["other_replace_text"][$sLanguageCode]) . self::_addsgqacode(" (-oth-)") . "\n\t\t\t" . self::_input_type_image('other') . self::_addsgqacode(" (" . $deqrow['sid'] . "X" . $deqrow['gid'] . "X" . $deqrow['qid'] . "other)") . "\n" . $wrapper['item-end']; } $question['ANSWER'] .= $wrapper['whole-end']; //Let's break the presentation into columns. break; // ================================================================== // ================================================================== case "O": //LIST WITH COMMENT $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:"); $dearesult = Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$sLanguageCode}'", array('sortorder', 'answer')); $question['ANSWER'] = "\t<ul>\n"; foreach ($dearesult->readAll() as $dearow) { $question['ANSWER'] .= "\t\t<li>\n\t\t\t" . self::_input_type_image('radio', $dearow['answer']) . "\n\t\t\t" . $dearow['answer'] . self::_addsgqacode(" (" . $dearow['code'] . ")") . "\n\t\t</li>\n"; } $question['ANSWER'] .= "\t</ul>\n"; $question['ANSWER'] .= "\t<p class=\"comment\">\n\t\t" . gT("Make a comment on your choice here:") . "\n"; $question['ANSWER'] .= "\t\t" . self::_input_type_image('textarea', gT("Make a comment on your choice here:"), 50, 8) . self::_addsgqacode(" (" . $deqrow['sid'] . "X" . $deqrow['gid'] . "X" . $deqrow['qid'] . "comment)") . "\n\t</p>\n"; break; // ================================================================== // ================================================================== case "R": //RANKING Type Question $rearesult = Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$sLanguageCode}'", array('sortorder', 'answer')); $rearesult = $rearesult->readAll(); $reacount = count($rearesult); $question['QUESTION_TYPE_HELP'] .= gT("Please number each box in order of preference from 1 to") . " {$reacount}"; $question['QUESTION_TYPE_HELP'] .= self::_min_max_answers_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] = "\n<ul>\n"; foreach ($rearesult as $rearow) { $question['ANSWER'] .= "\t<li>\n\t" . self::_input_type_image('rank', '', 4, 1) . "\n\t\t " . $rearow['answer'] . self::_addsgqacode(" (" . $fieldname . $rearow['code'] . ")") . "\n\t</li>\n"; } $question['ANSWER'] .= "\n</ul>\n"; break; // ================================================================== // ================================================================== case "M": //Multiple choice (Quite tricky really!) if (trim($qidattributes['display_columns']) != '') { $dcols = $qidattributes['display_columns']; } else { $dcols = 0; } $question['QUESTION_TYPE_HELP'] .= gT("Please choose *all* that apply:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' ", array('question_order')); $mearesult = $mearesult->readAll(); $meacount = count($mearesult); if ($deqrow['other'] == 'Y') { $meacount++; } $wrapper = setupColumns($dcols, $meacount); $question['ANSWER'] = $wrapper['whole-start']; $rowcounter = 0; $colcounter = 1; foreach ($mearesult as $mearow) { $question['ANSWER'] .= $wrapper['item-start'] . self::_input_type_image('checkbox', $mearow['question']) . "\n\t\t" . $mearow['question'] . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ") ") . $wrapper['item-end']; ++$rowcounter; if ($rowcounter == $wrapper['maxrows'] && $colcounter < $wrapper['cols']) { if ($colcounter == $wrapper['cols'] - 1) { $question['ANSWER'] .= $wrapper['col-devide-last']; } else { $question['ANSWER'] .= $wrapper['col-devide']; } $rowcounter = 0; ++$colcounter; } } if ($deqrow['other'] == "Y") { if (trim($qidattributes['other_replace_text'][$sLanguageCode]) == '') { $qidattributes["other_replace_text"][$sLanguageCode] = "Other"; } if (!isset($mearow['answer'])) { $mearow['answer'] = ""; } $question['ANSWER'] .= $wrapper['item-start-other'] . self::_input_type_image('checkbox', $mearow['answer']) . gT($qidattributes["other_replace_text"][$sLanguageCode]) . ":\n\t\t" . self::_input_type_image('other') . self::_addsgqacode(" (" . $fieldname . "other) ") . $wrapper['item-end']; } $question['ANSWER'] .= $wrapper['whole-end']; // } break; // ================================================================== // ================================================================== case "P": //Multiple choice with comments $question['QUESTION_TYPE_HELP'] .= gT("Please choose all that apply and provide a comment:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $mearesult = Question::model()->getAllRecords("parent_qid='{$deqrow['qid']}' AND language='{$sLanguageCode}'", array('question_order')); // $printablesurveyoutput .="\t\t\t<u>".gT("Please choose all that apply and provide a comment:")."</u><br />\n"; $j = 0; $longest_string = 0; foreach ($mearesult->readAll() as $mearow) { $longest_string = longestString($mearow['question'], $longest_string); $question['ANSWER'] .= "\t<li><span>\n\t\t" . self::_input_type_image('checkbox', $mearow['question']) . $mearow['question'] . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ") ") . "</span>\n\t\t" . self::_input_type_image('text', 'comment box', 60) . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . "comment) ") . "\n\t</li>\n"; $j++; } if ($deqrow['other'] == "Y") { $question['ANSWER'] .= "\t<li class=\"other\">\n\t\t<div class=\"other-replacetext\">" . gT('Other:') . self::_input_type_image('other', '', 1) . "</div>" . self::_input_type_image('othercomment', 'comment box', 50) . self::_addsgqacode(" (" . $fieldname . "other) ") . "\n\t</li>\n"; $j++; } $question['ANSWER'] = "\n<ul>\n" . $question['ANSWER'] . "</ul>\n"; break; // ================================================================== // ================================================================== case "Q": //MULTIPLE SHORT TEXT $width = 60; // ================================================================== // ================================================================== case "K": //MULTIPLE NUMERICAL $question['QUESTION_TYPE_HELP'] = ""; $width = isset($width) ? $width : 16; // if (!empty($qidattributes['equals_num_value'])) // { // $question['QUESTION_TYPE_HELP'] .= "* ".sprintf(gT('Total of all entries must equal %d'),$qidattributes['equals_num_value'])."<br />\n"; // } // if (!empty($qidattributes['max_num_value'])) // { // $question['QUESTION_TYPE_HELP'] .= sprintf(gT('Total of all entries must not exceed %d'), $qidattributes['max_num_value'])."<br />\n"; // } // if (!empty($qidattributes['min_num_value'])) // { // $question['QUESTION_TYPE_HELP'] .= sprintf(gT('Total of all entries must be at least %s'),$qidattributes['min_num_value'])."<br />\n"; // } $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer(s) here:"); $longest_string = 0; $mearesult = Question::model()->getAllRecords("parent_qid='{$deqrow['qid']}' AND language='{$sLanguageCode}'", array('question_order')); foreach ($mearesult->readAll() as $mearow) { $longest_string = longestString($mearow['question'], $longest_string); if (isset($qidattributes['slider_layout']) && $qidattributes['slider_layout'] == 1) { $mearow['question'] = explode(':', $mearow['question']); $mearow['question'] = $mearow['question'][0]; } $question['ANSWER'] .= "\t<li>\n\t\t<span>" . $mearow['question'] . "</span>\n\t\t" . self::_input_type_image('text', $mearow['question'], $width) . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ") ") . "\n\t</li>\n"; } $question['ANSWER'] = "\n<ul>\n" . $question['ANSWER'] . "</ul>\n"; break; // ================================================================== // ================================================================== case "S": //SHORT TEXT $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:"); $question['ANSWER'] = self::_input_type_image('text', $question['QUESTION_TYPE_HELP'], 50); break; // ================================================================== // ================================================================== case "T": //LONG TEXT $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:"); $question['ANSWER'] = self::_input_type_image('textarea', $question['QUESTION_TYPE_HELP'], '100%', 8); break; // ================================================================== // ================================================================== case "U": //HUGE TEXT $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:"); $question['ANSWER'] = self::_input_type_image('textarea', $question['QUESTION_TYPE_HELP'], '100%', 30); break; // ================================================================== // ================================================================== case "N": //NUMERICAL $prefix = ""; $suffix = ""; if ($qidattributes['prefix'][$sLanguageCode] != "") { $prefix = $qidattributes['prefix'][$sLanguageCode]; } if ($qidattributes['suffix'][$sLanguageCode] != "") { $suffix = $qidattributes['suffix'][$sLanguageCode]; } $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:"); $question['ANSWER'] = "<ul>\n\t<li>\n\t\t<span>{$prefix}</span>\n\t\t" . self::_input_type_image('text', $question['QUESTION_TYPE_HELP'], 20) . "\n\t\t<span>{$suffix}</span>\n\t\t</li>\n\t</ul>"; break; // ================================================================== // ================================================================== case "Y": //YES/NO $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:"); $question['ANSWER'] = "\n<ul>\n\t<li>\n\t\t" . self::_input_type_image('radio', gT('Yes')) . "\n\t\t" . gT('Yes') . self::_addsgqacode(" (Y)") . "\n\t</li>\n"; $question['ANSWER'] .= "\n\t<li>\n\t\t" . self::_input_type_image('radio', gT('No')) . "\n\t\t" . gT('No') . self::_addsgqacode(" (N)") . "\n\t</li>\n</ul>\n"; break; // ================================================================== // ================================================================== case "A": //ARRAY (5 POINT CHOICE) $condition = "parent_qid = '{$deqrow['qid']}' AND language= '{$sLanguageCode}'"; $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] = "\n <table>\n <thead>\n <tr>\n <td> </td>\n <th style='font-family:Arial,helvetica,sans-serif;font-weight:normal;'>1 " . self::_addsgqacode(" (1)") . "</th>\n <th style='font-family:Arial,helvetica,sans-serif;font-weight:normal;'>2 " . self::_addsgqacode(" (2)") . "</th>\n <th style='font-family:Arial,helvetica,sans-serif;font-weight:normal;'>3 " . self::_addsgqacode(" (3)") . "</th>\n <th style='font-family:Arial,helvetica,sans-serif;font-weight:normal;'>4 " . self::_addsgqacode(" (4)") . "</th>\n <th style='font-family:Arial,helvetica,sans-serif;font-weight:normal;'>5" . self::_addsgqacode(" (5)") . "</th>\n </tr>\n </thead>\n <tbody>"; $j = 0; $rowclass = 'array1'; $mearesult = Question::model()->getAllRecords($condition, array('question_order')); foreach ($mearesult->readAll() as $mearow) { $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n"; $rowclass = alternation($rowclass, 'row'); //semantic differential question type? if (strpos($mearow['question'], '|')) { $answertext = substr($mearow['question'], 0, strpos($mearow['question'], '|')) . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ")") . " "; } else { $answertext = $mearow['question'] . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ")"); } $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$answertext}</th>\n"; for ($i = 1; $i <= 5; $i++) { $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', $i) . "</td>\n"; } $answertext .= $mearow['question']; //semantic differential question type? if (strpos($mearow['question'], '|')) { $answertext2 = substr($mearow['question'], strpos($mearow['question'], '|') + 1); $question['ANSWER'] .= "\t\t\t<th class=\"answertextright\">{$answertext2}</td>\n"; } $question['ANSWER'] .= "\t\t</tr>\n"; $j++; } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; // ================================================================== // ================================================================== case "B": //ARRAY (10 POINT CHOICE) $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td> </td>\n"; for ($i = 1; $i <= 10; $i++) { $question['ANSWER'] .= "\t\t\t<th>{$i}" . self::_addsgqacode(" ({$i})") . "</th>\n"; } $question['ANSWER'] .= "\t</thead>\n\n\t<tbody>\n"; $j = 0; $rowclass = 'array1'; $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' ", array('question_order')); foreach ($mearesult->readAll() as $mearow) { $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n\t\t\t<th class=\"answertext\">{$mearow['question']}" . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ")") . "</th>\n"; $rowclass = alternation($rowclass, 'row'); for ($i = 1; $i <= 10; $i++) { $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', $i) . "</td>\n"; } $question['ANSWER'] .= "\t\t</tr>\n"; $j++; } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; // ================================================================== // ================================================================== case "C": //ARRAY (YES/UNCERTAIN/NO) $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] = ' <table> <thead> <tr> <td> </td> <th>' . gT("Yes") . self::_addsgqacode(" (Y)") . '</th> <th>' . gT("Uncertain") . self::_addsgqacode(" (U)") . '</th> <th>' . gT("No") . self::_addsgqacode(" (N)") . '</th> </tr> </thead> <tbody> '; $j = 0; $rowclass = 'array1'; $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' ", array('question_order')); foreach ($mearesult->readAll() as $mearow) { $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n"; $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$mearow['question']}" . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ")") . "</th>\n"; $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', gT("Yes")) . "</td>\n"; $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', gT("Uncertain")) . "</td>\n"; $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', gT("No")) . "</td>\n"; $question['ANSWER'] .= "\t\t</tr>\n"; $j++; $rowclass = alternation($rowclass, 'row'); } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; case "E": //ARRAY (Increase/Same/Decrease) $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] = ' <table> <thead> <tr> <td> </td> <th>' . gT("Increase") . self::_addsgqacode(" (I)") . '</th> <th>' . gT("Same") . self::_addsgqacode(" (S)") . '</th> <th>' . gT("Decrease") . self::_addsgqacode(" (D)") . '</th> </tr> </thead> <tbody> '; $j = 0; $rowclass = 'array1'; $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' ", array('question_order')); foreach ($mearesult->readAll() as $mearow) { $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n"; $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$mearow['question']}" . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ")") . "</th>\n"; $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', gT("Increase")) . "</td>\n"; $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', gT("Same")) . "</td>\n"; $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio', gT("Decrease")) . "</td>\n"; $question['ANSWER'] .= "\t\t</tr>\n"; $j++; $rowclass = alternation($rowclass, 'row'); } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; // ================================================================== // ================================================================== case ":": //ARRAY (Multi Flexible) (Numbers) $headstyle = "style='padding-left: 20px; padding-right: 7px'"; if (trim($qidattributes['multiflexible_max']) != '' && trim($qidattributes['multiflexible_min']) == '') { $maxvalue = $qidattributes['multiflexible_max']; $minvalue = 1; } if (trim($qidattributes['multiflexible_min']) != '' && trim($qidattributes['multiflexible_max']) == '') { $minvalue = $qidattributes['multiflexible_min']; $maxvalue = $qidattributes['multiflexible_min'] + 10; } if (trim($qidattributes['multiflexible_min']) == '' && trim($qidattributes['multiflexible_max']) == '') { $minvalue = 1; $maxvalue = 10; } if (trim($qidattributes['multiflexible_min']) != '' && trim($qidattributes['multiflexible_max']) != '') { if ($qidattributes['multiflexible_min'] < $qidattributes['multiflexible_max']) { $minvalue = $qidattributes['multiflexible_min']; $maxvalue = $qidattributes['multiflexible_max']; } } if (trim($qidattributes['multiflexible_step']) != '') { $stepvalue = $qidattributes['multiflexible_step']; } else { $stepvalue = 1; } if ($qidattributes['multiflexible_checkbox'] != 0) { $checkboxlayout = true; } else { $checkboxlayout = false; } $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td> </td>\n"; $fresult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' and scale_id=1 AND language='{$sLanguageCode}' ", array('question_order')); $fresult = $fresult->readAll(); $fcount = count($fresult); $fwidth = "120"; $i = 0; //array to temporary store X axis question codes $xaxisarray = array(); foreach ($fresult as $frow) { $question['ANSWER'] .= "\t\t\t<th>{$frow['question']}</th>\n"; $i++; //add current question code $xaxisarray[$i] = $frow['title']; } $question['ANSWER'] .= "\t\t</tr>\n\t</thead>\n\n\t<tbody>\n"; $a = 1; //Counter for pdfoutput $rowclass = 'array1'; $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' and scale_id=0 AND language='{$sLanguageCode}' ", array('question_order')); $result = $mearesult->readAll(); foreach ($result as $frow) { $question['ANSWER'] .= "\t<tr class=\"{$rowclass}\">\n"; $rowclass = alternation($rowclass, 'row'); $answertext = $frow['question']; if (strpos($answertext, '|')) { $answertext = substr($answertext, 0, strpos($answertext, '|')); } $question['ANSWER'] .= "\t\t\t\t\t<th class=\"answertext\">{$answertext}</th>\n"; //$printablesurveyoutput .="\t\t\t\t\t<td>"; for ($i = 1; $i <= $fcount; $i++) { $question['ANSWER'] .= "\t\t\t<td>\n"; if ($checkboxlayout === false) { $question['ANSWER'] .= "\t\t\t\t" . self::_input_type_image('text', '', 4) . self::_addsgqacode(" (" . $fieldname . $frow['title'] . "_" . $xaxisarray[$i] . ") ") . "\n"; } else { $question['ANSWER'] .= "\t\t\t\t" . self::_input_type_image('checkbox') . self::_addsgqacode(" (" . $fieldname . $frow['title'] . "_" . $xaxisarray[$i] . ") ") . "\n"; } $question['ANSWER'] .= "\t\t\t</td>\n"; } $answertext = $frow['question']; if (strpos($answertext, '|')) { $answertext = substr($answertext, strpos($answertext, '|') + 1); $question['ANSWER'] .= "\t\t\t<th class=\"answertextright\">{$answertext}</th>\n"; } $question['ANSWER'] .= "\t\t</tr>\n"; $a++; } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; // ================================================================== // ================================================================== case ";": //ARRAY (Multi Flexible) (text) $headstyle = "style='padding-left: 20px; padding-right: 7px'"; $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND scale_id=0 AND language='{$sLanguageCode}' ", array('question_order')); $mearesult = $mearesult->readAll(); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td> </td>\n"; $fresult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND scale_id=1 AND language='{$sLanguageCode}' ", array('question_order')); $fresult = $fresult->readAll(); $fcount = count($fresult); $fwidth = "120"; $i = 0; //array to temporary store X axis question codes $xaxisarray = array(); foreach ($fresult as $frow) { $question['ANSWER'] .= "\t\t\t<th>{$frow['question']}</th>\n"; $i++; //add current question code $xaxisarray[$i] = $frow['title']; } $question['ANSWER'] .= "\t\t</tr>\n\t</thead>\n\n<tbody>\n"; $a = 1; $rowclass = 'array1'; foreach ($mearesult as $mearow) { $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n"; $rowclass = alternation($rowclass, 'row'); $answertext = $mearow['question']; if (strpos($answertext, '|')) { $answertext = substr($answertext, 0, strpos($answertext, '|')); } $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$answertext}</th>\n"; for ($i = 1; $i <= $fcount; $i++) { $question['ANSWER'] .= "\t\t\t<td>\n"; $question['ANSWER'] .= "\t\t\t\t" . self::_input_type_image('text', '', 23) . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . "_" . $xaxisarray[$i] . ") ") . "\n"; $question['ANSWER'] .= "\t\t\t</td>\n"; } $answertext = $mearow['question']; if (strpos($answertext, '|')) { $answertext = substr($answertext, strpos($answertext, '|') + 1); $question['ANSWER'] .= "\t\t\t\t<th class=\"answertextright\">{$answertext}</th>\n"; } $question['ANSWER'] .= "\t\t</tr>\n"; $a++; } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; // ================================================================== // ================================================================== case "F": //ARRAY (Flexible Labels) $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $fresult = Answer::model()->getAllRecords(" scale_id=0 AND qid='{$deqrow['qid']}' AND language='{$sLanguageCode}'", array('sortorder', 'code')); $fresult = $fresult->readAll(); $fcount = count($fresult); $fwidth = "120"; $i = 1; $column_headings = array(); foreach ($fresult as $frow) { $column_headings[] = $frow['answer'] . self::_addsgqacode(" (" . $frow['code'] . ")"); } if (trim($qidattributes['answer_width']) != '') { $iAnswerWidth = 100 - $qidattributes['answer_width']; } else { $iAnswerWidth = 80; } if (count($column_headings) > 0) { $col_width = round($iAnswerWidth / count($column_headings)); } else { $heading = ''; } $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n"; $question['ANSWER'] .= "\t\t\t<td> </td>\n"; foreach ($column_headings as $heading) { $question['ANSWER'] .= "\t\t\t<th style=\"width:{$col_width}%;\">{$heading}</th>\n"; } $i++; $question['ANSWER'] .= "\t\t</tr>\n\t</thead>\n\n\t<tbody>\n"; $counter = 1; $rowclass = 'array1'; $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' ", array('question_order')); foreach ($mearesult->readAll() as $mearow) { $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n"; $rowclass = alternation($rowclass, 'row'); if (trim($answertext) == '') { $answertext = ' '; } //semantic differential question type? if (strpos($mearow['question'], '|')) { $answertext = substr($mearow['question'], 0, strpos($mearow['question'], '|')) . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ")") . " "; } else { $answertext = $mearow['question'] . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . ")"); } if (trim($qidattributes['answer_width']) != '') { $sInsertStyle = ' style="width:' . $qidattributes['answer_width'] . '%" '; } else { $sInsertStyle = ''; } $question['ANSWER'] .= "\t\t\t<th {$sInsertStyle} class=\"answertext\">{$answertext}</th>\n"; for ($i = 1; $i <= $fcount; $i++) { $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio') . "</td>\n"; } $counter++; $answertext = $mearow['question']; //semantic differential question type? if (strpos($mearow['question'], '|')) { $answertext2 = substr($mearow['question'], strpos($mearow['question'], '|') + 1); $question['ANSWER'] .= "\t\t\t<th class=\"answertextright\">{$answertext2}</th>\n"; } $question['ANSWER'] .= "\t\t</tr>\n"; } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; // ================================================================== // ================================================================== case "1": //ARRAY (Flexible Labels) multi scale $leftheader = $qidattributes['dualscale_headerA'][$sLanguageCode]; $rightheader = $qidattributes['dualscale_headerB'][$sLanguageCode]; $headstyle = 'style="padding-left: 20px; padding-right: 7px"'; $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $sLanguageCode, $surveyid); $question['ANSWER'] .= "\n<table>\n\t<thead>\n"; $condition = "qid= '{$deqrow['qid']}' AND language= '{$sLanguageCode}' AND scale_id=0"; $fresult = Answer::model()->getAllRecords($condition, array('sortorder', 'code')); $fresult = $fresult->readAll(); $fcount = count($fresult); $fwidth = "120"; $l1 = 0; $printablesurveyoutput2 = "\t\t\t<td> </td>\n"; $myheader2 = ''; foreach ($fresult as $frow) { $printablesurveyoutput2 .= "\t\t\t<th>{$frow['answer']}" . self::_addsgqacode(" (" . $frow['code'] . ")") . "</th>\n"; $myheader2 .= "<td></td>"; $l1++; } // second scale $printablesurveyoutput2 .= "\t\t\t<td> </td>\n"; //$fquery1 = "SELECT * FROM {{answers}} WHERE qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' AND scale_id=1 ORDER BY sortorder, code"; // $fresult1 = Yii::app()->db->createCommand($fquery1)->query(); $fresult1 = Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$sLanguageCode}' AND scale_id=1 ", array('sortorder', 'code')); $fresult1 = $fresult1->readAll(); $fcount1 = count($fresult1); $fwidth = "120"; $l2 = 0; //array to temporary store second scale question codes $scale2array = array(); foreach ($fresult1 as $frow1) { $printablesurveyoutput2 .= "\t\t\t<th>{$frow1['answer']}" . self::_addsgqacode(" (" . $frow1['code'] . ")") . "</th>\n"; //add current question code $scale2array[$l2] = $frow1['code']; $l2++; } // build header if needed if ($leftheader != '' || $rightheader != '') { $myheader = "\t\t\t<td> </td>"; $myheader .= "\t\t\t<th colspan=\"" . $l1 . "\">{$leftheader}</th>\n"; if ($rightheader != '') { // $myheader .= "\t\t\t\t\t" .$myheader2; $myheader .= "\t\t\t<td> </td>"; $myheader .= "\t\t\t<th colspan=\"" . $l2 . "\">{$rightheader}</td>\n"; } $myheader .= "\t\t\t\t</tr>\n"; } else { $myheader = ''; } $question['ANSWER'] .= $myheader . "\t\t</tr>\n\n\t\t<tr>\n"; $question['ANSWER'] .= $printablesurveyoutput2; $question['ANSWER'] .= "\t\t</tr>\n\t</thead>\n\n\t<tbody>\n"; $rowclass = 'array1'; //counter for each subquestion $sqcounter = 0; $mearesult = Question::model()->getAllRecords(" parent_qid={$deqrow['qid']} AND language='{$sLanguageCode}' ", array('question_order')); foreach ($mearesult->readAll() as $mearow) { $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n"; $rowclass = alternation($rowclass, 'row'); $answertext = $mearow['question'] . self::_addsgqacode(" (" . $fieldname . $mearow['title'] . "#0) / (" . $fieldname . $mearow['title'] . "#1)"); if (strpos($answertext, '|')) { $answertext = substr($answertext, 0, strpos($answertext, '|')); } $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$answertext}</th>\n"; for ($i = 1; $i <= $fcount; $i++) { $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio') . "</td>\n"; } $question['ANSWER'] .= "\t\t\t<td> </td>\n"; for ($i = 1; $i <= $fcount1; $i++) { $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio') . "</td>\n"; } $answertext = $mearow['question']; if (strpos($answertext, '|')) { $answertext = substr($answertext, strpos($answertext, '|') + 1); $question['ANSWER'] .= "\t\t\t<th class=\"answertextright\">{$answertext}</th>\n"; } $question['ANSWER'] .= "\t\t</tr>\n"; //increase subquestion counter $sqcounter++; } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; // ================================================================== // ================================================================== case "H": //ARRAY (Flexible Labels) by Column //$headstyle="style='border-left-style: solid; border-left-width: 1px; border-left-color: #AAAAAA'"; $headstyle = "style='padding-left: 20px; padding-right: 7px'"; $condition = "parent_qid= '{$deqrow['qid']}' AND language= '{$sLanguageCode}'"; $fresult = Question::model()->getAllRecords($condition, array('question_order', 'title')); $fresult = $fresult->readAll(); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:"); $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td> </td>\n"; $fcount = count($fresult); $fwidth = "120"; $i = 0; foreach ($fresult as $frow) { $question['ANSWER'] .= "\t\t\t<th>{$frow['question']}" . self::_addsgqacode(" (" . $fieldname . $frow['title'] . ")") . "</th>\n"; $i++; } $question['ANSWER'] .= "\t\t</tr>\n\t</thead>\n\n\t<tbody>\n"; $a = 1; $rowclass = 'array1'; $mearesult = Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND scale_id=0 AND language='{$sLanguageCode}' ", array('sortorder', 'code')); foreach ($mearesult->readAll() as $mearow) { //$_POST['type']=$type; $question['ANSWER'] .= "\t\t<tr class=\"{$rowclass}\">\n"; $rowclass = alternation($rowclass, 'row'); $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$mearow['answer']}" . self::_addsgqacode(" (" . $mearow['code'] . ")") . "</th>\n"; //$printablesurveyoutput .="\t\t\t\t\t<td>"; for ($i = 1; $i <= $fcount; $i++) { $question['ANSWER'] .= "\t\t\t<td>" . self::_input_type_image('radio') . "</td>\n"; } //$printablesurveyoutput .="\t\t\t\t\t</tr></table></td>\n"; $question['ANSWER'] .= "\t\t</tr>\n"; $a++; } $question['ANSWER'] .= "\t</tbody>\n</table>\n"; break; case "|": // File Upload $question['QUESTION_TYPE_HELP'] .= "Kindly attach the aforementioned documents along with the survey"; break; // === END SWITCH =================================================== } $question['QUESTION_TYPE_HELP'] = self::_star_replace($question['QUESTION_TYPE_HELP']); $group['QUESTIONS'] .= self::_populate_template('question', $question); } if ($bGroupHasVisibleQuestions) { $survey_output['GROUPS'] .= self::_populate_template('group', $group); } } $survey_output['THEREAREXQUESTIONS'] = str_replace('{NUMBEROFQUESTIONS}', $total_questions, gT('There are {NUMBEROFQUESTIONS} questions in this survey')); // START recursive tag stripping. // PHP 5.1.0 introduced the count parameter for preg_replace() and thus allows this procedure to run with only one regular expression. // Previous version of PHP needs two regular expressions to do the same thing and thus will run a bit slower. $server_is_newer = version_compare(PHP_VERSION, '5.1.0', '>'); $rounds = 0; while ($rounds < 1) { $replace_count = 0; if ($server_is_newer) { $survey_output['GROUPS'] = preg_replace(array('/<td>(?: | | )?<\\/td>/isU', '/<th[^>]*>(?: | | )?<\\/th>/isU', '/<([^ >]+)[^>]*>(?: | |\\r\\n|\\n\\r|\\n|\\r|\\t| )*<\\/\\1>/isU'), array('[[EMPTY-TABLE-CELL]]', '[[EMPTY-TABLE-CELL-HEADER]]', ''), $survey_output['GROUPS'], -1, $replace_count); } else { $survey_output['GROUPS'] = preg_replace(array('/<td>(?: | | )?<\\/td>/isU', '/<th[^>]*>(?: | | )?<\\/th>/isU', '/<([^ >]+)[^>]*>(?: | |\\r\\n|\\n\\r|\\n|\\r|\\t| )*<\\/\\1>/isU'), array('[[EMPTY-TABLE-CELL]]', '[[EMPTY-TABLE-CELL-HEADER]]', ''), $survey_output['GROUPS']); $replace_count = preg_match('/<([^ >]+)[^>]*>(?: | |\\r\\n|\\n\\r|\\n|\\r|\\t| )*<\\/\\1>/isU', $survey_output['GROUPS']); } if ($replace_count == 0) { ++$rounds; $survey_output['GROUPS'] = preg_replace(array('/\\[\\[EMPTY-TABLE-CELL\\]\\]/', '/\\[\\[EMPTY-TABLE-CELL-HEADER\\]\\]/', '/\\n(?:\\t*\\n)+/'), array('<td> </td>', '<th> </th>', "\n"), $survey_output['GROUPS']); } } $survey_output['GROUPS'] = preg_replace('/(<div[^>]*>){NOTEMPTY}(<\\/div>)/', '\\1 \\2', $survey_output['GROUPS']); // END recursive empty tag stripping. echo self::_populate_template('survey', $survey_output); } // End print }
public function exportresults() { $iSurveyID = sanitize_int(Yii::app()->request->getParam('surveyid')); if (!isset($imageurl)) { $imageurl = "./images"; } if (!isset($iSurveyID)) { $iSurveyID = returnGlobal('sid'); } if (!isset($exportstyle)) { $exportstyle = returnGlobal('exportstyle'); } if (!isset($answers)) { $answers = returnGlobal('answers'); } if (!isset($type)) { $type = returnGlobal('type'); } 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 (!isset($convertspacetous)) { $convertspacetous = returnGlobal('convertspacetous'); } $clang = Yii::app()->lang; if (!hasSurveyPermission($iSurveyID, 'responses', 'export')) { exit; } Yii::app()->loadHelper("admin/exportresults"); $surveybaselang = Survey::model()->findByPk($iSurveyID)->language; $exportoutput = ""; // Get info about the survey $thissurvey = getSurveyInfo($iSurveyID); if (!$exportstyle) { //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'"; } $data['SingleResponse'] = (int) returnGlobal('id'); $data['selecthide'] = $selecthide; $data['selectshow'] = $selectshow; $data['selectinc'] = $selectinc; $data['afieldcount'] = $iFieldCount; $data['excesscols'] = $aFieldMap; //get max number of datasets $iMaximum = Yii::app()->db->createCommand("SELECT count(id) FROM {{survey_" . intval($iSurveyID) . "}}")->queryScalar(); $data['max_datasets'] = $iMaximum; $data['surveyid'] = $iSurveyID; $data['imageurl'] = Yii::app()->getConfig('imageurl'); $data['thissurvey'] = $thissurvey; $data['display']['menu_bars']['browse'] = $clang->gT("Export results"); $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 = $surveybaselang; $elang = new limesurvey_lang($explang); //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 = $answers; $options->convertN = $convertnto2; $options->output = 'display'; if ($options->convertN) { $options->nValue = $convertnto; } $options->convertY = $convertyto1; if ($options->convertY) { $options->yValue = $convertyto; } $options->headerSpacesToUnderscores = $convertspacetous; $options->headingFormat = $exportstyle; $options->responseCompletionState = incompleteAnsFilterState(); // 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 = 'id=' . (int) Yii::app()->request->getPost('response_id'); } else { $sFilter = ''; } $resultsService = new ExportSurveyResultsService(); $resultsService->exportSurvey($iSurveyID, $explang, $type, $options, $sFilter); exit; }
/** * import from csv */ function import($iSurveyId) { $clang = $this->getController()->lang; $iSurveyId = (int) $iSurveyId; if (!hasSurveyPermission($iSurveyId, 'tokens', 'import')) { Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page."); $this->getController()->redirect($this->getController()->createUrl("/admin/survey/sa/view/surveyid/{$iSurveyId}")); } // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) { self::_newtokentable($iSurveyId); } $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'tokens.js'); $aEncodings = array("armscii8" => $clang->gT("ARMSCII-8 Armenian"), "ascii" => $clang->gT("US ASCII"), "auto" => $clang->gT("Automatic"), "big5" => $clang->gT("Big5 Traditional Chinese"), "binary" => $clang->gT("Binary pseudo charset"), "cp1250" => $clang->gT("Windows Central European"), "cp1251" => $clang->gT("Windows Cyrillic"), "cp1256" => $clang->gT("Windows Arabic"), "cp1257" => $clang->gT("Windows Baltic"), "cp850" => $clang->gT("DOS West European"), "cp852" => $clang->gT("DOS Central European"), "cp866" => $clang->gT("DOS Russian"), "cp932" => $clang->gT("SJIS for Windows Japanese"), "dec8" => $clang->gT("DEC West European"), "eucjpms" => $clang->gT("UJIS for Windows Japanese"), "euckr" => $clang->gT("EUC-KR Korean"), "gb2312" => $clang->gT("GB2312 Simplified Chinese"), "gbk" => $clang->gT("GBK Simplified Chinese"), "geostd8" => $clang->gT("GEOSTD8 Georgian"), "greek" => $clang->gT("ISO 8859-7 Greek"), "hebrew" => $clang->gT("ISO 8859-8 Hebrew"), "hp8" => $clang->gT("HP West European"), "keybcs2" => $clang->gT("DOS Kamenicky Czech-Slovak"), "koi8r" => $clang->gT("KOI8-R Relcom Russian"), "koi8u" => $clang->gT("KOI8-U Ukrainian"), "latin1" => $clang->gT("cp1252 West European"), "latin2" => $clang->gT("ISO 8859-2 Central European"), "latin5" => $clang->gT("ISO 8859-9 Turkish"), "latin7" => $clang->gT("ISO 8859-13 Baltic"), "macce" => $clang->gT("Mac Central European"), "macroman" => $clang->gT("Mac West European"), "sjis" => $clang->gT("Shift-JIS Japanese"), "swe7" => $clang->gT("7bit Swedish"), "tis620" => $clang->gT("TIS620 Thai"), "ucs2" => $clang->gT("UCS-2 Unicode"), "ujis" => $clang->gT("EUC-JP Japanese"), "utf8" => $clang->gT("UTF-8 Unicode")); if (Yii::app()->request->getPost('submit')) { if (Yii::app()->request->getPost('csvcharset') && Yii::app()->request->getPost('csvcharset')) { $uploadcharset = Yii::app()->request->getPost('csvcharset'); if (!array_key_exists($uploadcharset, $aEncodings)) { $uploadcharset = 'auto'; } $filterduplicatetoken = Yii::app()->request->getPost('filterduplicatetoken') && Yii::app()->request->getPost('filterduplicatetoken') == 'on'; $filterblankemail = Yii::app()->request->getPost('filterblankemail') && Yii::app()->request->getPost('filterblankemail') == 'on'; } $attrfieldnames = getAttributeFieldNames($iSurveyId); $duplicatelist = array(); $invalidemaillist = array(); $invalidformatlist = array(); $firstline = array(); $sPath = Yii::app()->getConfig('tempdir'); $sFileTmpName = $_FILES['the_file']['tmp_name']; $sFilePath = $sPath . '/' . randomChars(20); if (!@move_uploaded_file($sFileTmpName, $sFilePath)) { $aData['sError'] = $clang->gT("Upload file not found. Check your permissions and path ({$sFilePath}) for the upload directory"); $aData['aEncodings'] = $aEncodings; $aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $this->_renderWrappedTemplate('token', array('tokenbar', 'csvupload'), $aData); } else { $xz = 0; $recordcount = 0; $xv = 0; // This allows to read file with MAC line endings too @ini_set('auto_detect_line_endings', true); // open it and trim the ednings $tokenlistarray = file($sFilePath); $sBaseLanguage = Survey::model()->findByPk($iSurveyId)->language; if (!Yii::app()->request->getPost('filterduplicatefields') || Yii::app()->request->getPost('filterduplicatefields') && count(Yii::app()->request->getPost('filterduplicatefields')) == 0) { $filterduplicatefields = array('firstname', 'lastname', 'email'); } else { $filterduplicatefields = Yii::app()->request->getPost('filterduplicatefields'); } $separator = returnGlobal('separator'); foreach ($tokenlistarray as $buffer) { $buffer = @mb_convert_encoding($buffer, "UTF-8", $uploadcharset); $firstname = ""; $lastname = ""; $email = ""; $emailstatus = "OK"; $token = ""; $language = ""; $attribute1 = ""; $attribute2 = ""; //Clear out values from the last path, in case the next line is missing a value if ($recordcount == 0) { // Pick apart the first line $buffer = removeBOM($buffer); $allowedfieldnames = array('firstname', 'lastname', 'email', 'emailstatus', 'token', 'language', 'validfrom', 'validuntil', 'usesleft'); $allowedfieldnames = array_merge($attrfieldnames, $allowedfieldnames); switch ($separator) { case 'comma': $separator = ','; break; case 'semicolon': $separator = ';'; break; default: $comma = substr_count($buffer, ','); $semicolon = substr_count($buffer, ';'); if ($semicolon > $comma) { $separator = ';'; } else { $separator = ','; } } $firstline = convertCSVRowToArray($buffer, $separator, '"'); $firstline = array_map('trim', $firstline); $ignoredcolumns = array(); //now check the first line for invalid fields foreach ($firstline as $index => $fieldname) { $firstline[$index] = preg_replace("/(.*) <[^,]*>\$/", "\$1", $fieldname); $fieldname = $firstline[$index]; if (!in_array($fieldname, $allowedfieldnames)) { $ignoredcolumns[] = $fieldname; } } if (!in_array('firstname', $firstline) || !in_array('lastname', $firstline) || !in_array('email', $firstline)) { $recordcount = count($tokenlistarray); break; } } else { $line = convertCSVRowToArray($buffer, $separator, '"'); if (count($firstline) != count($line)) { $invalidformatlist[] = $recordcount; $recordcount++; continue; } $writearray = array_combine($firstline, $line); //kick out ignored columns foreach ($ignoredcolumns as $column) { unset($writearray[$column]); } $dupfound = false; $invalidemail = false; if ($filterduplicatetoken != false) { $dupquery = "SELECT count(tid) from {{tokens_" . intval($iSurveyId) . "}} where 1=1"; foreach ($filterduplicatefields as $field) { if (isset($writearray[$field])) { $dupquery .= " and " . Yii::app()->db->quoteColumnName($field) . " = " . Yii::app()->db->quoteValue($writearray[$field]); } } $dupresult = Yii::app()->db->createCommand($dupquery)->queryScalar(); if ($dupresult > 0) { $dupfound = true; $duplicatelist[] = Yii::app()->db->quoteValue($writearray['firstname']) . " " . Yii::app()->db->quoteValue($writearray['lastname']) . " (" . Yii::app()->db->quoteValue($writearray['email']) . ")"; } } $writearray['email'] = trim($writearray['email']); //treat blank emails if ($filterblankemail && $writearray['email'] == '') { $invalidemail = true; $invalidemaillist[] = $line[0] . " " . $line[1] . " ( )"; } if ($writearray['email'] != '') { $aEmailAddresses = explode(';', $writearray['email']); foreach ($aEmailAddresses as $sEmailaddress) { if (!validateEmailAddress($sEmailaddress)) { $invalidemail = true; $invalidemaillist[] = $line[0] . " " . $line[1] . " (" . $line[2] . ")"; } } } if (!isset($writearray['token'])) { $writearray['token'] = ''; } else { $writearray['token'] = sanitize_token($writearray['token']); } if (!$dupfound && !$invalidemail) { if (!isset($writearray['emailstatus']) || $writearray['emailstatus'] == '') { $writearray['emailstatus'] = "OK"; } if (!isset($writearray['usesleft']) || $writearray['usesleft'] == '') { $writearray['usesleft'] = 1; } if (!isset($writearray['language']) || $writearray['language'] == "") { $writearray['language'] = $sBaseLanguage; } if (isset($writearray['validfrom']) && trim($writearray['validfrom'] == '')) { unset($writearray['validfrom']); } if (isset($writearray['validuntil']) && trim($writearray['validuntil'] == '')) { unset($writearray['validuntil']); } // sanitize it before writing into table foreach ($writearray as $key => $value) { if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') { $value = substr($value, 1, -1); } $sanitizedArray[Yii::app()->db->quoteColumnName($key)] = Yii::app()->db->quoteValue($value); } $iq = "INSERT INTO {{tokens_{$iSurveyId}}} \n" . "(" . implode(',', array_keys($writearray)) . ") \n" . "VALUES (" . implode(",", $sanitizedArray) . ")"; $ir = Yii::app()->db->createCommand($iq)->execute(); if (!$ir) { $duplicatelist[] = $writearray['firstname'] . " " . $writearray['lastname'] . " (" . $writearray['email'] . ")"; } else { $xz++; } } $xv++; } $recordcount++; } $recordcount = $recordcount - 1; unlink($sFilePath); $aData['tokenlistarray'] = $tokenlistarray; $aData['xz'] = $xz; $aData['xv'] = $xv; $aData['recordcount'] = $recordcount; $aData['firstline'] = $firstline; $aData['duplicatelist'] = $duplicatelist; $aData['invalidformatlist'] = $invalidformatlist; $aData['invalidemaillist'] = $invalidemaillist; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId; $this->_renderWrappedTemplate('token', array('tokenbar', 'csvpost'), $aData); } } else { $aData['aEncodings'] = $aEncodings; $aData['iSurveyId'] = $iSurveyId; $aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['surveyid'] = $iSurveyId; $aTokenTableFields = getTokenFieldsAndNames($iSurveyId); unset($aTokenTableFields['sent']); unset($aTokenTableFields['remindersent']); unset($aTokenTableFields['remindercount']); unset($aTokenTableFields['usesleft']); foreach ($aTokenTableFields as $sKey => $sValue) { if ($sValue['description'] != $sKey) { $sValue['description'] .= ' - ' . $sKey; } $aNewTokenTableFields[$sKey] = $sValue['description']; } $aData['aTokenTableFields'] = $aNewTokenTableFields; $this->_renderWrappedTemplate('token', array('tokenbar', 'csvupload'), $aData); } }