/** * printanswers::view() * View answers at the end of a survey in one place. To export as pdf, set 'usepdfexport' = 1 in lsconfig.php and $printableexport='pdf'. * @param mixed $surveyid * @param bool $printableexport * @return */ function actionView($surveyid, $printableexport = FALSE) { Yii::app()->loadHelper("frontend"); Yii::import('application.libraries.admin.pdf'); $iSurveyID = (int) $surveyid; $sExportType = $printableexport; Yii::app()->loadHelper('database'); if (isset($_SESSION['survey_' . $iSurveyID]['sid'])) { $iSurveyID = $_SESSION['survey_' . $iSurveyID]['sid']; } else { //die('Invalid survey/session'); } // Get the survey inforamtion // Set the language for dispay if (isset($_SESSION['survey_' . $iSurveyID]['s_lang'])) { $sLanguage = $_SESSION['survey_' . $iSurveyID]['s_lang']; } elseif (Survey::model()->findByPk($iSurveyID)) { $sLanguage = Survey::model()->findByPk($iSurveyID)->language; } else { $iSurveyID = 0; $sLanguage = Yii::app()->getConfig("defaultlang"); } $clang = SetSurveyLanguage($iSurveyID, $sLanguage); $aSurveyInfo = getSurveyInfo($iSurveyID, $sLanguage); //SET THE TEMPLATE DIRECTORY if (!isset($aSurveyInfo['templatedir']) || !$aSurveyInfo['templatedir']) { $aSurveyInfo['templatedir'] = Yii::app()->getConfig('defaulttemplate'); } $sTemplate = validateTemplateDir($aSurveyInfo['templatedir']); //Survey is not finished or don't exist if (!isset($_SESSION['survey_' . $iSurveyID]['finished']) || !isset($_SESSION['survey_' . $iSurveyID]['srid'])) { sendCacheHeaders(); doHeader(); echo templatereplace(file_get_contents(getTemplatePath($sTemplate) . '/startpage.pstpl'), array()); echo "<center><br />\n" . "\t<font color='RED'><strong>" . $clang->gT("Error") . "</strong></font><br />\n" . "\t" . $clang->gT("We are sorry but your session has expired.") . "<br />" . $clang->gT("Either you have been inactive for too long, you have cookies disabled for your browser, or there were problems with your connection.") . "<br />\n" . "\t" . sprintf($clang->gT("Please contact %s ( %s ) for further assistance."), Yii::app()->getConfig("siteadminname"), Yii::app()->getConfig("siteadminemail")) . "\n" . "</center><br />\n"; echo templatereplace(file_get_contents(getTemplatePath($sTemplate) . '/endpage.pstpl'), array()); doFooter(); exit; } //Fin session time out $sSRID = $_SESSION['survey_' . $iSurveyID]['srid']; //I want to see the answers with this id //Ensure script is not run directly, avoid path disclosure //if (!isset($rootdir) || isset($_REQUEST['$rootdir'])) {die( "browse - Cannot run this script directly");} if ($aSurveyInfo['printanswers'] == 'N') { die; //Die quietly if print answers is not permitted } //CHECK IF SURVEY IS ACTIVATED AND EXISTS $sSurveyName = $aSurveyInfo['surveyls_title']; $sAnonymized = $aSurveyInfo['anonymized']; //OK. IF WE GOT THIS FAR, THEN THE SURVEY EXISTS AND IT IS ACTIVE, SO LETS GET TO WORK. //SHOW HEADER $sOutput = CHtml::form(array("printanswers/view/surveyid/{$iSurveyID}/printableexport/pdf"), 'post') . "<center><input type='submit' value='" . $clang->gT("PDF export") . "'id=\"exportbutton\"/><input type='hidden' name='printableexport' /></center></form>"; if ($sExportType == 'pdf') { //require (Yii::app()->getConfig('rootdir').'/application/config/tcpdf.php'); Yii::import('application.libraries.admin.pdf', true); Yii::import('application.helpers.pdfHelper'); $aPdfLanguageSettings = pdfHelper::getPdfLanguageSettings($clang->langcode); $oPDF = new pdf(); $oPDF->SetTitle($clang->gT("Survey name (ID)", 'unescaped') . ": {$sSurveyName} ({$iSurveyID})"); $oPDF->SetSubject($sSurveyName); $oPDF->SetDisplayMode('fullpage', 'two'); $oPDF->setLanguageArray($aPdfLanguageSettings['lg']); $oPDF->setHeaderFont(array($aPdfLanguageSettings['pdffont'], '', PDF_FONT_SIZE_MAIN)); $oPDF->setFooterFont(array($aPdfLanguageSettings['pdffont'], '', PDF_FONT_SIZE_DATA)); $oPDF->SetFont($aPdfLanguageSettings['pdffont'], '', $aPdfLanguageSettings['pdffontsize']); $oPDF->AddPage(); $oPDF->titleintopdf($clang->gT("Survey name (ID)", 'unescaped') . ": {$sSurveyName} ({$iSurveyID})"); } $sOutput .= "\t<div class='printouttitle'><strong>" . $clang->gT("Survey name (ID):") . "</strong> {$sSurveyName} ({$iSurveyID})</div><p> \n"; LimeExpressionManager::StartProcessingPage(true); // means that all variables are on the same page // Since all data are loaded, and don't need JavaScript, pretend all from Group 1 LimeExpressionManager::StartProcessingGroup(1, $aSurveyInfo['anonymized'] != "N", $iSurveyID); $printanswershonorsconditions = Yii::app()->getConfig('printanswershonorsconditions'); $aFullResponseTable = getFullResponseTable($iSurveyID, $sSRID, $sLanguage, $printanswershonorsconditions); //Get the fieldmap @TODO: do we need to filter out some fields? if ($aSurveyInfo['datestamp'] != "Y" || $sAnonymized == 'Y') { unset($aFullResponseTable['submitdate']); } else { unset($aFullResponseTable['id']); } unset($aFullResponseTable['token']); unset($aFullResponseTable['lastpage']); unset($aFullResponseTable['startlanguage']); unset($aFullResponseTable['datestamp']); unset($aFullResponseTable['startdate']); $sOutput .= "<table class='printouttable' >\n"; foreach ($aFullResponseTable as $sFieldname => $fname) { if (substr($sFieldname, 0, 4) == 'gid_') { $sOutput .= "\t<tr class='printanswersgroup'><td colspan='2'>{$fname[0]}</td></tr>\n"; } elseif (substr($sFieldname, 0, 4) == 'qid_') { $sOutput .= "\t<tr class='printanswersquestionhead'><td colspan='2'>{$fname[0]}</td></tr>\n"; } elseif ($sFieldname == 'submitdate') { if ($sAnonymized != 'Y') { $sOutput .= "\t<tr class='printanswersquestion'><td>{$fname[0]} {$fname[1]} {$sFieldname}</td><td class='printanswersanswertext'>{$fname[2]}</td></tr>"; } } else { $sOutput .= "\t<tr class='printanswersquestion'><td>{$fname[0]} {$fname[1]}</td><td class='printanswersanswertext'>" . flattenText($fname[2]) . "</td></tr>"; } } $sOutput .= "</table>\n"; $sData['thissurvey'] = $aSurveyInfo; $sOutput = templatereplace($sOutput, array(), $sData, '', $aSurveyInfo['anonymized'] == "Y", NULL, array(), true); // Do a static replacement if ($sExportType == 'pdf') { $oPDF->writeHTML($sOutput); header("Pragma: public"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); $sExportFileName = sanitize_filename($sSurveyName); $oPDF->Output($sExportFileName . "-" . $iSurveyID . ".pdf", "D"); } else { ob_start(function ($buffer, $phase) { App()->getClientScript()->render($buffer); App()->getClientScript()->reset(); return $buffer; }); ob_implicit_flush(false); sendCacheHeaders(); doHeader(); echo templatereplace(file_get_contents(getTemplatePath($sTemplate) . '/startpage.pstpl'), array(), $sData); echo templatereplace(file_get_contents(getTemplatePath($sTemplate) . '/printanswers.pstpl'), array('ANSWERTABLE' => $sOutput), $sData); echo templatereplace(file_get_contents(getTemplatePath($sTemplate) . '/endpage.pstpl'), array(), $sData); echo "</body></html>"; ob_flush(); } LimeExpressionManager::FinishProcessingGroup(); LimeExpressionManager::FinishProcessingPage(); }
/** * Generates statistics * * @param int $surveyid The survey id * @param mixed $allfields * @param mixed $q2show * @param mixed $usegraph * @param string $outputType Optional - Can be xls, html or pdf - Defaults to pdf * @param string $pdfOutput Sets the target for the PDF output: DD=File download , F=Save file to local disk * @param string $statlangcode Lamguage for statistics * @param mixed $browse Show browse buttons * @return buffer */ public function generate_statistics($surveyid, $allfields, $q2show = 'all', $usegraph = 0, $outputType = 'pdf', $pdfOutput = 'I', $sLanguageCode = null, $browse = true) { $aStatisticsData = array(); //astatdata generates data for the output page's javascript so it can rebuild graphs on the fly //load surveytranslator helper Yii::import('application.helpers.surveytranslator_helper', true); Yii::import('application.third_party.ar-php.Arabic', true); $sOutputHTML = ""; //This string carries all the actual HTML code to print. $sTempDir = Yii::app()->getConfig("tempdir"); $this->pdf = array(); //Make sure $this->pdf exists - it will be replaced with an object if a $this->pdf is actually being created //pick the best font file if font setting is 'auto' if (is_null($sLanguageCode)) { $sLanguageCode = getBaseLanguageFromSurveyID($surveyid); } Yii::app()->setLanguage($sLanguageCode); /* * this variable is used in the function shortencode() which cuts off a question/answer title * after $maxchars and shows the rest as tooltip (in html mode) */ $maxchars = 13; //we collect all the html-output within this variable $sOutputHTML = ''; /** * $outputType: html || pdf || */ /** * get/set Survey Details */ //no survey ID? -> come and get one if (!isset($surveyid)) { $surveyid = returnGlobal('sid'); } //Get an array of codes of all available languages in this survey $surveylanguagecodes = Survey::model()->findByPk($surveyid)->additionalLanguages; $surveylanguagecodes[] = Survey::model()->findByPk($surveyid)->language; $fieldmap = createFieldMap($surveyid, "full", false, false, $sLanguageCode); // Set language for questions and answers to base language of this survey $language = $sLanguageCode; if ($q2show == 'all') { $summarySql = " SELECT gid, parent_qid, qid, type " . " FROM {{questions}} WHERE parent_qid=0" . " AND sid={$surveyid} "; $summaryRs = Yii::app()->db->createCommand($summarySql)->query()->readAll(); foreach ($summaryRs as $field) { $myField = $surveyid . "X" . $field['gid'] . "X" . $field['qid']; // Multiple choice get special treatment if ($field['type'] == "M") { $myField = "M{$myField}"; } if ($field['type'] == "P") { $myField = "P{$myField}"; } //numerical input will get special treatment (arihtmetic mean, standard derivation, ...) if ($field['type'] == "N") { $myField = "N{$myField}"; } if ($field['type'] == "|") { $myField = "|{$myField}"; } if ($field['type'] == "Q") { $myField = "Q{$myField}"; } // textfields get special treatment if ($field['type'] == "S" || $field['type'] == "T" || $field['type'] == "U") { $myField = "T{$myField}"; } //statistics for Date questions are not implemented yet. if ($field['type'] == "D") { $myField = "D{$myField}"; } if ($field['type'] == "F" || $field['type'] == "H") { //Get answers. We always use the answer code because the label might be too long elsewise $query = "SELECT code, answer FROM {{answers}} WHERE qid='" . $field['qid'] . "' AND scale_id=0 AND language='{$language}' ORDER BY sortorder, answer"; $result = Yii::app()->db->createCommand($query)->query(); $counter2 = 0; //check all the answers foreach ($result->readAll() as $row) { $row = array_values($row); $myField = "{$myField}{$row[0]}"; } //$myField = "{$surveyid}X{$flt[1]}X{$flt[0]}{$row[0]}[]"; } if ($q2show == 'all') { $summary[] = $myField; } //$allfields[]=$myField; } } else { // This gets all the 'to be shown questions' from the POST and puts these into an array if (!is_array($q2show)) { $summary = returnGlobal('summary'); } else { $summary = $q2show; } //print_r($_POST); //if $summary isn't an array we create one if (isset($summary) && !is_array($summary)) { $summary = explode("+", $summary); } } /** * pdf Config */ if ($outputType == 'pdf') { //require_once('classes/tcpdf/mypdf.php'); Yii::import('application.libraries.admin.pdf', true); Yii::import('application.helpers.pdfHelper'); $aPdfLanguageSettings = pdfHelper::getPdfLanguageSettings($language); // create new PDF document $this->pdf = new pdf(); $surveyInfo = getSurveyInfo($surveyid, $language); // set document information $this->pdf->SetCreator(PDF_CREATOR); $this->pdf->SetAuthor('LimeSurvey'); $this->pdf->SetTitle(sprintf(gT("Statistics survey %s"), $surveyid)); $this->pdf->SetSubject($surveyInfo['surveyls_title']); $this->pdf->SetKeywords('LimeSurvey,' . gT("Statistics") . ', ' . sprintf(gT("Survey %s"), $surveyid)); $this->pdf->SetDisplayMode('fullpage', 'two'); $this->pdf->setLanguageArray($aPdfLanguageSettings['lg']); // set header and footer fonts $this->pdf->setHeaderFont(array($aPdfLanguageSettings['pdffont'], '', PDF_FONT_SIZE_MAIN)); $this->pdf->setFooterFont(array($aPdfLanguageSettings['pdffont'], '', PDF_FONT_SIZE_DATA)); // set default header data // Since png crashes some servers (and we can not try/catch that) we use .gif (or .jpg) instead $headerlogo = 'statistics.gif'; $this->pdf->SetHeaderData($headerlogo, 10, gT("Quick statistics", 'unescaped'), gT("Survey") . " " . $surveyid . " '" . flattenText($surveyInfo['surveyls_title'], false, true, 'UTF-8') . "'"); $this->pdf->SetFont($aPdfLanguageSettings['pdffont'], '', $aPdfLanguageSettings['pdffontsize']); // set default monospaced font $this->pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); } if ($outputType == 'xls') { /** * Initiate the Spreadsheet_Excel_Writer */ require_once APPPATH . '/third_party/pear/Spreadsheet/Excel/Xlswriter.php'; if ($pdfOutput == 'F') { $sFileName = $sTempDir . '/statistic-survey' . $surveyid . '.xls'; $this->workbook = new Xlswriter($sFileName); } else { $this->workbook = new Xlswriter(); } $this->workbook->setVersion(8); // Inform the module that our data will arrive as UTF-8. // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) $this->workbook->setTempDir($sTempDir); // Inform the module that our data will arrive as UTF-8. // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) if (!empty($sTempDir)) { $this->workbook->setTempDir($sTempDir); } if ($pdfOutput != 'F') { $this->workbook->send('statistic-survey' . $surveyid . '.xls'); } // Creating the first worksheet $this->sheet = $this->workbook->addWorksheet(utf8_decode('results-survey' . $surveyid)); $this->xlsPercents =& $this->workbook->addFormat(); $this->xlsPercents->setNumFormat('0.00%'); $this->formatBold =& $this->workbook->addFormat(array('Bold' => 1)); $this->sheet->setInputEncoding('utf-8'); $this->sheet->setColumn(0, 20, 20); $separator = "~|"; /**XXX*/ } /** * Start generating */ $selects = buildSelects($allfields, $surveyid, $language); //count number of answers $query = "SELECT count(*) FROM {{survey_{$surveyid}}}"; //if incompleted answers should be filtert submitdate has to be not null if (incompleteAnsFilterState() == "incomplete") { $query .= " WHERE submitdate is null"; } elseif (incompleteAnsFilterState() == "complete") { $query .= " WHERE submitdate is not null"; } $total = Yii::app()->db->createCommand($query)->queryScalar(); //are there any filters that have to be taken care of? if (isset($selects) && $selects) { //Save the filters to session for use in browsing text & other features (statistics.php function listcolumn()) Yii::app()->session['statistics_selects_' . $surveyid] = $selects; //filter incomplete answers? if (incompleteAnsFilterState() == "complete" || incompleteAnsFilterState() == "incomplete") { $query .= " AND "; } else { $query .= " WHERE "; } //add filter criteria to SQL $query .= implode(" AND ", $selects); } //get me some data Scotty $results = Yii::app()->db->createCommand($query)->queryScalar(); if ($total) { $percent = sprintf("%01.2f", $results / $total * 100); } switch ($outputType) { case "xls": $this->xlsRow = 0; $this->sheet->write($this->xlsRow, 0, gT("Number of records in this query:", 'unescaped')); $this->sheet->writeNumber($this->xlsRow, 1, $results); $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Total records in survey:", 'unescaped')); $this->sheet->writeNumber($this->xlsRow, 1, $total); if ($total) { $this->xlsRow++; $this->sheet->write($this->xlsRow, 0, gT("Percentage of total:", 'unescaped')); $this->sheet->writeNumber($this->xlsRow, 1, $results / $total, $this->xlsPercents); } break; case 'pdf': // add summary to pdf $array = array(array(gT("Number of records in this query:", 'unescaped'), $results), array(gT("Total records in survey:", 'unescaped'), $total)); if ($total) { $array[] = array(gT("Percentage of total:", 'unescaped'), $percent . "%"); } $this->pdf->AddPage('P', ' A4'); $this->pdf->Bookmark(gT("Results", 'unescaped'), 0, 0); $this->pdf->titleintopdf(gT("Results", 'unescaped'), gT("Survey", 'unescaped') . " " . $surveyid); $this->pdf->tableintopdf($array); break; case 'html': $sOutputHTML .= "<br />\n<table class='statisticssummary' >\n" . "\t<thead><tr><th colspan='2'>" . gT("Results") . "</th></tr></thead>\n" . "\t<tr><th >" . gT("Number of records in this query:") . '</th>' . "<td>{$results}</td></tr>\n" . "\t<tr><th>" . gT("Total records in survey:") . '</th>' . "<td>{$total}</td></tr>\n"; //only calculate percentage if $total is set if ($total) { $percent = sprintf("%01.2f", $results / $total * 100); $sOutputHTML .= "\t<tr><th align='right'>" . gT("Percentage of total:") . '</th>' . "<td>{$percent}%</td></tr>\n"; } $sOutputHTML .= "</table>\n"; break; default: break; } //put everything from $selects array into a string connected by AND //This string ($sql) can then be passed on to other functions so you can //browse these results if (isset($selects) && $selects) { $sql = implode(" AND ", $selects); } elseif (!empty($newsql)) { $sql = $newsql; } if (!isset($sql) || !$sql) { $sql = null; } //only continue if we have something to output if ($results > 0) { if ($outputType == 'html' && $browse === true && Permission::model()->hasSurveyPermission($surveyid, 'responses', 'read')) { //add a buttons to browse results $sOutputHTML .= CHtml::form(array("admin/responses/sa/browse/surveyid/{$surveyid}"), 'post', array('target' => '_blank')) . "\n" . "\t\t<p>" . "\t\t\t<input type='submit' value='" . gT("Browse") . "' />\n" . "\t\t\t<input type='hidden' name='sid' value='{$surveyid}' />\n" . "\t\t\t<input type='hidden' name='sql' value=\"{$sql}\" />\n" . "\t\t\t<input type='hidden' name='subaction' value='all' />\n" . "\t\t</p>" . "\t\t</form>\n"; } } //end if (results > 0) /* Show Summary results * The $summary array contains each fieldname that we want to display statistics for * * */ if (isset($summary) && $summary) { //let's run through the survey $runthrough = $summary; //START Chop up fieldname and find matching questions //loop through all selected questions foreach ($runthrough as $rt) { //Step 1: Get information about this response field (SGQA) for the summary $outputs = $this->buildOutputList($rt, $language, $surveyid, $outputType, $sql, $sLanguageCode); $sOutputHTML .= $outputs['statisticsoutput']; //2. Collect and Display results ####################################################################### if (isset($outputs['alist']) && $outputs['alist']) { $display = $this->displayResults($outputs, $results, $rt, $outputType, $surveyid, $sql, $usegraph, $browse, $sLanguageCode); $sOutputHTML .= $display['statisticsoutput']; $aStatisticsData = array_merge($aStatisticsData, $display['astatdata']); } //end if -> collect and display results //Delete Build Outputs data unset($outputs); unset($display); } // end foreach -> loop through all questions //output if ($outputType == 'html') { $sOutputHTML .= "<br /> \n"; } } //end if -> show summary results switch ($outputType) { case 'xls': $this->workbook->close(); if ($pdfOutput == 'F') { return $sFileName; } else { return; } break; case 'pdf': $this->pdf->lastPage(); if ($pdfOutput == 'F') { // This is only used by lsrc to send an E-Mail attachment, so it gives back the filename to send and delete afterwards $tempfilename = $sTempDir . "/Survey_" . $surveyid . ".pdf"; $this->pdf->Output($tempfilename, $pdfOutput); return $tempfilename; } else { return $this->pdf->Output(gT('Survey') . '_' . $surveyid . "_" . $surveyInfo['surveyls_title'] . '.pdf', $pdfOutput); } break; case 'html': $sGoogleMapsAPIKey = trim(Yii::app()->getConfig("googleMapsAPIKey")); if ($sGoogleMapsAPIKey != '') { $sGoogleMapsAPIKey = '&key=' . $sGoogleMapsAPIKey; } $sSSL = ''; if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != "off") { $sSSL = 's'; } $sOutputHTML .= "<script type=\"text/javascript\" src=\"http{$sSSL}://maps.googleapis.com/maps/api/js?sensor=false{$sGoogleMapsAPIKey}\"></script>\n" . "<script type=\"text/javascript\">var site_url='" . Yii::app()->baseUrl . "';var temppath='" . Yii::app()->getConfig("tempurl") . "';var imgpath='" . Yii::app()->getConfig('adminimageurl') . "';var aStatData=" . ls_json_encode($aStatisticsData) . "</script>"; return $sOutputHTML; break; default: return $sOutputHTML; break; } }