/** * 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 - nested array, Quotas->Members->Fields, includes quota information matched in session. */ function checkCompletedQuota($surveyid, $return = false) { if (!isset($_SESSION['survey_' . $surveyid]['srid'])) { 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; } // Test only completed quota, other is not needed $aQuotasCompleted = array(); foreach ($aQuotasInfo as $aQuotaInfo) { $iCompleted = getQuotaCompletedCount($surveyid, $aQuotaInfo['id']); // Return a string if (ctype_digit($iCompleted) && (int) $iCompleted >= (int) $aQuotaInfo['qlimit']) { // This remove invalid quota and not completed $aQuotasCompleted[] = $aQuotaInfo; } } if (empty($aQuotasCompleted)) { 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 ($aQuotasCompleted as $aQuotaCompleted) { $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(); foreach ($aQuotaCompleted['members'] as $aQuotaMember) { $aQuotaFields[$aQuotaMember['fieldname']][] = $aQuotaMember['value']; $aQuotaRelevantFieldnames[$aQuotaMember['fieldname']] = isset($_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']]) && $_SESSION['survey_' . $surveyid]['relevanceStatus'][$aQuotaMember['qid']]; } // 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)) { $bPostedField = true; } } if ($iMatchedAnswers == count($aQuotaFields)) { switch ($aQuotaCompleted['action']) { case '1': default: $aMatchedQuotas[] = $aQuotaCompleted; break; case '2': if ($bPostedField) { // Action 2 allow to correct last answers, then need to be posted $aMatchedQuotas[] = $aQuotaCompleted; } break; } } } } 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']); $sTemplatePath = getTemplatePath($aSurveyInfo['templatedir']); $sClientToken = isset($_SESSION['survey_' . $surveyid]['token']) ? $_SESSION['survey_' . $surveyid]['token'] : ""; // {TOKEN} is take by $redata ... // $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(); foreach ($event->getAllContent() as $blockData) { /* @var $blockData PluginEventContent */ $blocks[] = CHtml::tag('div', array('id' => $blockData->getCssId(), 'class' => $blockData->getCssClass()), $blockData->getContent()); } // Allow plugin to update message, url, url description and action $sMessage = $event->get('message', $aMatchedQuota['quotals_message']); $sUrl = $event->get('url', $aMatchedQuota['quotals_url']); $sUrlDescription = $event->get('urldescrip', $aMatchedQuota['quotals_urldescrip']); $sAction = $event->get('action', $aMatchedQuota['action']); $sAutoloadUrl = $event->get('autoloadurl', $aMatchedQuota['autoload_url']); // Construct the default message $sMessage = templatereplace($sMessage, array(), $aDataReplacement, 'QuotaMessage', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true); $sUrl = passthruReplace($sUrl, $aSurveyInfo); $sUrl = templatereplace($sUrl, array(), $aDataReplacement, 'QuotaUrl', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true); $sUrlDescription = templatereplace($sUrlDescription, array(), $aDataReplacement, 'QuotaUrldescription', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true); // Doing the action and show the page if ($sAction == "1" && $sClientToken) { submittokens(true); } // Construction of default message inside quotamessage class $quotaMessage = "<div class='quotamessage limesurveycore'>\n"; $quotaMessage .= "\t" . $sMessage . "\n"; if ($sUrl) { $quotaMessage .= "<br /><br />\t<a href='" . $sUrl . "'>" . $sUrlDescription . "</a><br />\n"; } // Add the navigator with Previous button if quota allow modification. if ($sAction == "2") { $sQuotaStep = isset($_SESSION['survey_' . $surveyid]['step']) ? $_SESSION['survey_' . $surveyid]['step'] : 0; // Surely not needed $sNavigator = CHtml::htmlButton(gT("Previous"), array('type' => 'submit', 'id' => "moveprevbtn", 'value' => $sQuotaStep, 'name' => 'move', 'accesskey' => 'p', 'class' => "submit button")); $quotaMessage .= CHtml::form(array("/survey/index"), 'post', array('id' => 'limesurvey', 'name' => 'limesurvey')); $quotaMessage .= templatereplace(file_get_contents($sTemplatePath . "/navigator.pstpl"), array('NAVIGATOR' => $sNavigator, 'SAVE' => ''), $aDataReplacement); $quotaMessage .= CHtml::hiddenField('sid', $surveyid); $quotaMessage .= CHtml::hiddenField('token', $sClientToken); // Did we really need it ? $quotaMessage .= CHtml::endForm(); } $quotaMessage .= "</div>\n"; // Add the plugin message before default message $quotaMessage = implode("\n", $blocks) . "\n" . $quotaMessage; // Send page to user and end. sendCacheHeaders(); if ($sAutoloadUrl == 1 && $sUrl != "") { if ($sAction == "1") { killSurveySession($surveyid); } header("Location: " . $sUrl); } doHeader(); echo templatereplace(file_get_contents($sTemplatePath . "/startpage.pstpl"), array(), $aDataReplacement); echo $quotaMessage; echo templatereplace(file_get_contents($sTemplatePath . "/endpage.pstpl"), array(), $aDataReplacement); doFooter(); if ($sAction == "1") { killSurveySession($surveyid); } Yii::app()->end(); }
function index($iSurveyId, $quickreport = false) { $iSurveyId = sanitize_int($iSurveyId); $this->_checkPermissions($iSurveyId, 'read'); $aData = $this->_getData($iSurveyId); $aViewUrls = array(); if ($quickreport == false) { $aViewUrls[] = 'viewquotas_view'; } $aData['surveyid'] = $iSurveyID = $surveyid = sanitize_int($iSurveyId); $aData['sidemenu']['state'] = false; $surveyinfo = Survey::model()->findByPk($iSurveyID)->surveyinfo; $aData['title_bar']['title'] = $surveyinfo['surveyls_title'] . "(" . gT("ID") . ":" . $iSurveyID . ")"; //$aData['surveybar']['active_survey_properties'] = 'quotas'; $aData['surveybar']['buttons']['view'] = TRUE; $aData['surveybar']['active_survey_properties']['img'] = 'quota'; $aData['surveybar']['active_survey_properties']['txt'] = gT("Quotas"); $aData['surveybar']['closebutton']['url'] = 'admin/survey/sa/view/surveyid/' . $iSurveyID; // Close button $aData['surveybar']['closebutton']['forbidden'][] = 'quotas'; $totalquotas = 0; $totalcompleted = 0; $csvoutput = array(); $criteria = new CDbCriteria(); $criteria->select = '*'; $criteria->join = 'LEFT JOIN {{quota_languagesettings}} as qls ON (t.id = qls.quotals_quota_id)'; $criteria->condition = 'sid=:survey AND quotals_language=:lang'; $criteria->params = array(':survey' => $iSurveyId, ':lang' => $aData['sBaseLang']); $criteria->order = 'name'; $aResult = Quota::model()->findAll($criteria); //if there are quotas let's proceed $aViewUrls['output'] = ''; if (count($aResult) > 0) { $aData['output'] = ''; //loop through all quotas foreach ($aResult as $aQuotaListing) { $totalquotas += $aQuotaListing['qlimit']; $completed = getQuotaCompletedCount($iSurveyId, $aQuotaListing['id']); $highlight = $completed >= $aQuotaListing['qlimit'] ? '' : "style='color: orange'"; //Incomplete quotas displayed in red $totalcompleted = $totalcompleted + $completed; $csvoutput[] = $aQuotaListing['name'] . "," . $aQuotaListing['qlimit'] . "," . $completed . "," . ($aQuotaListing['qlimit'] - $completed) . "\r\n"; if ($quickreport != false) { continue; } $aData['quotalisting'] = $aQuotaListing; $aData['highlight'] = $highlight; $aData['completed'] = $completed; $aData['totalquotas'] = $totalquotas; $aData['totalcompleted'] = $totalcompleted; $aViewUrls['output'] .= $this->getController()->renderPartial("/admin/quotas/viewquotasrow_view", $aData, true); $aData['output'] .= $this->getController()->renderPartial("/admin/quotas/viewquotasrow_view", $aData, true); //check how many sub-elements exist for a certain quota $aResults2 = QuotaMember::model()->findAllByAttributes(array('quota_id' => $aQuotaListing['id'])); //loop through all sub-parts foreach ($aResults2 as $aQuotaQuestions) { $aQuestionAnswers = self::getQuotaAnswers($aQuotaQuestions['qid'], $iSurveyId, $aQuotaListing['id']); $aData['question_answers'] = $aQuestionAnswers; $aData['quota_questions'] = $aQuotaQuestions; $aViewUrls['output'] .= $this->getController()->renderPartial('/admin/quotas/viewquotasrowsub_view', $aData, true); //$aData['output'] .= $this->getController()->renderPartial('/admin/quotas/viewquotasrowsub_view', $aData, true); } } } else { // No quotas have been set for this survey //$aViewUrls[] = 'viewquotasempty_view'; $aData['output'] = $this->getController()->renderPartial('/admin/quotas/viewquotasempty_view', $aData, true); } $aData['totalquotas'] = $totalquotas; $aData['totalcompleted'] = $totalcompleted; if ($quickreport == false) { //$aViewUrls[] = 'viewquotasfooter_view'; $aViewUrls['output'] .= $this->getController()->renderPartial('/admin/quotas/viewquotasfooter_view', $aData, true); $this->_renderWrappedTemplate('quotas', $aViewUrls, $aData); } else { //// WHY ??????? header("Content-Disposition: attachment; filename=results-survey" . $iSurveyId . ".csv"); header("Content-type: text/comma-separated-values; charset=UTF-8"); header("Pragma: public"); echo gT("Quota name") . "," . gT("Limit") . "," . gT("Completed") . "," . gT("Remaining") . "\r\n"; foreach ($csvoutput as $line) { echo $line; } die; } }
/** * 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(); foreach ($event->getAllContent() as $blockData) { /* @var $blockData PluginEventContent */ $blocks[] = CHtml::tag('div', array('id' => $blockData->getCssId(), 'class' => $blockData->getCssClass()), $blockData->getContent()); } // Allow plugin to update message, url, url description and action $sMessage = $event->get('message', $aMatchedQuota['quotals_message']); $sUrl = $event->get('url', $aMatchedQuota['quotals_url']); $sUrlDescription = $event->get('urldescrip', $aMatchedQuota['quotals_urldescrip']); $sAction = $event->get('action', $aMatchedQuota['action']); $sAutoloadUrl = $event->get('autoloadurl', $aMatchedQuota['autoload_url']); // Doing the action and show the page if ($sAction == "1" && $sClientToken) { submittokens(true); } // Construct the default message $sMessage = templatereplace($sMessage, array(), $aDataReplacement, 'QuotaMessage', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true); $sUrl = passthruReplace($sUrl, $aSurveyInfo); $sUrl = templatereplace($sUrl, array(), $aDataReplacement, 'QuotaUrl', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true); $sUrlDescription = templatereplace($sUrlDescription, array(), $aDataReplacement, 'QuotaUrldescription', $aSurveyInfo['anonymized'] != 'N', NULL, array(), true); // Construction of default message inside quotamessage class $sHtmlQuotaMessage = "<div class='quotamessage limesurveycore'>\n"; $sHtmlQuotaMessage .= "\t" . $sMessage . "\n"; $sHtmlQuotaUrl = $sUrl ? "<a href='" . $sUrl . "'>" . $sUrlDescription . "</a>" : ""; // Add the navigator with Previous button if quota allow modification. if ($sAction == "2") { $sQuotaStep = isset($_SESSION['survey_' . $surveyid]['step']) ? $_SESSION['survey_' . $surveyid]['step'] : 0; // Surely not needed $sNavigator = CHtml::htmlButton(gT("Previous"), array('type' => 'submit', 'id' => "moveprevbtn", 'value' => $sQuotaStep, 'name' => 'move', 'accesskey' => 'p', 'class' => "submit button btn btn-default")); //$sNavigator .= " ".CHtml::htmlButton(gT("Submit"),array('type'=>'submit','id'=>"movesubmit",'value'=>"movesubmit",'name'=>"movesubmit",'accesskey'=>'l','class'=>"submit button")); $sHtmlQuotaMessage .= CHtml::form(array("/survey/index", "sid" => $surveyid), 'post', array('id' => 'limesurvey', 'name' => 'limesurvey', 'class' => 'survey-form-container QuotaMessage')); $sHtmlQuotaMessage .= templatereplace(file_get_contents($sTemplateViewPath . "/navigator.pstpl"), array('NAVIGATOR' => $sNavigator, 'SAVE' => ''), $aDataReplacement); $sHtmlQuotaMessage .= CHtml::hiddenField('sid', $surveyid); $sHtmlQuotaMessage .= CHtml::hiddenField('token', $sClientToken); // Did we really need it ? $sHtmlQuotaMessage .= CHtml::endForm(); } $sHtmlQuotaMessage .= "</div>\n"; // Add the plugin message before default message $sHtmlQuotaMessage = implode("\n", $blocks) . "\n" . $sHtmlQuotaMessage; // Send page to user and end. sendCacheHeaders(); if ($sAutoloadUrl == 1 && $sUrl != "") { if ($sAction == "1") { killSurveySession($surveyid); } header("Location: " . $sUrl); } doHeader(); echo templatereplace(file_get_contents($sTemplateViewPath . "/startpage.pstpl"), array(), $aDataReplacement); echo templatereplace(file_get_contents($sTemplateViewPath . "/completed.pstpl"), array("COMPLETED" => $sHtmlQuotaMessage, "URL" => $sHtmlQuotaUrl), $aDataReplacement); echo templatereplace(file_get_contents($sTemplateViewPath . "/endpage.pstpl"), array(), $aDataReplacement); doFooter(); if ($sAction == "1") { killSurveySession($surveyid); } Yii::app()->end(); }