/** * 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; } } }
/** * 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; } } }