/** * Returns the number of answers matching the quota * * @param int $iSurveyId - Survey identification number * @param int $quotaid - quota id for which you want to compute the completed field * @return mixed - value of matching entries in the result DB or null */ function getQuotaCompletedCount($iSurveyId, $quotaid) { if (!tableExists("survey_{$iSurveyId}")) { // Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}' are not updated even after Yii::app()->db->schema->refresh(); return; } $aColumnName = SurveyDynamic::model($iSurveyId)->getTableSchema()->getColumnNames(); $aQuotas = getQuotaInformation($iSurveyId, Survey::model()->findByPk($iSurveyId)->language, $quotaid); $aQuota = $aQuotas[0]; if (Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}') && count($aQuota['members']) > 0) { // Keep a list of fields for easy reference $aQuotaColumns = array(); foreach ($aQuota['members'] as $member) { if (in_array($member['fieldname'], $aColumnName)) { $aQuotaColumns[$member['fieldname']][] = $member['value']; } else { return; } } $oCriteria = new CDbCriteria(); $oCriteria->condition = "submitdate IS NOT NULL"; foreach ($aQuotaColumns as $sColumn => $aValue) { if (count($aValue) == 1) { $oCriteria->compare(Yii::app()->db->quoteColumnName($sColumn), $aValue); // NO need params : compare bind } else { $oCriteria->addInCondition(Yii::app()->db->quoteColumnName($sColumn), $aValue); // NO need params : addInCondition bind } } return SurveyDynamic::model($iSurveyId)->count($oCriteria); } }
/** * checkQuota() returns quota information for the current survey * @param string $checkaction - action the function must take after completing: * enforce: Enforce the Quota action * return: Return the updated quota array from getQuotaAnswers() * @param string $surveyid - Survey identification number * @return array - nested array, Quotas->Members->Fields, includes quota status and which members matched in session. */ function checkQuota($checkaction, $surveyid) { global $clienttoken; if (!isset($_SESSION['survey_' . $surveyid]['srid'])) { return; } $thissurvey = getSurveyInfo($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']); $sTemplatePath = getTemplatePath($thissurvey['templatedir']); $global_matched = false; $quota_info = getQuotaInformation($surveyid, $_SESSION['survey_' . $surveyid]['s_lang']); $x = 0; $clang = Yii::app()->lang; if (count($quota_info) > 0) { // Check each quota on saved data to see if it is full $querycond = array(); foreach ($quota_info as $quota) { if (count($quota['members']) > 0) { $fields_list = array(); // Keep a list of fields for easy reference $y = 0; // We need to make the conditions for the select statement here unset($querycond); // fill the array of value and query for each fieldnames $fields_value_array = array(); $fields_query_array = array(); foreach ($quota['members'] as $member) { foreach ($member['fieldnames'] as $fieldname) { if (!in_array($fieldname, $fields_list)) { $fields_list[] = $fieldname; $fields_value_array[$fieldname] = array(); $fields_query_array[$fieldname] = array(); } $fields_value_array[$fieldname][] = $member['value']; $fields_query_array[$fieldname][] = dbQuoteID($fieldname) . " = '{$member['value']}'"; } } // fill the $querycond array with each fields_query grouped by fieldname foreach ($fields_list as $fieldname) { $select_query = " ( " . implode(' OR ', $fields_query_array[$fieldname]) . ' )'; $querycond[] = $select_query; } // Test if the fieldname is in the array of value in the session foreach ($quota['members'] as $member) { foreach ($member['fieldnames'] as $fieldname) { if (isset($_SESSION['survey_' . $surveyid][$fieldname])) { if (in_array($_SESSION['survey_' . $surveyid][$fieldname], $fields_value_array[$fieldname])) { $quota_info[$x]['members'][$y]['insession'] = "true"; } } } $y++; } unset($fields_query_array); unset($fields_value_array); // Lets only continue if any of the quota fields is in the posted page $matched_fields = false; if (isset($_POST['fieldnames'])) { $posted_fields = explode("|", $_POST['fieldnames']); foreach ($fields_list as $checkfield) { if (in_array($checkfield, $posted_fields)) { $matched_fields = true; $global_matched = true; } } } // A field was submitted that is part of the quota if ($matched_fields == true) { // Check the status of the quota, is it full or not $sQuery = "SELECT count(id) FROM {{survey_" . $surveyid . "}}\n WHERE " . implode(' AND ', $querycond) . " " . "\n AND submitdate IS NOT NULL"; $iRowCount = Yii::app()->db->createCommand($sQuery)->queryScalar(); if ($iRowCount >= $quota['Limit']) { // Now we have to check if the quota matches in the current session // This will let us know if this person is going to exceed the quota $counted_matches = 0; foreach ($quota_info[$x]['members'] as $member) { if (isset($member['insession']) && $member['insession'] == "true") { $counted_matches++; } } if ($counted_matches == count($quota['members'])) { // They are going to exceed the quota if data is submitted $quota_info[$x]['status'] = "matched"; } else { $quota_info[$x]['status'] = "notmatched"; } } else { // Quota is no in danger of being exceeded. $quota_info[$x]['status'] = "notmatched"; } } } $x++; } } else { return false; } // Now we have all the information we need about the quotas and their status. // Lets see what we should do now if ($checkaction == 'return') { return $quota_info; } elseif ($global_matched == true && $checkaction == 'enforce') { // Need to add Quota action enforcement here. reset($quota_info); $tempmsg = ""; $found = false; $redata = compact(array_keys(get_defined_vars())); foreach ($quota_info as $quota) { $quota['Message'] = templatereplace($quota['Message'], array(), $redata); $quota['Url'] = passthruReplace($quota['Url'], $thissurvey); $quota['Url'] = templatereplace($quota['Url'], array(), $redata); $quota['UrlDescrip'] = templatereplace($quota['UrlDescrip'], array(), $redata); if (isset($quota['status']) && $quota['status'] == "matched" && (isset($quota['Action']) && $quota['Action'] == "1")) { // If a token is used then mark the token as completed if (isset($clienttoken) && $clienttoken) { submittokens(true); } sendCacheHeaders(); if ($quota['AutoloadUrl'] == 1 && $quota['Url'] != "") { header("Location: " . $quota['Url']); killSurveySession($surveyid); } doHeader(); echo templatereplace(file_get_contents($sTemplatePath . "/startpage.pstpl"), array(), $redata, 'frontend_helper[2617]'); echo "\t<div class='quotamessage'>\n"; echo "\t" . $quota['Message'] . "<br /><br />\n"; echo "\t<a href='" . $quota['Url'] . "'>" . $quota['UrlDescrip'] . "</a><br />\n"; echo "\t</div>\n"; echo templatereplace(file_get_contents($sTemplatePath . "/endpage.pstpl"), array(), $redata, 'frontend_helper[2622]'); doFooter(); killSurveySession($surveyid); exit; } if (isset($quota['status']) && $quota['status'] == "matched" && (isset($quota['Action']) && $quota['Action'] == "2")) { sendCacheHeaders(); doHeader(); $redata = compact(array_keys(get_defined_vars())); echo templatereplace(file_get_contents($sTemplatePath . "/startpage.pstpl"), array(), $redata, 'frontend_helper[2634]'); echo "\t<div class='quotamessage'>\n"; echo "\t" . $quota['Message'] . "<br /><br />\n"; echo "\t<a href='" . $quota['Url'] . "'>" . $quota['UrlDescrip'] . "</a><br />\n"; echo CHtml::form(array("/survey/index"), 'post', array('id' => 'limesurvey', 'name' => 'limesurvey')) . "\n <input type='hidden' name='move' value='movenext' id='movenext' />\n <button class='nav-button nav-button-icon-left ui-corner-all' class='submit' accesskey='p' onclick=\"javascript:document.limesurvey.move.value = 'moveprev'; document.limesurvey.submit();\" id='moveprevbtn'>" . $clang->gT("Previous") . "</button>\n <input type='hidden' name='thisstep' value='" . $_SESSION['survey_' . $surveyid]['step'] . "' id='thisstep' />\n <input type='hidden' name='sid' value='" . returnGlobal('sid') . "' id='sid' />\n <input type='hidden' name='token' value='" . $clienttoken . "' id='token' />\n </form>\n"; echo "\t</div>\n"; echo templatereplace(file_get_contents($sTemplatePath . "/endpage.pstpl"), array(), $redata, 'frontend_helper[2644]'); doFooter(); exit; } } } else { // Unknown value return false; } }
/** * 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(); }
/** * Returns the number of answers matching the quota * * @param int $iSurveyId - Survey identification number * @param int $quotaid - quota id for which you want to compute the completed field * @return mixed - Integer of matching entries in the result DB or 'N/A' */ function getQuotaCompletedCount($iSurveyId, $quotaid) { $result = "N/A"; $quota_info = getQuotaInformation($iSurveyId, Survey::model()->findByPk($iSurveyId)->language, $quotaid); $quota = $quota_info[0]; if (Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}') && count($quota['members']) > 0) { // Keep a list of fields for easy reference $fields_list = array(); // Construct an array of value for each $quota['members']['fieldnames'] $fields_query = array(); foreach ($quota['members'] as $member) { $criteria = new CDbCriteria(); foreach ($member['fieldnames'] as $fieldname) { if (!in_array($fieldname, $fields_list)) { $fields_list[] = $fieldname; } $criteria->addColumnCondition(array($fieldname => $member['value']), 'OR'); } $fields_query[$fieldname] = $criteria; } $criteria = new CDbCriteria(); foreach ($fields_list as $fieldname) { $criteria->mergeWith($fields_query[$fieldname]); } $result = Survey_dynamic::model($iSurveyId)->count($criteria); } return $result; }
/** * 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(); }
/** * Returns the number of answers matching the quota * * @param int $iSurveyId - Survey identification number * @param int $quotaid - quota id for which you want to compute the completed field * @return string - Integer of matching entries in the result DB or 'N/A' */ function getQuotaCompletedCount($iSurveyId, $quotaid) { $result = "N/A"; if (!tableExists("survey_{$iSurveyId}")) { // Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}' are not updated even after Yii::app()->db->schema->refresh(); return $result; } $aColumnName = SurveyDynamic::model($iSurveyId)->getTableSchema()->getColumnNames(); $quota_info = getQuotaInformation($iSurveyId, Survey::model()->findByPk($iSurveyId)->language, $quotaid); $quota = $quota_info[0]; if (count($quota['members']) > 0) { // Keep a list of fields for easy reference $fields_list = array(); // Construct an array of value for each $quota['members']['fieldnames'] $fields_query = array(); foreach ($quota['members'] as $member) { if (in_array($member['fieldname'], $aColumnName)) { $fields_list[$member['fieldname']][] = $member['value']; } else { return $result; } // We return N/A even for activated survey : $member['fieldname'] don't exist anymore (deleted question for example) } $criteria = new CDbCriteria(); $criteria->condition = "submitdate IS NOT NULL"; foreach ($fields_list as $fieldname => $aValue) { if (count($aValue) == 1) { $criteria->compare(Yii::app()->db->quoteColumnName($fieldname), $aValue[0]); // NO need params } else { $criteria->addInCondition(Yii::app()->db->quoteColumnName($fieldname), $aValue); // NO need params : addInCondition bind automatically } } // Ensure to return a string, Yii count return a string (see http://www.yiiframework.com/doc/api/1.1/CActiveRecord#count-detail) // But seems under certain condition, count return integer see http://bugs.limesurvey.org/view.php?id=9587#c31917 $result = strval(SurveyDynamic::model($iSurveyId)->count($criteria)); } return $result; }
/** * get_quotaCompletedCount() returns the number of answers matching the quota * @param string $surveyid - Survey identification number * @param string $quotaid - quota id for which you want to compute the completed field * @return string - number of mathing entries in the result DB or 'N/A' */ function get_quotaCompletedCount($surveyid, $quotaid) { $result = "N/A"; $quota_info = getQuotaInformation($surveyid, GetBaseLanguageFromSurveyID($surveyid), $quotaid); $quota = $quota_info[0]; if (db_tables_exist(db_table_name_nq('survey_' . $surveyid)) && count($quota['members']) > 0) { $fields_list = array(); // Keep a list of fields for easy reference // construct an array of value for each $quota['members']['fieldnames'] unset($querycond); $fields_query = array(); foreach ($quota['members'] as $member) { foreach ($member['fieldnames'] as $fieldname) { if (!in_array($fieldname, $fields_list)) { $fields_list[] = $fieldname; $fields_query[$fieldname] = array(); } $fields_query[$fieldname][] = db_quote_id($fieldname) . " = '{$member['value']}'"; } } foreach ($fields_list as $fieldname) { $select_query = " ( " . implode(' OR ', $fields_query[$fieldname]) . ' )'; $querycond[] = $select_query; } $querysel = "SELECT count(id) as count FROM " . db_table_name('survey_' . $surveyid) . " WHERE " . implode(' AND ', $querycond) . " " . " AND submitdate IS NOT NULL"; $result = db_execute_assoc($querysel) or safe_die($connect->ErrorMsg()); //Checked $quota_check = $result->FetchRow(); $result = $quota_check['count']; } return $result; }
/** * check_quota() returns quota information for the current survey * @param string $checkaction - action the function must take after completing: * enforce: Enforce the quota action * return: Return the updated quota array from getQuotaAnswers() * @param string $surveyid - Survey identification number * @return array - nested array, Quotas->Members->Fields, includes quota status and which members matched in session. */ function check_quota($checkaction, $surveyid) { if (!isset($_SESSION['s_lang'])) { return; } global $thistpl, $clang, $clienttoken, $publicurl; $global_matched = false; $quota_info = getQuotaInformation($surveyid, $_SESSION['s_lang']); $x = 0; if (count($quota_info) > 0) { // Check each quota on saved data to see if it is full $querycond = array(); foreach ($quota_info as $quota) { if (count($quota['members']) > 0) { $fields_list = array(); // Keep a list of fields for easy reference $y = 0; // We need to make the conditions for the select statement here // I'm supporting more than one field for a question/answer, not sure if this is necessary. unset($querycond); foreach ($quota['members'] as $member) { $fields_query = array(); $select_query = " ("; foreach ($member['fieldnames'] as $fieldname) { $fields_list[] = $fieldname; $fields_query[] = db_quote_id($fieldname) . " = '{$member['value']}'"; // Check which quota fields and codes match in session, for later use. // Incase of multiple fields for an answer - only needs to match once. if (isset($_SESSION[$fieldname]) && $_SESSION[$fieldname] == $member['value']) { $quota_info[$x]['members'][$y]['insession'] = "true"; } } $select_query .= implode(' OR ', $fields_query) . ' )'; $querycond[] = $select_query; unset($fields_query); $y++; } // Lets only continue if any of the quota fields is in the posted page $matched_fields = false; if (isset($_POST['fieldnames'])) { $posted_fields = explode("|", $_POST['fieldnames']); foreach ($fields_list as $checkfield) { if (in_array($checkfield, $posted_fields)) { $matched_fields = true; $global_matched = true; } } } // A field was submitted that is part of the quota if ($matched_fields == true) { // Check the status of the quota, is it full or not $querysel = "SELECT id FROM " . db_table_name('survey_' . $surveyid) . "\n\t\t\t\t\t WHERE " . implode(' AND ', $querycond) . " " . "\n\t\t\t\t\t\t\t\t AND submitdate IS NOT NULL"; $result = db_execute_assoc($querysel) or safe_die($connect->ErrorMsg()); //Checked $quota_check = $result->FetchRow(); if ($result->RecordCount() >= $quota['Limit']) { // Now we have to check if the quota matches in the current session // This will let us know if this person is going to exceed the quota $counted_matches = 0; foreach ($quota_info[$x]['members'] as $member) { if (isset($member['insession']) && $member['insession'] == "true") { $counted_matches++; } } if ($counted_matches == count($quota['members'])) { // They are going to exceed the quota if data is submitted $quota_info[$x]['status'] = "matched"; } else { $quota_info[$x]['status'] = "notmatched"; } } else { // Quota is no in danger of being exceeded. $quota_info[$x]['status'] = "notmatched"; } } } $x++; } } else { return false; } // Now we have all the information we need about the quotas and their status. // Lets see what we should do now if ($checkaction == 'return') { return $quota_info; } else { if ($global_matched == true && $checkaction == 'enforce') { // Need to add quota action enforcement here. reset($quota_info); $tempmsg = ""; $found = false; foreach ($quota_info as $quota) { if (isset($quota['status']) && $quota['status'] == "matched" && (isset($quota['Action']) && $quota['Action'] == "1")) { // If a token is used then mark the token as completed if (isset($clienttoken) && $clienttoken) { submittokens(true); } session_destroy(); sendcacheheaders(); if ($quota['AutoloadUrl'] == 1 && $quota['Url'] != "") { header("Location: " . $quota['Url']); } doHeader(); echo templatereplace(file_get_contents("{$thistpl}/startpage.pstpl")); echo "\t<div class='quotamessage'>\n"; echo "\t" . $quota['Message'] . "<br /><br />\n"; echo "\t<a href='" . $quota['Url'] . "'>" . $quota['UrlDescrip'] . "</a><br />\n"; echo "\t</div>\n"; echo templatereplace(file_get_contents("{$thistpl}/endpage.pstpl")); doFooter(); exit; } if (isset($quota['status']) && $quota['status'] == "matched" && (isset($quota['Action']) && $quota['Action'] == "2")) { sendcacheheaders(); doHeader(); echo templatereplace(file_get_contents("{$thistpl}/startpage.pstpl")); echo "\t<div class='quotamessage'>\n"; echo "\t" . $quota['Message'] . "<br /><br />\n"; echo "\t<a href='" . $quota['Url'] . "'>" . $quota['UrlDescrip'] . "</a><br />\n"; echo "<form method='post' action='{$publicurl}/index.php' id='limesurvey' name='limesurvey'><input type=\"hidden\" name=\"move\" value=\"movenext\" id=\"movenext\" /><input class='submit' accesskey='p' type='button' onclick=\"javascript:document.limesurvey.move.value = 'moveprev'; document.limesurvey.submit();\" value=' << " . $clang->gT("Previous") . " ' name='move2' />\n\t\t\t\t\t<input type='hidden' name='thisstep' value='" . $_SESSION['step'] . "' id='thisstep' />\n\t\t\t\t\t<input type='hidden' name='sid' value='" . returnglobal('sid') . "' id='sid' />\n\t\t\t\t\t<input type='hidden' name='token' value='" . $clienttoken . "' id='token' /></form>\n"; echo "\t</div>\n"; echo templatereplace(file_get_contents("{$thistpl}/endpage.pstpl")); doFooter(); exit; } } } else { // Unknown value return false; } } }
/** * Returns the number of answers matching the quota * * @param int $iSurveyId - Survey identification number * @param int $quotaid - quota id for which you want to compute the completed field * @return mixed - Integer of matching entries in the result DB or 'N/A' */ function getQuotaCompletedCount($iSurveyId, $quotaid) { $result = "N/A"; if (!tableExists("survey_{$iSurveyId}")) { // Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}' are not updated even after Yii::app()->db->schema->refresh(); return $result; } $aColumnName = SurveyDynamic::model($iSurveyId)->getTableSchema()->getColumnNames(); $quota_info = getQuotaInformation($iSurveyId, Survey::model()->findByPk($iSurveyId)->language, $quotaid); $quota = $quota_info[0]; if (count($quota['members']) > 0) { // Keep a list of fields for easy reference $fields_list = array(); // Construct an array of value for each $quota['members']['fieldnames'] $fields_query = array(); foreach ($quota['members'] as $member) { if (in_array($member['fieldname'], $aColumnName)) { $fields_list[$member['fieldname']][] = $member['value']; } else { return $result; } // We return N/A even for activated survey } $criteria = new CDbCriteria(); $criteria->condition = "submitdate IS NOT NULL"; $aParams = array(); foreach ($fields_list as $fieldname => $aValue) { if (count($aValue) == 1) { // Quote columnName : starting with number broke mssql $criteria->addCondition(Yii::app()->db->quoteColumnName($fieldname) . " = :field{$fieldname}"); $aParams[":field{$fieldname}"] = $aValue[0]; } else { $criteria->addInCondition(Yii::app()->db->quoteColumnName($fieldname), $aValue); // NO need params : addInCondition bind automatically } // We can use directly addInCondition, but don't know what is speediest. } if (!empty($aParams)) { $criteria->params = $aParams; } $result = SurveyDynamic::model($iSurveyId)->count($criteria); } return $result; }
/** * get_quotaCompletedCount() returns the number of answers matching the quota * @param string $surveyid - Survey identification number * @param string $quotaid - quota id for which you want to compute the completed field * @return string - number of mathing entries in the result DB or 'N/A' */ function get_quotaCompletedCount($surveyid, $quotaid) { $result = "N/A"; $quota_info = getQuotaInformation($surveyid, GetBaseLanguageFromSurveyID($surveyid), $quotaid); $quota = $quota_info[0]; if (db_tables_exist(db_table_name_nq('survey_' . $surveyid)) && count($quota['members']) > 0) { $fields_list = array(); // Keep a list of fields for easy reference unset($querycond); foreach ($quota['members'] as $member) { $fields_query = array(); $select_query = " ("; foreach ($member['fieldnames'] as $fieldname) { $fields_list[] = $fieldname; $fields_query[] = db_quote_id($fieldname) . " = '{$member['value']}'"; // Incase of multiple fields for an answer - only needs to match once. $select_query .= implode(' OR ', $fields_query) . ' )'; $querycond[] = $select_query; unset($fields_query); } } //FOR MYSQL? $querysel = "SELECT count(id) as count FROM " . db_table_name('survey_' . $surveyid) . " WHERE " . implode(' AND ', $querycond) . " " . " AND submitdate !=''"; //FOR POSTGRES? $querysel = "SELECT count(id) as count FROM " . db_table_name('survey_' . $surveyid) . " WHERE " . implode(' AND ', $querycond) . " " . " AND submitdate IS NOT NULL"; $result = db_execute_assoc($querysel) or safe_die($connect->ErrorMsg()); //Checked $quota_check = $result->FetchRow(); $result = $quota_check['count']; } return $result; }