/** * Handler to view a generated report file * * @param type $data * @param type $form */ public function viewreport($request) { $item = 1; $allowed = array('html', 'pdf', 'csv'); $ext = $request->getExtension(); if (!in_array($ext, $allowed)) { return $this->httpError(404); } $reportID = (int) $request->param('ID'); $fileID = (int) $request->param('OtherID'); $report = AdvancedReport::get()->byID($reportID); if (!$report || !$report->canView()) { return $this->httpError(404); } $file = $report->{strtoupper($ext) . 'File'}(); if (!$file || !strlen($file->Content)) { return $this->httpError(404); } $mimeType = HTTP::get_mime_type($file->Name); header("Content-Type: {$mimeType}; name=\"" . addslashes($file->Name) . "\""); header("Content-Disposition: attachment; filename=" . addslashes($file->Name)); header("Content-Length: {$file->getSize()}"); header("Pragma: "); session_write_close(); ob_flush(); flush(); // Push the file while not EOF and connection exists echo base64_decode($file->Content); exit; }
public function getSettingsFields() { $fields = parent::getSettingsFields(); $types = ClassInfo::subclassesFor('DataObject'); array_shift($types); ksort($types); $fields->insertAfter(new DropdownField('ReportOn', _t('AdvancedReport.REPORT_ON', 'Report on'), $types), 'Title'); return $fields; }
public function getCMSFields($params = null) { $fields = new FieldList(); // tabbed or untabbed $fields->push(new TabSet("Root", $mainTab = new Tab("Main"))); $mainTab->setTitle(_t('SiteTree.TABMAIN', "Main")); $reports = array(); $reportObjs = AdvancedReport::get()->filter(array('ReportID' => 0)); if ($reportObjs && $reportObjs->count()) { foreach ($reportObjs as $obj) { if ($obj instanceof CombinedReport) { continue; } $reports[$obj->ID] = $obj->Title . '(' . $obj->ClassName . ')'; } } $fields->addFieldsToTab('Root.Main', array(new DropdownField('ReportID', 'Related report', $reports), new TextField('Title'), new KeyValueField('Parameters', 'Parameters to pass to the report'), new NumericField('Sort'))); return $fields; }
/** * @return AdvancedReport */ public function getReport() { return AdvancedReport::get()->byID($this->reportID); }
/** * Overwrites SiteTree.getCMSFields. * * This method creates a customised CMS form for back-end user. * * @return fieldset */ function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeFieldsFromTab("Root.Main", array("Pages")); return $fields; }
/** * Restructures the data objects according to the settings of the report. * * @todo this method is too complex and should be refactored into smaller methods */ protected function reformatDataObjects() { $this->data = array(); $dataObjects = $this->report->getDataObjects(); $colsToBlank = $this->report->getDuplicatedBlankingFields(); $i = 0; $previousVals = array(); $tableName = self::DEFAULT_TABLE_NAME; $paginateBy = $this->report->dottedFieldToUnique($this->report->PaginateBy); $headerTemplate = $this->report->PageHeader ? $this->report->PageHeader : '$name'; $addCols = null; if ($this->report->AddInRows && count($this->report->AddInRows->getValues())) { $addCols = $this->report->AddInRows->getValues(); } if (!$dataObjects) { $this->data[$tableName] = array(); return; } foreach ($dataObjects as $item) { // lets check to see whether this item has the paginate variable, if so we want to be // adding this result to that table entry if ($paginateBy) { $pageVar = is_object($item) ? $item->{$paginateBy} : $item[$paginateBy]; if ($pageVar) { $tableName = str_replace('$name', $pageVar, $headerTemplate); } else { $tableName = sprintf(_t('ReportFormatter.NO_PAGINATE_VALUE', 'No %s'), $paginateBy); } } $row = array(); $addToTable = isset($this->data[$tableName]) ? $this->data[$tableName] : array(); $rowSum = 0; foreach ($this->headers as $field => $display) { // Account for our total summation of things. if ($field == self::ADD_IN_ROWS_TOTAL) { if (is_object($item)) { $item->{$field} = $rowSum; } else { $item[$field] = $rowSum; } } // check if the value is coming from an object or is an element of an array $value = 0; if (is_object($item)) { // if this is an object we need to check if the field we are looking for is a method or a value if (method_exists($item, $field)) { $value = $item->{$field}(); } else { $value = $item->{$field}; } } else { $value = $item[$field]; } if (in_array($field, $colsToBlank)) { if (!isset($previousVals[$field]) || $previousVals[$field] != $value) { $row[$field] = $value; // if this value that has changed is the 'first' value, then we need to reset all the other // 'previous' values from left to right from this position $previousVals = $this->resetPreviousVals($previousVals, $field); $previousVals[$field] = $value; } else { $row[$field] = ''; } } else { $row[$field] = $value; } if ($addCols && in_array($field, $addCols)) { $rowSum += $value; } } $addToTable[] = $row; $this->data[$tableName] = $addToTable; $i++; } // now that the tables have been created, need to do column summation on each. We could do this during // the above looping, but because we don't FORCE the items to be properly sorted first, we can't guarantee // that the columns that need summation are in the right places $addCols = $this->report->AddCols ? $this->report->AddCols->getValues() : array(); if (count($addCols)) { // if we had a row total, we'll add it in by default; it only makes sense! if (isset($this->headers[self::ADD_IN_ROWS_TOTAL])) { $addCols[] = self::ADD_IN_ROWS_TOTAL; } foreach ($this->data as $tableName => $data) { $sums = array(); $titleColumn = null; foreach ($data as $row) { $prevField = null; foreach ($row as $field => $value) { if (in_array($field, $addCols)) { // if we haven't already figured it out, we now know that we want the field BEFORE // this as the column we put the Total text into if (!$titleColumn) { $titleColumn = $prevField; } $cur = isset($sums[$field]) ? $sums[$field] : 0; // use a report custom method for adding up or count/sum it up // based on the best possible assumptions we can make if (method_exists($this->report, 'columnAdder')) { $sums[$field] = $this->report->columnAdder($field, $cur, $value); } else { // summing up totals makes only sense if it is a number // otherwise we count the number of items if (is_numeric($value)) { $sums[$field] = $cur + $value; } else { $sums[$field] = $cur + 1; } } } else { $sums[$field] = ''; } $prevField = $field; } } // figure out the name of the field we want to stick the Total text $sums[$titleColumn] = _t('ReportFormatter.ROW_TOTAL', 'Total'); $data[] = $sums; $this->data[$tableName] = $data; } } }
/** * Creates a report in a specified format, returning a string which contains either * the raw content of the report, or an object that encapsulates the report (eg a PDF). * * @param string $format * @param boolean $store * Whether to store the created report. * @param array $parameters * An array of parameters that will be used as dynamic replacements */ public function createReport($format = 'html', $store = false) { Requirements::clear(); $convertTo = null; $renderFormat = $format; if (isset(AdvancedReport::config()->conversion_formats[$format])) { $convertTo = 'pdf'; $renderFormat = AdvancedReport::config()->conversion_formats[$format]; } $reports = $this->ChildReports(); if (!$reports->count()) { return _t('AdvancedReport.NO_REPORTS_SELECTED', 'No reports selected'); } $contents = array(); foreach ($reports as $report) { if (!$report->ReportID) { continue; } $params = $report->Parameters; $report = $report->Report(); if ($params) { $params = $params->getValues(); $baseParams = $report->ReportParams->getValues(); $params = array_merge($baseParams, $params); $report->ReportParams = $params; } $formatter = $report->getReportFormatter($renderFormat); if ($formatter) { $contents[] = $report->customise(array('ReportContent' => $formatter->format())); } else { $contents[] = new ArrayData(array('ReportContent' => "Formatter for '{$renderFormat}' not found.")); } } $templates = array(get_class($this) . '_' . $renderFormat); $date = DBField::create_field('SS_Datetime', time()); $this->Description = nl2br($this->Description); $reportData = array('Reports' => new ArrayList($contents), 'Format' => $format, 'Now' => $date); $output = $this->customise($reportData)->renderWith($templates); if (!$output) { // put_contents fails if it's an empty string... $output = " "; } if (!$convertTo) { if ($store) { // stick it in a temp file? $outputFile = tempnam(TEMP_FOLDER, $format); if (file_put_contents($outputFile, $output)) { return new AdvancedReportOutput(null, $outputFile); } else { throw new Exception("Failed creating report in {$outputFile}"); } } else { return new AdvancedReportOutput($output); } } // hard coded for now, need proper content transformations.... switch ($convertTo) { case 'pdf': if ($store) { $filename = singleton('PdfRenditionService')->render($output); return new AdvancedReportOutput(null, $filename); } else { singleton('PdfRenditionService')->render($output, 'browser'); return new AdvancedReportOutput(); } break; default: break; } }
/** * Restructures the data objects according to the settings of the report. */ protected function reformatDataObjects() { $this->data = array(); $dataObjects = $this->report->getDataObjects(); $colsToBlank = $this->report->getDuplicatedBlankingFields(); $mapping = $this->report->getFieldMapping(); $i = 0; $previousVals = array(); $tableName = self::DEFAULT_TABLE_NAME; $paginateBy = $this->report->PaginateBy; $headerTemplate = $this->report->PageHeader ? $this->report->PageHeader : '$name'; $addCols = $this->report->AddInRows && count($this->report->AddInRows->getValues()) ? $this->report->AddInRows->getValues() : null; if (!$dataObjects) { $this->data[$tableName] = array(); return; } foreach ($dataObjects as $item) { // lets check to see whether this item has the paginate variable, if so we want to be // adding this result to that table entry if ($paginateBy) { $pageVar = is_object($item) ? $item->{$paginateBy} : $item[$paginateBy]; if ($pageVar) { $tableName = str_replace('$name', $pageVar, $headerTemplate); } else { $tableName = sprintf(_t('ReportFormatter.NO_PAGINATE_VALUE', 'No %s'), $paginateBy); } } $row = array(); $addToTable = isset($this->data[$tableName]) ? $this->data[$tableName] : array(); $rowSum = 0; foreach ($this->headers as $field => $display) { // Account for our total summation of things. if ($field == self::ADD_IN_ROWS_TOTAL) { if (is_object($item)) { $item->{$field} = $rowSum; } else { $item[$field] = $rowSum; } } $rawValue = is_object($item) ? $item->{$field} : $item[$field]; $value = ''; // based on the field name we've been given, lets // see if we can resolve it to a value on our data object if (isset($mapping[$field]) && $rawValue) { $format = $mapping[$field]; eval('$value = ' . $format . ';'); } else { if ($rawValue) { $value = $rawValue; } } if (in_array($field, $colsToBlank)) { if (!isset($previousVals[$field]) || $previousVals[$field] != $value) { $row[$field] = $value; // if this value that has changed is the 'first' value, then we need to reset all the other // 'previous' values from left to right from this position $previousVals = $this->resetPreviousVals($previousVals, $field); $previousVals[$field] = $value; } else { $row[$field] = ''; } } else { $row[$field] = $value; } if ($addCols && in_array($field, $addCols)) { $rowSum += $value; } } $addToTable[] = $row; $this->data[$tableName] = $addToTable; $i++; } // now that the tables have been created, need to do column summation on each. We could do this during // the above looping, but because we don't FORCE the items to be properly sorted first, we can't guarantee // that the columns that need summation are in the right places $addCols = $this->report->AddCols ? $this->report->AddCols->getValues() : array(); if (count($addCols)) { // if we had a row total, we'll add it in by default; it only makes sense! if (isset($this->headers[self::ADD_IN_ROWS_TOTAL])) { $addCols[] = self::ADD_IN_ROWS_TOTAL; } foreach ($this->data as $tableName => $data) { $sums = array(); $titleColumn = null; foreach ($data as $row) { $prevField = null; foreach ($row as $field => $value) { if (in_array($field, $addCols)) { // if we haven't already figured it out, we now know that we want the field BEFORE // this as the column we put the Total text into if (!$titleColumn) { $titleColumn = $prevField; } $cur = isset($sums[$field]) ? $sums[$field] : 0; $sums[$field] = $cur + $value; } else { $sums[$field] = ''; } $prevField = $field; } } // figure out the name of the field we want to stick the Total text $sums[$titleColumn] = _t('ReportFormatter.ROW_TOTAL', 'Total'); $data[] = $sums; $this->data[$tableName] = $data; } } }