/**
* 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();
}
Exemplo n.º 2
0
 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();
}