/** * Returns this model's relations * * @access public * @return array */ public function relations() { if ($this->getbHaveToken()) { TokenDynamic::sid(self::$sid); return array('survey' => array(self::HAS_ONE, 'Survey', array(), 'condition' => 'sid = ' . self::$sid), 'tokens' => array(self::HAS_ONE, 'TokenDynamic', array('token' => 'token'))); } else { return array(); } }
/** * Show dialogs and create a new tokens table */ function _newtokentable($iSurveyId) { $clang = $this->getController()->lang; $aSurveyInfo = getSurveyInfo($iSurveyId); if (!Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'update') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'create')) { Yii::app()->session['flashmessage'] = $clang->gT("Tokens have not been initialised for this survey."); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); } $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if ($bTokenExists) { Yii::app()->session['flashmessage'] = $clang->gT("Tokens already exist for this survey."); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); } // The user have rigth to create token, then don't test right after Yii::import('application.helpers.admin.token_helper', true); if (Yii::app()->request->getQuery('createtable') == "Y") { createTokenTable($iSurveyId); LimeExpressionManager::SetDirtyFlag(); // LimeExpressionManager needs to know about the new token table $this->_renderWrappedTemplate('token', array('message' => array('title' => $clang->gT("Token control"), 'message' => $clang->gT("A token table has been created for this survey.") . " (\"" . Yii::app()->db->tablePrefix . "tokens_{$iSurveyId}\")<br /><br />\n" . "<input type='submit' value='" . $clang->gT("Continue") . "' onclick=\"window.open('" . $this->getController()->createUrl("admin/tokens/sa/index/surveyid/{$iSurveyId}") . "', '_top')\" />\n"))); } elseif (returnGlobal('restoretable') == "Y" && Yii::app()->request->getPost('oldtable')) { //Rebuild attributedescription value for the surveys table $table = Yii::app()->db->schema->getTable(Yii::app()->request->getPost('oldtable')); $fields = array_filter(array_keys($table->columns), 'filterForAttributes'); $fieldcontents = $aSurveyInfo['attributedescriptions']; if (!is_array($fieldcontents)) { $fieldcontents = array(); } foreach ($fields as $fieldname) { $name = $fieldname; if ($fieldname[10] == 'c') { //This belongs to a cpdb attribute $cpdbattid = substr($fieldname, 15); $data = ParticipantAttributeName::model()->getAttributeName($cpdbattid, Yii::app()->session['adminlang']); $name = $data['attribute_name']; } if (!isset($fieldcontents[$fieldname])) { $fieldcontents[$fieldname] = array('description' => $name, 'mandatory' => 'N', 'show_register' => 'N'); } } Survey::model()->updateByPk($iSurveyId, array('attributedescriptions' => serialize($fieldcontents))); Yii::app()->db->createCommand()->renameTable(Yii::app()->request->getPost('oldtable'), Yii::app()->db->tablePrefix . "tokens_" . intval($iSurveyId)); Yii::app()->db->schema->getTable(Yii::app()->db->tablePrefix . "tokens_" . intval($iSurveyId), true); // Refresh schema cache just in case the table existed in the past //Check that the tokens table has the required fields TokenDynamic::model($iSurveyId)->checkColumns(); //Add any survey_links from the renamed table SurveyLink::model()->rebuildLinksFromTokenTable($iSurveyId); $this->_renderWrappedTemplate('token', array('message' => array('title' => $clang->gT("Import old tokens"), 'message' => $clang->gT("A token table has been created for this survey and the old tokens were imported.") . " (\"" . Yii::app()->db->tablePrefix . "tokens_{$iSurveyId}" . "\")<br /><br />\n" . "<input type='submit' value='" . $clang->gT("Continue") . "' onclick=\"window.open('" . $this->getController()->createUrl("admin/tokens/sa/index/surveyid/{$iSurveyId}") . "', '_top')\" />\n"))); LimeExpressionManager::SetDirtyFlag(); // so that knows that token tables have changed } else { $this->getController()->loadHelper('database'); $result = Yii::app()->db->createCommand(dbSelectTablesLike("{{old_tokens_" . intval($iSurveyId) . "_%}}"))->queryAll(); $tcount = count($result); if ($tcount > 0) { foreach ($result as $rows) { $oldlist[] = reset($rows); } $aData['oldlist'] = $oldlist; } $thissurvey = getSurveyInfo($iSurveyId); $aData['thissurvey'] = $thissurvey; $aData['surveyid'] = $iSurveyId; $aData['tcount'] = $tcount; $aData['databasetype'] = Yii::app()->db->getDriverName(); $this->_renderWrappedTemplate('token', 'tokenwarning', $aData); } }
/** * 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 (Permission::model()->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 = ''; $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 = TokenDynamic::model($iSurveyID); $aAllTokens = $oTokens->findUninvitedIDs(false, 0, false, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition); $iAllTokensCount = count($aAllTokens); unset($aAllTokens); // save some memory before the next query $aResultTokens = $oTokens->findUninvited(false, $iMaxEmails, false, $SQLemailstatuscondition, $SQLremindercountcondition, $SQLreminderdelaycondition); if (empty($aResultTokens)) { return array('status' => 'Error: No candidate tokens'); } $aResult = emailTokens($iSurveyID, $aResultTokens, 'remind'); $iLeft = $iAllTokensCount - count($aResultTokens); $aResult['status'] = $iLeft . " left to send"; return $aResult; } else { return array('status' => 'No permission'); } }
/** * Returns survey responses in json format for a given survey * * @access public * @param $iSurveyID : survey id * @return json */ public function getResponses_json($iSurveyID) { if (!Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'read')) { Yii::app()->end(); } $aData = $this->_getData($iSurveyID); $bHaveToken = $aData['surveyinfo']['anonymized'] == "N" && tableExists('tokens_' . $iSurveyID) && Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'read'); extract($aData); $aViewUrls = array(); $sBrowseLanguage = $aData['language']; $sImageURL = Yii::app()->getConfig('adminimageurl'); $fnames = array(); $aSpecificColumns = array('submitdate', 'token', 'id', 'lastpage'); $aFieldmap = createFieldMap($iSurveyID, 'full', true, false, $aData['language']); // Get the survey responses $sOrder = Yii::app()->request->getPost('sord') == 'desc' ? 'desc' : 'asc'; $sOrderBy = Yii::app()->request->getPost('sidx', 'id'); $iPage = Yii::app()->request->getPost('page', 1); $iLimit = Yii::app()->request->getPost('rows', 50); // Default to 50 ? // Old behaviour : ajax default request from jqgrid need sort / rows (limit) / page (start) / sidx for order by : use javacript log please .... $oCriteria = new CDbCriteria(); //Create the query if ($bHaveToken) { $oCriteria = SurveyDynamic::model($iSurveyID)->addTokenCriteria($oCriteria); $aSpecificColumns = array_merge($aSpecificColumns, TokenDynamic::model($iSurveyID)->getTableSchema()->getColumnNames()); } if (incompleteAnsFilterState() == "incomplete") { $oCriteria->addCondition("submitdate IS NULL"); } elseif (incompleteAnsFilterState() == "complete") { $oCriteria->addCondition("submitdate IS NOT NULL"); } //Get the filter data //if (Yii::app()->request->getPost('sql') && stripcslashes(Yii::app()->request->getPost('sql')) !== "" && Yii::app()->request->getPost('sql') != "NULL") // $oCriteria->addCondition(stripcslashes(Yii::app()->request->getPost('sql'))); $aKnowColumns = array_keys(SurveyDynamic::model($iSurveyID)->attributes); if ($bHaveToken) { $aKnowColumns[] = 'firstname'; $aKnowColumns[] = 'lastname'; $aKnowColumns[] = 'email'; } switch ($sOrderBy) { case 'completed': $sOrderBy = 'submitdate'; break; default: if (!in_array($sOrderBy, $aKnowColumns)) { Yii::trace("unknow column {$sOrderBy} in json request"); $sOrderBy = 'id'; } } $sOrderBy = Yii::app()->db->quoteColumnName($sOrderBy); // Maybe need to fix if $sOrderBy is in columns name $oCriteria->order = "{$sOrderBy} {$sOrder}"; if (Yii::app()->request->getParam('_search')) { if ($value = Yii::app()->request->getParam('completed')) { if ($value == 'Y') { $oCriteria->addCondition("submitdate IS NOT NULL"); Yii::app()->session['incompleteanswers'] = 'complete'; } elseif ($value == 'N') { $oCriteria->addCondition("submitdate IS NULL"); Yii::app()->session['incompleteanswers'] = 'incomplete'; } else { Yii::app()->session['incompleteanswers'] = 'all'; } } //Get the filter data if (App()->request->getQuery('statfilter') && is_array(Yii::app()->session['statistics_selects_' . $iSurveyID])) { foreach (Yii::app()->session['statistics_selects_' . $iSurveyID] as $sCondition) { $oCriteria->addCondition($sCondition); } } foreach ($aKnowColumns as $sFiltering) { if ($value = Yii::app()->request->getParam($sFiltering)) { if ($sFiltering == 'token') { $sFiltering = 'tokens.token'; } $oCriteria->compare(Yii::app()->db->quoteColumnName($sFiltering), $value, true); } } if ($sFilters = Yii::app()->request->getParam('filters')) { $aFilters = json_decode($sFilters); // TODO : groupOp and rules } } // Elements for nav bar of jquery $iCount = SurveyDynamic::model($iSurveyID)->count($oCriteria); // or die("Couldn't get response data<br />"); $iLimit = (int) $iLimit > 0 ? (int) $iLimit : 50; if (!$iLimit || $iLimit > $iCount) { $iLimit = $iCount; } $iStart = (int) $iPage > 0 ? (int) $iPage * $iLimit - $iLimit : 0; $aSurveyEntries = new stdClass(); $aSurveyEntries->page = $iPage; // Did we need to fix page ? $aSurveyEntries->total = $iCount > 0 ? ceil($iCount / $iLimit) : 0; $aSurveyEntries->records = $iCount; // Last criteria update $oCriteria->offset = $iStart; $oCriteria->limit = $iLimit; // Get the rows $dtresult = SurveyDynamic::model($iSurveyID)->findAllAsArray($oCriteria); $all_rows = array(); foreach ($dtresult as $row) { // View detail icon $action_html = '<a href="' . Yii::app()->createUrl("admin/responses/view/surveyid/{$surveyid}/id/{$row['id']}") . '"><span class="glyphicon glyphicon-list-alt text-success" title="' . gT('View response details') . '"></span></a>'; // Edit icon if (Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'update')) { $action_html .= "<a href='" . Yii::app()->createUrl("admin/dataentry/editdata/subaction/edit/surveyid/{$surveyid}/id/{$row['id']}") . "'>\n <span class='glyphicon glyphicon-pencil text-success' title='" . gT('Edit this response') . "'></span></a>"; } // Download icon if (hasFileUploadQuestion($surveyid)) { if (Response::model($surveyid)->findByPk($row['id'])->getFiles()) { $action_url = Yii::app()->createUrl("admin/responses", array("sa" => "actionDownloadfiles", "surveyid" => $surveyid, "sResponseId" => $row['id'])); $action_html .= '<a title="' . gT('Download all files in this response as a zip file') . '" href="' . $action_url . '"><span class="glyphicon glyphicon-download-alt downloadfile"></span></a>'; } } // Delete icon if (Permission::model()->hasSurveyPermission($iSurveyID, 'responses', 'delete')) { $action_html .= "<a href='" . Yii::app()->createUrl("admin/responses", array("sa" => "actionDelete", "surveyid" => $surveyid, "sResponseId" => $row['id'])) . "' data-delete='" . $row['id'] . "'>\n <span title='" . sprintf(gT('Delete response %s'), $row['id']) . "' class='deleteresponse glyphicon glyphicon-trash text-warning'></span></a>"; } $aSurveyEntry = array(); $aSurveyEntry[] = $action_html; $aSurveyEntry[] = $row['id']; $aSurveyEntry[] = $row['lastpage']; // completed $aSurveyEntry[] = empty($row['submitdate']) ? 'N' : 'Y'; if ($bHaveToken) { if (is_null($row['tid'])) { $aSurveyEntry[] = strip_tags($row['token']); } else { $aSurveyEntry[] = "<a href='" . Yii::app()->createUrl("admin/tokens", array("sa" => "edit", "surveyid" => $surveyid, "tokenid" => $row['tid'])) . "'>" . strip_tags($row['token']) . "</a>"; } $aSurveyEntry[] = strip_tags($row['firstname']); $aSurveyEntry[] = strip_tags($row['lastname']); $aSurveyEntry[] = strip_tags($row['email']); } // startlanguage //$aSurveyEntry[] = $row['startlanguage']; foreach ($row as $aFieldName => $mFieldValue) { if (in_array($aFieldName, $aSpecificColumns)) { continue; } $sSurveyEntry = strip_tags(getExtendedAnswer($iSurveyID, $aFieldName, $mFieldValue, $sBrowseLanguage)); // This fix XSS and get the value if ($aFieldmap[$aFieldName]['type'] == '|' && strpos($aFieldName, 'filecount') === false) { $aQuestionAttributes = getQuestionAttributeValues($aFieldmap[$aFieldName]['qid']); $aFilesInfo = json_decode_ls($mFieldValue); for ($iFileIndex = 0; $iFileIndex < $aQuestionAttributes['max_num_of_files']; $iFileIndex++) { if (isset($aFilesInfo[$iFileIndex])) { $aSurveyEntry[] = htmlspecialchars($aFilesInfo[$iFileIndex]['title'], ENT_QUOTES, 'UTF-8'); $aSurveyEntry[] = htmlspecialchars($aFilesInfo[$iFileIndex]['comment'], ENT_QUOTES, 'UTF-8'); $aSurveyEntry[] = CHtml::link(rawurldecode($aFilesInfo[$iFileIndex]['name']), $this->getController()->createUrl("/admin/responses", array("sa" => "actionDownloadfile", "surveyid" => $surveyid, "iResponseId" => $row['id'], "sFileName" => $aFilesInfo[$iFileIndex]['name']))); $aSurveyEntry[] = sprintf('%s Mb', round($aFilesInfo[$iFileIndex]['size'] / 1000, 2)); } else { $aSurveyEntry[] = ""; $aSurveyEntry[] = ""; $aSurveyEntry[] = ""; $aSurveyEntry[] = ""; } } } else { $aSurveyEntry[] = $sSurveyEntry; } } $all_rows[] = array('id' => $row['id'], 'cell' => $aSurveyEntry); } $aSurveyEntries->rows = $all_rows; viewHelper::disableHtmlLogging(); // It's better with but we need to fix error actually header('Content-type: application/json'); echo json_encode($aSurveyEntries); Yii::app()->end(); }
function deleteRecords($iTokenIds) { foreach ($iTokenIds as &$currentrow) { $currentrow = Yii::app()->db->quoteValue($currentrow); } $dlquery = "DELETE FROM " . TokenDynamic::tableName() . " WHERE tid IN (" . implode(", ", $iTokenIds) . ")"; return Yii::app()->db->createCommand($dlquery)->query(); }
/** * 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); }
public function beforeSurveyPage() { $oEvent = $this->event; $iSurveyId = $oEvent->get('surveyId'); self::__init(); $bUse=$this->get('bUse', 'Survey', $iSurveyId); if(is_null($bUse)) $bUse=$this->bUse; if(!$bUse) return; $sToken= Yii::app()->request->getParam('token'); if($iSurveyId && !$sToken)// Test invalid token ? { // Get the survey model $oSurvey=Survey::model()->find("sid=:sid",array(':sid'=>$iSurveyId)); if($oSurvey && $oSurvey->active=="Y" && $oSurvey->allowregister=="Y" && tableExists("tokens_{$iSurveyId}")) { // Fill parameters $bShowTokenForm=$this->get('bShowTokenForm', 'Survey', $iSurveyId); if(is_null($bShowTokenForm)) $bShowTokenForm=$this->bShowTokenForm; $bShowTokenForm=$this->get('use', 'Survey', $iSurveyId); if(is_null($bShowTokenForm)) $bShowTokenForm=$this->bUse; Yii::app()->getClientScript()->registerCssFile(Yii::app()->getConfig('publicurl')."plugins/replaceRegister/css/register.css"); // We can go $sLanguage = Yii::app()->request->getParam('lang',''); if ($sLanguage=="" ) { $sLanguage = Survey::model()->findByPk($iSurveyId)->language; } $aSurveyInfo=getSurveyInfo($iSurveyId,$sLanguage); $sAction= Yii::app()->request->getParam('action','view') ; $sHtmlRegistererror=""; $sHtmlRegistermessage1=gT("You must be registered to complete this survey");; $sHtmlRegistermessage2=gT("You may register for this survey if you wish to take part.")."<br />\n".gT("Enter your details below, and an email containing the link to participate in this survey will be sent immediately."); $sHtmlRegisterform=""; $sHtml=""; $bShowForm=true; $bValidMail=false; $bTokenCreate=true; $aExtraParams=array(); $aRegisterError=array(); $sR_email= Yii::app()->request->getPost('register_email'); $sR_firstname= sanitize_xss_string(Yii::app()->request->getPost('register_firstname',"")); $sR_lastname= sanitize_xss_string(Yii::app()->request->getPost('register_lastname',"")); $sR_lastname= sanitize_xss_string(Yii::app()->request->getPost('register_lastname',"")); $aR_attribute=array(); $aR_attributeGet=array(); $aExtraParams=array(); $aMail=array(); foreach ($aSurveyInfo['attributedescriptions'] as $field => $aAttribute) { if (!empty($aAttribute['show_register']) && $aAttribute['show_register'] == 'Y') { $aR_attribute[$field]= sanitize_xss_string(Yii::app()->request->getPost('register_'.$field),"");// Need to be filtered ? } elseif($aAttribute['description']==sanitize_paranoid_string($aAttribute['description']) && trim(Yii::app()->request->getQuery($aAttribute['description'],"")) ) { $aR_attributeGet[$field]= sanitize_xss_string(trim(Yii::app()->request->getQuery($aAttribute['description'],"")));// Allow prefill with URL (TODO: add an option) $aExtraParams[$aAttribute['description']]=sanitize_xss_string(trim(Yii::app()->request->getParam($aAttribute['description'],""))); } } if($sAction=='register' && !is_null($sR_email) && Yii::app()->request->getPost('changelang')!='changelang') { $bShowForm=false; // captcha $sLoadsecurity=Yii::app()->request->getPost('loadsecurity'); $sSecAnswer=(isset($_SESSION['survey_'.$iSurveyId]['secanswer']))?$_SESSION['survey_'.$iSurveyId]['secanswer']:""; $bShowForm=false; $bNoError=true; // Copy paste RegisterController if($sR_email) { //Check that the email is a valid style addressattribute_2 if (!validateEmailAddress($sR_email)) { $aRegisterError[]= gT("The email you used is not valid. Please try again."); } } else { $aRegisterError[]= gT("The email you used is not valid. Please try again.");// Empty email } // Fill and validate mandatory extra attribute foreach ($aSurveyInfo['attributedescriptions'] as $field => $aAttribute) { if (!empty($aAttribute['show_register']) && $aAttribute['show_register'] == 'Y' && $aAttribute['mandatory'] == 'Y' && ($aR_attribute[$field]=="" || is_null($aR_attribute[$field])) ) { $aRegisterError[]= sprintf(gT("%s cannot be left empty").".", $aSurveyInfo['attributecaptions'][$field]); } } // Check the security question's answer : at end because the security question is the last one if (function_exists("ImageCreate") && isCaptchaEnabled('registrationscreen',$aSurveyInfo['usecaptcha']) ) { if (!$sLoadsecurity || !$sSecAnswer || $sLoadsecurity != $sSecAnswer) { $aRegisterError[]= gT("The answer to the security question is incorrect."); } } if(count($aRegisterError)==0) { //Check if this email already exists in token database $oToken=TokenDynamic::model($iSurveyId)->find('email=:email',array(':email'=>$sR_email)); if ($oToken) { if($oToken->usesleft<1 && $aSurveyInfo['alloweditaftercompletion']!='Y') { $aRegisterError="The e-mail address you have entered is already registered an the questionnaire has been completed."; } elseif(strtolower(substr(trim($oToken->emailstatus),0,6))==="optout")// And global blacklisting ? { $aRegisterError="This email address is already registered but someone ask to don't receive new email again."; } elseif(!$oToken->emailstatus && $oToken->emailstatus!="OK") { $aRegisterError="This email address is already registered but the email adress was bounced."; } else { $iTokenId=$oToken->tid; $aMail['subject']=$aSurveyInfo['email_register_subj']; $aMail['message']=$aSurveyInfo['email_register']; $aMail['information']="The address you have entered is already registered. An email has been sent to this address with a link that gives you access to the survey."; // Did we update the token ? Setting ? } } else { $oToken= Token::create($iSurveyId); $oToken->firstname = $sR_firstname; $oToken->lastname = $sR_lastname; $oToken->email = $sR_email; $oToken->emailstatus = 'OK'; $oToken->language = $sLanguage; $oToken->setAttributes($aR_attribute); $oToken->setAttributes($aR_attributeGet);// Need an option if ($aSurveyInfo['startdate']) { $oToken->validfrom = $aSurveyInfo['startdate']; } if ($aSurveyInfo['expires']) { $oToken->validuntil = $aSurveyInfo['expires']; } $oToken->save(); $iTokenId=$oToken->tid; TokenDynamic::model($iSurveyId)->createToken($iTokenId);// Review if really create a token $aMail['subject']=$aSurveyInfo['email_register_subj']; $aMail['message']=$aSurveyInfo['email_register']; $aMail['information']=gT("An email has been sent to the address you provided with access details for this survey. Please follow the link in that email to proceed."); } } } if($aMail && $oToken) { $aReplacementFields=array(); $aReplacementFields["{ADMINNAME}"]=$aSurveyInfo['adminname']; $aReplacementFields["{ADMINEMAIL}"]=$aSurveyInfo['adminemail']; $aReplacementFields["{SURVEYNAME}"]=$aSurveyInfo['name']; $aReplacementFields["{SURVEYDESCRIPTION}"]=$aSurveyInfo['description']; $aReplacementFields["{EXPIRY}"]=$aSurveyInfo["expiry"]; $oToken=TokenDynamic::model($iSurveyId)->findByPk($iTokenId); foreach($oToken->attributes as $attribute=>$value){ $aReplacementFields["{".strtoupper($attribute)."}"]=$value; } $sToken=$oToken->token; $aMail['subject']=preg_replace("/{TOKEN:([A-Z0-9_]+)}/","{"."$1"."}",$aMail['subject']); $aMail['message']=preg_replace("/{TOKEN:([A-Z0-9_]+)}/","{"."$1"."}",$aMail['message']); $surveylink = App()->createAbsoluteUrl("/survey/index/sid/{$iSurveyId}",array('lang'=>$sLanguage,'token'=>$sToken)); $optoutlink = App()->createAbsoluteUrl("/optout/tokens/surveyid/{$iSurveyId}",array('langcode'=>$sLanguage,'token'=>$sToken)); $optinlink = App()->createAbsoluteUrl("/optin/tokens/surveyid/{$iSurveyId}",array('langcode'=>$sLanguage,'token'=>$sToken)); if (getEmailFormat($iSurveyId) == 'html') { $useHtmlEmail = true; $aReplacementFields["{SURVEYURL}"]="<a href='$surveylink'>".$surveylink."</a>"; $aReplacementFields["{OPTOUTURL}"]="<a href='$optoutlink'>".$optoutlink."</a>"; $aReplacementFields["{OPTINURL}"]="<a href='$optinlink'>".$optinlink."</a>"; } else { $useHtmlEmail = false; $aReplacementFields["{SURVEYURL}"]= $surveylink; $aReplacementFields["{OPTOUTURL}"]= $optoutlink; $aReplacementFields["{OPTINURL}"]= $optinlink; } // Allow barebone link for all URL $aMail['message'] = str_replace("@@SURVEYURL@@", $surveylink, $aMail['message']); $aMail['message'] = str_replace("@@OPTOUTURL@@", $optoutlink, $aMail['message']); $aMail['message'] = str_replace("@@OPTINURL@@", $optinlink, $aMail['message']); // Replace the fields $aMail['subject']=ReplaceFields($aMail['subject'], $aReplacementFields); $aMail['message']=ReplaceFields($aMail['message'], $aReplacementFields); // We have it, then try to send the mail. $from = "{$aSurveyInfo['adminname']} <{$aSurveyInfo['adminemail']}>"; $sitename = Yii::app()->getConfig('sitename'); if (SendEmailMessage($aMail['message'], $aMail['subject'], $sR_email, $from, $sitename,$useHtmlEmail,getBounceEmail($iSurveyId))) { // TLR change to put date into sent $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig('timeadjust')); $oToken->sent=$today; $oToken->save(); $sReturnHtml="<div id='wrapper' class='message tokenmessage'>" . "<p>".gT("Thank you for registering to participate in this survey.")."</p>\n" . "<p>".$aMail['information']."</p>\n" . "<p>".gT("Survey administrator")." {ADMINNAME} ({ADMINEMAIL})</p>" . "</div>\n"; } else { $sReturnHtml="<div id='wrapper' class='message tokenmessage'>" . "<p>".gT("Thank you for registering to participate in this survey.")."</p>\n" . "<p>"."We can not sent you an email actually, please contact the survey administrator"."</p>\n" . "<p>".gT("Survey administrator")." {ADMINNAME} ({ADMINEMAIL})</p>" . "</div>\n"; } $sReturnHtml=ReplaceFields($sReturnHtml, $aReplacementFields); $sTemplatePath=$aData['templatedir'] = getTemplatePath($aSurveyInfo['template']); ob_start(function($buffer, $phase) { App()->getClientScript()->render($buffer); App()->getClientScript()->reset(); return $buffer; }); ob_implicit_flush(false); sendCacheHeaders(); doHeader(); $aData['thissurvey'] = $aSurveyInfo; $aData['thissurvey'] = $aSurveyInfo; echo templatereplace(file_get_contents($sTemplatePath.'/startpage.pstpl'),array(), $aData); echo templatereplace(file_get_contents($sTemplatePath.'/survey.pstpl'),array(), $aData); echo $sReturnHtml; echo templatereplace(file_get_contents($sTemplatePath.'/endpage.pstpl'),array(), $aData); doFooter(); ob_flush(); App()->end(); } if($bShowForm || count($aRegisterError)) { // Language ? if(count($aRegisterError)==1){ $sHtmlRegistererror="<p class='error error-register'><strong>{$aRegisterError[0]}</strong></p>"; }elseif(count($aRegisterError)>1){ $sHtmlRegistererror="<ul class='error error-register error-list'>"; foreach ($aRegisterError as $sRegisterError) $sHtmlRegistererror.="<li><strong>{$sRegisterError}</strong></li>"; $sHtmlRegistererror.="</ul>"; } $aExtraParams['action']='register'; $aExtraParams['lang']=$sLanguage; $sHtmlRegisterform = CHtml::form(Yii::app()->createUrl("/survey/index/sid/{$iSurveyId}",$aExtraParams), 'post'); $sHtmlRegisterform.="<table class='register'><tbody>\n"; $sHtmlRegisterform.= "<tr><th><label for='register_firstname'>".gT("First name") . "</label></th><td>".CHtml::textField('register_firstname',htmlentities($sR_firstname, ENT_QUOTES, 'UTF-8'),array('class'=>'text'))."</td></tr>\n"; $sHtmlRegisterform.= "<tr><th><label for='register_lastname'>".gT("Last name") . "</label></th><td>".CHtml::textField('register_lastname',htmlentities($sR_lastname, ENT_QUOTES, 'UTF-8'),array('class'=>'text'))."</td></tr>\n"; $sHtmlRegisterform.= "<tr class='mandatory'><th><label for='register_email'>".gT("Email address") . "</label></th><td>".CHtml::textField('register_email',htmlentities($sR_email, ENT_QUOTES, 'UTF-8'),array('class'=>'text'))."</td></tr>\n"; // Extra attribute foreach ($aSurveyInfo['attributedescriptions'] as $field => $aAttribute) { if (!empty($aAttribute['show_register']) && $aAttribute['show_register'] == 'Y') { $sHtmlRegisterform.= "<tr".($aAttribute['mandatory'] == 'Y' ? " class='mandatory'" : '')."><th><label for='register_{$field}'>".$aSurveyInfo['attributecaptions'][$field].($aAttribute['mandatory'] == 'Y' ? ' *' : '')."</label></th><td>".CHtml::textField('register_'.$field,htmlentities($aR_attribute[$field], ENT_QUOTES, 'UTF-8'),array('class'=>'text'))."</td></tr>\n"; } } if (function_exists("ImageCreate") && isCaptchaEnabled('registrationscreen', $aSurveyInfo['usecaptcha'])) $sHtmlRegisterform.= "<tr><th><label for='loadsecurity'>" . gT("Security question") . "</label></th><td><img src='".Yii::app()->getController()->createUrl("/verification/image/sid/{$iSurveyId}")."' alt='' /><input type='text' size='5' maxlength='3' name='loadsecurity' id='loadsecurity' value='' /></td></tr>\n"; $sHtmlRegisterform.= "<tr><td></td><td>".CHtml::submitButton(gT("Continue"))."</td></tr>"; $sHtmlRegisterform.= "</tbody></table>\n"; $sHtmlRegisterform.= makeLanguageChangerSurvey($sLanguage);// Need to be inside the form $sHtmlRegisterform.= CHtml::endForm(); } $sTemplatePath=$aData['templatedir'] = getTemplatePath($aSurveyInfo['template']); ob_start(function($buffer, $phase) { App()->getClientScript()->render($buffer); App()->getClientScript()->reset(); return $buffer; }); ob_implicit_flush(false); sendCacheHeaders(); doHeader(); // Get the register.pstpl file content, but remplace default by own string $sHtmlRegister=file_get_contents($sTemplatePath.'/register.pstpl'); $sHtmlRegister= str_replace("{REGISTERERROR}",$sHtmlRegistererror,$sHtmlRegister); $sHtmlRegister= str_replace("{REGISTERMESSAGE1}",$sHtmlRegistermessage1,$sHtmlRegister); $sHtmlRegister= str_replace("{REGISTERMESSAGE2}",$sHtmlRegistermessage2,$sHtmlRegister); $sHtmlRegister= str_replace("{REGISTERFORM}",$sHtmlRegisterform,$sHtmlRegister); $aData['thissurvey'] = $aSurveyInfo; echo templatereplace(file_get_contents($sTemplatePath.'/startpage.pstpl'),array(), $aData); echo templatereplace(file_get_contents($sTemplatePath.'/survey.pstpl'),array(), $aData); echo templatereplace($sHtmlRegister); echo templatereplace(file_get_contents($sTemplatePath.'/endpage.pstpl'),array(), $aData); doFooter(); ob_flush(); App()->end(); } } }
/** * 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 $iTokenID ID of the participant to send the reminder to * @return array Result of the action */ public function remind_participant($sSessionKey, $iSurveyID, $iTokenID) { 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 (Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'update')) { $timeadjust = Yii::app()->getConfig("timeadjust"); if (!tableExists("{{tokens_{$iSurveyID}}}")) { return array('status' => 'Error: No token table'); } $SQLemailstatuscondition = "emailstatus = 'OK'"; $oTokens = TokenDynamic::model($iSurveyID); $aResultTokens = $oTokens->findUninvited(false, $iMaxEmails, false, $SQLemailstatuscondition, '', ''); if (empty($aResultTokens)) { return array('status' => 'Error: No candidate tokens'); } // find our token $token = null; foreach ($aResultTokens as $key => $value) { if ($value['tid'] == $iTokenID) { $token = $value; } } if ($token) { emailTokens($iSurveyID, array($token), 'remind'); return $iTokenID; } else { return 'Error: Can not find token in token table'; } } else { return array('status' => 'No permission'); } }
public function beforeSurveyPage() { $oEvent = $this->event; $iSurveyId = $oEvent->get('surveyId'); $bUse = $this->get('bUse', 'Survey', $iSurveyId); if ($bUse) { //Only private surveys with authsaml plugin enabled if ($this->ssp->isAuthenticated()) { //Only idp users $sLanguage = Yii::app()->request->getParam('lang'); $aSurveyInfo = getSurveyInfo($iSurveyId, $sLanguage); $aSurveyIdpAttributes = array_diff(json_decode($this->get('surveyIdpAttributes', 'Survey', $iSurveyId), true), array('none')); if ($this->checkIdpAttributes($aSurveyIdpAttributes)) { $oToken = TokenDynamic::model($iSurveyId)->find('email=:email', array(':email' => $this->getUserMail())); if ($oToken) { //Allow survey access if the token is given if (Yii::app()->request->getParam('token')) { return; } $sToken = $oToken->token; } else {//Creation of the token $oToken = Token::create($iSurveyId); $oToken->firstname = $this->getUserGivenName(); $oToken->lastname = $this->getUserSurName(); $oToken->email = $this->getUserMail(); $oToken->emailstatus = 'OK'; $oToken->language = $sLanguage; if ($aSurveyInfo['startdate']) { $oToken->validfrom = $aSurveyInfo['startdate']; } if ($aSurveyInfo['expires']) { $oToken->validuntil = $aSurveyInfo['expires']; } $oToken->save(); $iTokenId = $oToken->tid; $sToken = TokenDynamic::model($iSurveyId)->createToken($iTokenId); } if ($sToken) { $surveylink = App()->createAbsoluteUrl("/survey/index/sid/{$iSurveyId}", array('token' => $sToken)); header('Location: ' . $surveylink); } } else { $aReplacementFields = array(); $aReplacementFields["{ADMINNAME}"] = $aSurveyInfo['adminname']; $aReplacementFields["{ADMINEMAIL}"] = $aSurveyInfo['adminemail']; $sLanguage = Yii::app()->request->getParam('lang', ''); if ($sLanguage == "") { $sLanguage = Survey::model()->findByPk($iSurveyId)->language; } $aSurveyInfo = getSurveyInfo($iSurveyId, $sLanguage); $sTemplatePath = $aData['templatedir'] = getTemplatePath($aSurveyInfo['template']); $sAttributesRequired = ''; $sAttributesReceived = ''; foreach ($aSurveyIdpAttributes as $key => $value) { $sAttributesRequired .= "<li>{$key} = \"{$value}\"</li>"; } foreach (array_intersect_key($this->attributes, $aSurveyIdpAttributes) as $key => $value) { $sAttributesReceived .= "<li>{$key} = \"{$value[0]}\"</li>"; } $sReturnHtml = "<div id='wrapper' class='message tokenmessage'>" . "<h3>Acesso ao questionário não permitido!</h3>\n" . "<p>Informações de usuário necessárias:</p>\n" . "<ul>$sAttributesRequired</ul><br />" . "<p>Informações de usuário recebidas:</p>\n" . "<ul>$sAttributesReceived</ul><br />" . "<p>Entre em contato com o administrador do questionário: {ADMINNAME} ({ADMINEMAIL})</p>" . "</div>\n"; $sReturnHtml = ReplaceFields($sReturnHtml, $aReplacementFields); ob_start(function($buffer, $phase) { App()->getClientScript()->render($buffer); App()->getClientScript()->reset(); return $buffer; }); ob_implicit_flush(false); sendCacheHeaders(); doHeader(); $aData['thissurvey'] = $aSurveyInfo; $aData['thissurvey'] = $aSurveyInfo; echo templatereplace(file_get_contents($sTemplatePath . '/startpage.pstpl'), array(), $aData); echo templatereplace(file_get_contents($sTemplatePath . '/survey.pstpl'), array(), $aData); echo $sReturnHtml; echo templatereplace(file_get_contents($sTemplatePath . '/endpage.pstpl'), array(), $aData); doFooter(); ob_flush(); App()->end(); } } else {// Asks idp authentication header('Location: ' . $this->ssp->getLoginURL()); } } }
/** * 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); }
/** * register::index() * Process register form data and take appropriate action * @return */ function actionIndex($iSurveyID = null) { Yii::app()->loadHelper('database'); Yii::app()->loadHelper('replacements'); $sLanguage = Yii::app()->request->getParam('lang', ''); if ($iSurveyID == null) { $iSurveyID = Yii::app()->request->getPost('sid'); } if (!$iSurveyID) { $this->redirect(Yii::app()->baseUrl); } if ($sLanguage == "") { $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language; } else { $sBaseLanguage = $sLanguage; } Yii::import('application.libraries.Limesurvey_lang'); Yii::app()->lang = new Limesurvey_lang($sBaseLanguage); $clang = Yii::app()->lang; $thissurvey = getSurveyInfo($iSurveyID, $sBaseLanguage); $register_errormsg = ""; // Check the security question's answer if (function_exists("ImageCreate") && isCaptchaEnabled('registrationscreen', $thissurvey['usecaptcha'])) { if (!isset($_POST['loadsecurity']) || !isset($_SESSION['survey_' . $iSurveyID]['secanswer']) || Yii::app()->request->getPost('loadsecurity') != $_SESSION['survey_' . $iSurveyID]['secanswer']) { $register_errormsg .= $clang->gT("The answer to the security question is incorrect.") . "<br />\n"; } } //Check that the email is a valid style address if (!validateEmailAddress(Yii::app()->request->getPost('register_email'))) { $register_errormsg .= $clang->gT("The email you used is not valid. Please try again."); } // Check for additional fields $attributeinsertdata = array(); foreach (GetParticipantAttributes($iSurveyID) as $field => $data) { if (empty($data['show_register']) || $data['show_register'] != 'Y') { continue; } $value = sanitize_xss_string(Yii::app()->request->getPost('register_' . $field)); if (trim($value) == '' && $data['mandatory'] == 'Y') { $register_errormsg .= sprintf($clang->gT("%s cannot be left empty"), $thissurvey['attributecaptions'][$field]); } $attributeinsertdata[$field] = $value; } if ($register_errormsg != "") { $_SESSION['survey_' . $iSurveyID]['register_errormsg'] = $register_errormsg; $this->redirect($this->createUrl("survey/index/sid/{$iSurveyID}", array('lang' => $sBaseLanguage))); } //Check if this email already exists in token database $oToken = TokenDynamic::model($iSurveyID)->find('email=:email', array(':email' => Yii::app()->request->getPost('register_email'))); if ($oToken) { $register_errormsg = $clang->gT("The email you used has already been registered."); $_SESSION['survey_' . $iSurveyID]['register_errormsg'] = $register_errormsg; $this->redirect($this->createUrl("survey/index/sid/{$iSurveyID}", array('lang' => $sBaseLanguage))); //include "index.php"; //exit; } $mayinsert = false; // Get the survey settings for token length $tokenlength = $thissurvey['tokenlength']; //if tokenlength is not set or there are other problems use the default value (15) if (!isset($tokenlength) || $tokenlength == '') { $tokenlength = 15; } while ($mayinsert != true) { $newtoken = randomChars($tokenlength); $oTokenExist = TokenDynamic::model($iSurveyID)->find('token=:token', array(':token' => $newtoken)); if (!$oTokenExist) { $mayinsert = true; } } $postfirstname = sanitize_xss_string(strip_tags(Yii::app()->request->getPost('register_firstname'))); $postlastname = sanitize_xss_string(strip_tags(Yii::app()->request->getPost('register_lastname'))); $starttime = sanitize_xss_string(Yii::app()->request->getPost('startdate')); $endtime = sanitize_xss_string(Yii::app()->request->getPost('enddate')); /*$postattribute1=sanitize_xss_string(strip_tags(returnGlobal('register_attribute1'))); $postattribute2=sanitize_xss_string(strip_tags(returnGlobal('register_attribute2'))); */ // Insert new entry into tokens db $oToken = Token::create($thissurvey['sid']); $oToken->firstname = $postfirstname; $oToken->lastname = $postlastname; $oToken->email = Yii::app()->request->getPost('register_email'); $oToken->emailstatus = 'OK'; $oToken->token = $newtoken; if ($starttime && $endtime) { $oToken->validfrom = $starttime; $oToken->validuntil = $endtime; } $oToken->setAttributes($attributeinsertdata, false); $result = $oToken->save(); //$tid = $oToken->tid;// Not needed any more $fieldsarray["{ADMINNAME}"] = $thissurvey['adminname']; $fieldsarray["{ADMINEMAIL}"] = $thissurvey['adminemail']; $fieldsarray["{SURVEYNAME}"] = $thissurvey['name']; $fieldsarray["{SURVEYDESCRIPTION}"] = $thissurvey['description']; $fieldsarray["{FIRSTNAME}"] = $postfirstname; $fieldsarray["{LASTNAME}"] = $postlastname; $fieldsarray["{EXPIRY}"] = $thissurvey["expiry"]; $fieldsarray["{TOKEN}"] = $oToken->token; $fieldsarray["{EMAIL}"] = $oToken->email; $token = $oToken->token; $message = $thissurvey['email_register']; $subject = $thissurvey['email_register_subj']; $from = "{$thissurvey['adminname']} <{$thissurvey['adminemail']}>"; $surveylink = $this->createAbsoluteUrl("/survey/index/sid/{$iSurveyID}", array('lang' => $sBaseLanguage, 'token' => $newtoken)); $optoutlink = $this->createAbsoluteUrl("/optout/tokens/surveyid/{$iSurveyID}", array('langcode' => $sBaseLanguage, 'token' => $newtoken)); $optinlink = $this->createAbsoluteUrl("/optin/tokens/surveyid/{$iSurveyID}", array('langcode' => $sBaseLanguage, 'token' => $newtoken)); if (getEmailFormat($iSurveyID) == 'html') { $useHtmlEmail = true; $fieldsarray["{SURVEYURL}"] = "<a href='{$surveylink}'>" . $surveylink . "</a>"; $fieldsarray["{OPTOUTURL}"] = "<a href='{$optoutlink}'>" . $optoutlink . "</a>"; $fieldsarray["{OPTINURL}"] = "<a href='{$optinlink}'>" . $optinlink . "</a>"; } else { $useHtmlEmail = false; $fieldsarray["{SURVEYURL}"] = $surveylink; $fieldsarray["{OPTOUTURL}"] = $optoutlink; $fieldsarray["{OPTINURL}"] = $optinlink; } $message = ReplaceFields($message, $fieldsarray); $subject = ReplaceFields($subject, $fieldsarray); $html = ""; //Set variable $sitename = Yii::app()->getConfig('sitename'); if (SendEmailMessage($message, $subject, Yii::app()->request->getPost('register_email'), $from, $sitename, $useHtmlEmail, getBounceEmail($iSurveyID))) { // TLR change to put date into sent $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig('timeadjust')); $oToken->sent = $today; $oToken->save(); $html = "<div id='wrapper' class='message tokenmessage'>" . "<p>" . $clang->gT("Thank you for registering to participate in this survey.") . "</p>\n" . "<p>" . $clang->gT("An email has been sent to the address you provided with access details for this survey. Please follow the link in that email to proceed.") . "</p>\n" . "<p>" . $clang->gT("Survey administrator") . " {ADMINNAME} ({ADMINEMAIL})</p>" . "</div>\n"; $html = ReplaceFields($html, $fieldsarray); } else { $html = "Email Error"; } //PRINT COMPLETED PAGE if (!$thissurvey['template']) { $thistpl = getTemplatePath(validateTemplateDir('default')); } else { $thistpl = getTemplatePath(validateTemplateDir($thissurvey['template'])); } // Same fix than http://bugs.limesurvey.org/view.php?id=8441 ob_start(function ($buffer, $phase) { App()->getClientScript()->render($buffer); App()->getClientScript()->reset(); return $buffer; }); ob_implicit_flush(false); sendCacheHeaders(); doHeader(); Yii::app()->lang = $clang; // fetch the defined variables and pass it to the header footer templates. $redata = compact(array_keys(get_defined_vars())); $this->_printTemplateContent($thistpl . '/startpage.pstpl', $redata, __LINE__); $this->_printTemplateContent($thistpl . '/survey.pstpl', $redata, __LINE__); echo $html; $this->_printTemplateContent($thistpl . '/endpage.pstpl', $redata, __LINE__); doFooter(); ob_flush(); }