public function actionCron($interval)
{
$pm = \Yii::app()->pluginManager;
$event = new PluginEvent('cron');
$event->set('interval', $interval);
$pm->dispatchEvent($event);
}
public function actionPublicList($lang = null)
{
if (!empty($lang)) {
App()->setLanguage($lang);
} else {
App()->setLanguage(App()->getConfig('defaultlang'));
}
$oTemplate = Template::model()->getInstance(Yii::app()->getConfig("defaulttemplate"));
if ($oTemplate->cssFramework == 'bootstrap') {
// We now use the bootstrap package isntead of the Yiistrap TbApi::register() method
// Then instead of using the composer dependency system for templates
// We can use the package dependency system
Yii::app()->getClientScript()->registerMetaTag('width=device-width, initial-scale=1.0', 'viewport');
App()->bootstrap->registerAllScripts();
}
$aData = array('publicSurveys' => Survey::model()->active()->open()->public()->with('languagesettings')->findAll(), 'futureSurveys' => Survey::model()->active()->registration()->public()->with('languagesettings')->findAll());
$htmlOut = $this->render('publicSurveyList', $aData, true);
$event = new PluginEvent('beforeSurveysStartpageRender', $this);
$event->set('aData', $aData);
App()->getPluginManager()->dispatchEvent($event);
if ($event->get('result')) {
$htmlFromEvent = $event->get('result');
$htmlOut = $htmlFromEvent['html'];
}
echo $htmlOut;
}
/**
* method for dispatching plugin events
*
* See {@link find()} for detailed explanation about $condition and $params.
* @param string $sEventName event name to dispatch
* @param array $criteria array containing attributes, conditions and params for the filter query
* @return PluginEvent the dispatched event
*/
public function dispatchPluginModelEvent($sEventName, $criteria = null)
{
$oPluginEvent = new PluginEvent($sEventName, $this);
$oPluginEvent->set('model', $this->owner);
if (isset($criteria)) {
$oPluginEvent->set('filterCriteria', $criteria);
}
return App()->getPluginManager()->dispatchEvent($oPluginEvent);
}
/**
* Root function for any export results action
*
* @param mixed $iSurveyId
* @param mixed $sLanguageCode
* @param csv|doc|pdf|xls $sExportPlugin Type of export
* @param FormattingOptions $oOptions
* @param string $sFilter
*/
function exportSurvey($iSurveyId, $sLanguageCode, $sExportPlugin, FormattingOptions $oOptions, $sFilter = '')
{
//Do some input validation.
if (empty($iSurveyId)) {
safeDie('A survey ID must be supplied.');
}
if (empty($sLanguageCode)) {
safeDie('A language code must be supplied.');
}
if (empty($oOptions)) {
safeDie('Formatting options must be supplied.');
}
if (empty($oOptions->selectedColumns)) {
safeDie('At least one column must be selected for export.');
}
//echo $oOptions->toString().PHP_EOL;
$writer = null;
$iSurveyId = sanitize_int($iSurveyId);
if ($oOptions->output == 'display') {
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
}
$exports = $this->getExports();
if (array_key_exists($sExportPlugin, $exports) && !empty($exports[$sExportPlugin])) {
// This must be a plugin, now use plugin to load the right class
$event = new PluginEvent('newExport');
$event->set('type', $sExportPlugin);
$oPluginManager = App()->getPluginManager();
$oPluginManager->dispatchEvent($event, $exports[$sExportPlugin]);
$writer = $event->get('writer');
}
if (!$writer instanceof IWriter) {
throw new Exception(sprintf('Writer for %s should implement IWriter', $sExportPlugin));
}
$surveyDao = new SurveyDao();
$survey = $surveyDao->loadSurveyById($iSurveyId, $sLanguageCode);
$writer->init($survey, $sLanguageCode, $oOptions);
$surveyDao->loadSurveyResults($survey, $oOptions->responseMinRecord, $oOptions->responseMaxRecord, $sFilter, $oOptions->responseCompletionState);
$writer->write($survey, $sLanguageCode, $oOptions, true);
$result = $writer->close();
// Close resultset if needed
if ($survey->responses instanceof CDbDataReader) {
$survey->responses->close();
}
if ($oOptions->output == 'file') {
return $writer->filename;
} else {
return $result;
}
}
public function authenticate()
{
// First initialize the result, we can later retieve it to get the exact error code/message
$result = new LSAuthResult(self::ERROR_NONE);
// Check if the ip is locked out
if (FailedLoginAttempt::model()->isLockedOut()) {
$message = sprintf(gT('You have exceeded the number of maximum login attempts. Please wait %d minutes before trying again.'), App()->getConfig('timeOutTime') / 60);
$result->setError(self::ERROR_IP_LOCKED_OUT, $message);
}
// If still ok, continue
if ($result->isValid()) {
if (is_null($this->plugin)) {
$result->setError(self::ERROR_UNKNOWN_HANDLER);
} else {
// Delegate actual authentication to plugin
$authEvent = new PluginEvent('newUserSession', $this);
$authEvent->set('identity', $this);
App()->getPluginManager()->dispatchEvent($authEvent, array($this->plugin));
$pluginResult = $authEvent->get('result');
if ($pluginResult instanceof LSAuthResult) {
//print_r($pluginResult);
$result = $pluginResult;
} else {
//echo 'out result';
$result->setError(self::ERROR_UNKNOWN_IDENTITY);
}
}
}
if ($result->isValid()) {
// Perform postlogin
//exit('you are in post login');
$this->postLogin();
} else {
// Log a failed attempt
//exit('you login failed');
$userHostAddress = App()->request->getUserHostAddress();
FailedLoginAttempt::model()->addAttempt($userHostAddress);
App()->session->regenerateID();
// Handled on login by Yii
}
$this->errorCode = $result->getCode();
$this->errorMessage = $result->getMessage();
return $result->isValid();
}
/**
* Launch the event newUnsecureRequest
* @param $plugin : the target
* @param $function : the function to call from the plugin
*/
public function actionUnsecure($plugin, $function = null)
{
$oEvent = new PluginEvent('newUnsecureRequest');
// The intended target of the call.
$oEvent->set('target', $plugin);
// The name of the function.
$oEvent->set('function', $function);
$oEvent->set('request', App()->request);
App()->getPluginManager()->dispatchEvent($oEvent);
$sOutput = '';
foreach ($oEvent->getAllContent() as $content) {
$sOutput .= $content->getContent();
}
if (!empty($sOutput)) {
$this->renderText($sOutput);
}
}
/**
* Sets permissions (global or survey-specific) for a survey administrator
* Checks what permissions may be set and automatically filters invalid ones.
* A permission may be invalid if the permission does not exist or that particular user may not give that permission
*
* @param mixed $iUserID
* @param mixed $iEntityID
* @param mixed $sEntityName
* @param mixed $aPermissions
* @param mixed $bBypassCheck
*/
public static function setPermissions($iUserID, $iEntityID, $sEntityName, $aPermissions, $bBypassCheck = false)
{
$iUserID = sanitize_int($iUserID);
// Filter global permissions on save
if ($sEntityName == 'global') {
$aBasePermissions = Permission::model()->getGlobalBasePermissions();
if (!Permission::model()->hasGlobalPermission('superadmin', 'read') && !$bBypassCheck) {
// if not superadmin filter the available permissions as no admin may give more permissions than he owns
// Make sure that he owns the user he wants to give global permissions for
$oUser = User::model()->findByAttributes(array('uid' => $iUserID, 'parent_id' => Yii::app()->session['loginID']));
if (!$oUser) {
die('You are not allowed to set permisisons for this user');
}
$aFilteredPermissions = array();
foreach ($aBasePermissions as $PermissionName => $aPermission) {
foreach ($aPermission as $sPermissionKey => &$sPermissionValue) {
if ($sPermissionKey != 'title' && $sPermissionKey != 'img' && !Permission::model()->hasGlobalPermission($PermissionName, $sPermissionKey)) {
$sPermissionValue = false;
}
}
// Only have a row for that permission if there is at least one permission he may give to other users
if ($aPermission['create'] || $aPermission['read'] || $aPermission['update'] || $aPermission['delete'] || $aPermission['import'] || $aPermission['export']) {
$aFilteredPermissions[$PermissionName] = $aPermission;
}
}
$aBasePermissions = $aFilteredPermissions;
} elseif (Permission::model()->hasGlobalPermission('superadmin', 'read') && Yii::app()->session['loginID'] != 1) {
unset($aBasePermissions['superadmin']);
}
} elseif ($sEntityName == 'survey') {
$aBasePermissions = Permission::model()->getSurveyBasePermissions();
}
$aFilteredPermissions = array();
foreach ($aBasePermissions as $sPermissionname => $aPermission) {
$aFilteredPermissions[$sPermissionname]['create'] = isset($aPermissions[$sPermissionname]['create']) && $aPermissions[$sPermissionname]['create'];
$aFilteredPermissions[$sPermissionname]['read'] = isset($aPermissions[$sPermissionname]['read']) && $aPermissions[$sPermissionname]['read'];
$aFilteredPermissions[$sPermissionname]['update'] = isset($aPermissions[$sPermissionname]['update']) && $aPermissions[$sPermissionname]['update'];
$aFilteredPermissions[$sPermissionname]['delete'] = isset($aPermissions[$sPermissionname]['delete']) && $aPermissions[$sPermissionname]['delete'];
$aFilteredPermissions[$sPermissionname]['import'] = isset($aPermissions[$sPermissionname]['import']) && $aPermissions[$sPermissionname]['import'];
$aFilteredPermissions[$sPermissionname]['export'] = isset($aPermissions[$sPermissionname]['export']) && $aPermissions[$sPermissionname]['export'];
}
$condition = array('entity_id' => $iEntityID, 'uid' => $iUserID);
$oEvent = new PluginEvent('beforePermissionSetSave');
$oEvent->set('aNewPermissions', $aFilteredPermissions);
$oEvent->set('iSurveyID', $iEntityID);
$oEvent->set('iUserID', $iUserID);
$result = App()->getPluginManager()->dispatchEvent($oEvent);
// Only the original superadmin may change the superadmin permissions
if (Yii::app()->session['loginID'] != 1) {
Permission::model()->deleteAllByAttributes($condition, "permission <> 'superadmin'");
} else {
Permission::model()->deleteAllByAttributes($condition);
}
foreach ($aFilteredPermissions as $sPermissionname => $aPermission) {
if ($aPermission['create'] || $aPermission['read'] || $aPermission['update'] || $aPermission['delete'] || $aPermission['import'] || $aPermission['export']) {
$data = array('entity_id' => $iEntityID, 'entity' => $sEntityName, 'uid' => $iUserID, 'permission' => $sPermissionname, 'create_p' => (int) $aPermission['create'], 'read_p' => (int) $aPermission['read'], 'update_p' => (int) $aPermission['update'], 'delete_p' => (int) $aPermission['delete'], 'import_p' => (int) $aPermission['import'], 'export_p' => (int) $aPermission['export']);
$permission = new self();
foreach ($data as $k => $v) {
$permission->{$k} = $v;
}
$permission->save();
}
}
return true;
}
//.........这里部分代码省略.........
/*
* Get attachments.
*/
if ($sSubAction == 'email') {
$sTemplate = 'invitation';
} elseif ($sSubAction == 'remind') {
$sTemplate = 'reminder';
}
$aRelevantAttachments = array();
if (isset($aData['thissurvey'][$emrow['language']]['attachments'])) {
$aAttachments = unserialize($aData['thissurvey'][$emrow['language']]['attachments']);
if (!empty($aAttachments)) {
if (isset($aAttachments[$sTemplate])) {
LimeExpressionManager::singleton()->loadTokenInformation($aData['thissurvey']['sid'], $emrow['token']);
foreach ($aAttachments[$sTemplate] as $aAttachment) {
if (LimeExpressionManager::singleton()->ProcessRelevance($aAttachment['relevance'])) {
$aRelevantAttachments[] = $aAttachment['url'];
}
}
}
}
}
/**
* Event for email handling.
* Parameter type description:
* subject rw Body of the email
* to rw Recipient(s)
* from rw Sender(s)
* type r "invitation" or "reminder"
* send w If true limesurvey will send the email. Setting this to false will cause limesurvey to assume the mail has been sent by the plugin.
* error w If set and "send" is true, log the error as failed email attempt.
* token r Raw token data.
*/
$event = new PluginEvent('beforeTokenEmail');
$event->set('type', $sTemplate);
$event->set('subject', $modsubject);
$event->set('to', $to);
$event->set('body', $modmessage);
$event->set('from', $from);
$event->set('bounce', getBounceEmail($iSurveyId));
$event->set('token', $emrow);
App()->getPluginManager()->dispatchEvent($event);
$modsubject = $event->get('subject');
$modmessage = $event->get('body');
$to = $event->get('to');
$from = $event->get('from');
if ($event->get('send', true) == false) {
// This is some ancient global used for error reporting instead of a return value from the actual mail function..
$maildebug = $event->get('error', $maildebug);
$success = $event->get('error') == null;
} else {
$success = SendEmailMessage($modmessage, $modsubject, $to, $from, Yii::app()->getConfig("sitename"), $bHtml, getBounceEmail($iSurveyId), $aRelevantAttachments, $customheaders);
}
if ($success) {
// Put date into sent
$token = Token::model($iSurveyId)->findByPk($emrow['tid']);
if ($bEmail) {
$tokenoutput .= $clang->gT("Invitation sent to:");
$token->sent = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust"));
} else {
$tokenoutput .= $clang->gT("Reminder sent to:");
$token->remindersent = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust"));
$token->remindercount++;
}
$token->save();
//Update central participant survey_links
/**
* Checks if a user has a certain permission
*
* @param $iEntityID integer The entity ID
* @param $sEntityName string The entity name
* @param $sPermission string Name of the permission
* @param $sCRUD string The permission detail you want to check on: 'create','read','update','delete','import' or 'export'
* @param $iUserID integer User ID - if not given the one of the current user is used
* @return bool True if user has the permission
*/
function hasPermission($iEntityID, $sEntityName, $sPermission, $sCRUD = 'read', $iUserID = null)
{
static $aPermissionStatic;
$oEvent = new PluginEvent('beforeHasPermission');
$oEvent->set('iEntityID', $iEntityID);
$oEvent->set('sEntityName', $sEntityName);
$oEvent->set('sPermission', $sPermission);
$oEvent->set('sCRUD', $sCRUD);
$oEvent->set('iUserID', $iUserID);
App()->getPluginManager()->dispatchEvent($oEvent);
$pluginbPermission = $oEvent->get('bPermission');
// isset — Determine if a variable is set and is not NULL. And isset seems little speedest.
if (isset($pluginbPermission)) {
return $pluginbPermission;
}
if (!in_array($sCRUD, array('create', 'read', 'update', 'delete', 'import', 'export'))) {
return false;
}
$sCRUD = $sCRUD . '_p';
$iUserID = self::getUserId($iUserID);
if (!$iUserID) {
return false;
}
// Check if superadmin and cache it
if (!isset($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'])) {
$aPermission = $this->findByAttributes(array("entity_id" => 0, 'entity' => 'global', "uid" => $iUserID, "permission" => 'superadmin'));
$bPermission = is_null($aPermission) ? array() : $aPermission->attributes;
if (!isset($bPermission['read_p']) || $bPermission['read_p'] == 0) {
$bPermission = false;
} else {
$bPermission = true;
}
$aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p'] = $bPermission;
}
if ($aPermissionStatic[0]['global'][$iUserID]['superadmin']['read_p']) {
return true;
}
if (!isset($aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD])) {
$query = $this->findByAttributes(array("entity_id" => $iEntityID, "uid" => $iUserID, "entity" => $sEntityName, "permission" => $sPermission));
$bPermission = is_null($query) ? array() : $query->attributes;
if (!isset($bPermission[$sCRUD]) || $bPermission[$sCRUD] == 0) {
$bPermission = false;
} else {
$bPermission = true;
}
$aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD] = $bPermission;
}
return $aPermissionStatic[$iEntityID][$sEntityName][$iUserID][$sPermission][$sCRUD];
}
/**
* This function dispatches an event to all registered plugins.
* @param PluginEvent $event Object holding all event properties
* @param string|array $target Optional name of plugin to fire the event on
*
* @return PluginEvent
*/
public function dispatchEvent(PluginEvent $event, $target = array())
{
$eventName = $event->getEventName();
if (is_string($target)) {
$target = array($target);
}
if (isset($this->subscriptions[$eventName])) {
foreach ($this->subscriptions[$eventName] as $subscription) {
if (!$event->isStopped() && (empty($target) || in_array(get_class($subscription[0]), $target))) {
$subscription[0]->setEvent($event);
call_user_func($subscription);
}
}
}
return $event;
}
/**
* checkCompletedQuota() returns matched quotas information for the current response
* @param integer $surveyid - Survey identification number
* @param bool $return - set to true to return information, false do the quota
* @return array|void - nested array, Quotas->Members->Fields, includes quota information matched in session.
*/
function checkCompletedQuota($surveyid, $return = false)
{
/* Check if session is set */
if (!isset(App()->session['survey_' . $surveyid]['srid'])) {
return;
}
/* Check is Response is already submitted : only when "do" the quota: allow to send information about quota */
$oResponse = Response::model($surveyid)->findByPk(App()->session['survey_' . $surveyid]['srid']);
if (!$return && $oResponse && !is_null($oResponse->submitdate)) {
return;
}
static $aMatchedQuotas;
// EM call 2 times quotas with 3 lines of php code, then use static.
if (!$aMatchedQuotas) {
$aMatchedQuotas = array();
$quota_info = $aQuotasInfo = getQuotaInformation($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']);
// $aQuotasInfo have an 'active' key, we don't use it ?
if (!$aQuotasInfo || empty($aQuotasInfo)) {
return $aMatchedQuotas;
}
// OK, we have some quota, then find if this $_SESSION have some set
$aPostedFields = explode("|", Yii::app()->request->getPost('fieldnames', ''));
// Needed for quota allowing update
foreach ($aQuotasInfo as $aQuotaInfo) {
if (count($aQuotaInfo['members']) === 0) {
continue;
}
$iMatchedAnswers = 0;
$bPostedField = false;
// Array of field with quota array value
$aQuotaFields = array();
// Array of fieldnames with relevance value : EM fill $_SESSION with default value even is unrelevant (em_manager_helper line 6548)
$aQuotaRelevantFieldnames = array();
// To count number of hidden questions
$aQuotaQid = array();
foreach ($aQuotaInfo['members'] as $aQuotaMember) {
$aQuotaFields[$aQuotaMember['fieldname']][] = $aQuotaMember['value'];
$aQuotaRelevantFieldnames[$aQuotaMember['fieldname']] = isset($_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']]) && $_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']];
$aQuotaQid[] = $aQuotaMember['qid'];
}
$aQuotaQid = array_unique($aQuotaQid);
// For each field : test if actual responses is in quota (and is relevant)
foreach ($aQuotaFields as $sFieldName => $aValues) {
$bInQuota = isset($_SESSION['survey_' . $surveyid][$sFieldName]) && in_array($_SESSION['survey_' . $surveyid][$sFieldName], $aValues);
if ($bInQuota && $aQuotaRelevantFieldnames[$sFieldName]) {
$iMatchedAnswers++;
}
if (in_array($sFieldName, $aPostedFields)) {
// Need only one posted value
$bPostedField = true;
}
}
// Condition to count quota : Answers are the same in quota + an answer is submitted at this time (bPostedField) OR all questions is hidden (bAllHidden)
$bAllHidden = QuestionAttribute::model()->countByAttributes(array('qid' => $aQuotaQid), 'attribute=:attribute', array(':attribute' => 'hidden')) == count($aQuotaQid);
if ($iMatchedAnswers == count($aQuotaFields) && ($bPostedField || $bAllHidden)) {
if ($aQuotaInfo['qlimit'] == 0) {
// Always add the quota if qlimit==0
$aMatchedQuotas[] = $aQuotaInfo;
} else {
$iCompleted = getQuotaCompletedCount($surveyid, $aQuotaInfo['id']);
if (!is_null($iCompleted) && (int) $iCompleted >= (int) $aQuotaInfo['qlimit']) {
// This remove invalid quota and not completed
$aMatchedQuotas[] = $aQuotaInfo;
}
}
}
}
}
if ($return) {
return $aMatchedQuotas;
}
if (empty($aMatchedQuotas)) {
return;
}
// Now we have all the information we need about the quotas and their status.
// We need to construct the page and do all needed action
$aSurveyInfo = getSurveyInfo($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']);
$oTemplate = Template::model()->getInstance('', $surveyid);
$sTemplatePath = $oTemplate->path;
$sTemplateViewPath = $oTemplate->viewPath;
$sClientToken = isset($_SESSION['survey_' . $surveyid]['token']) ? $_SESSION['survey_' . $surveyid]['token'] : "";
// $redata for templatereplace
$aDataReplacement = array('thissurvey' => $aSurveyInfo, 'clienttoken' => $sClientToken, 'token' => $sClientToken);
// We take only the first matched quota, no need for each
$aMatchedQuota = $aMatchedQuotas[0];
// If a token is used then mark the token as completed, do it before event : this allow plugin to update token information
$event = new PluginEvent('afterSurveyQuota');
$event->set('surveyId', $surveyid);
$event->set('responseId', $_SESSION['survey_' . $surveyid]['srid']);
// We allways have a responseId
$event->set('aMatchedQuotas', $aMatchedQuotas);
// Give all the matched quota : the first is the active
App()->getPluginManager()->dispatchEvent($event);
$blocks = array();
//.........这里部分代码省略.........
请发表评论