public function run() { // process any search data that may be passed if (is_array($this->_data['Search']) && isset($this->_data['Search']['report_id'])) { $this->_data[$this->_templateobject->idField] = $this->_data['Search']['report_id']; unset($this->_data['Search']['report_id']); } if (!$this->loadData()) { $this->dataError(); sendBack(); } $flash = Flash::Instance(); // get the report model, lets not envoke it again... that's not cool $report = $this->_uses[$this->modeltype]; // there's no point in processing all the following data just to display the dialog... display it now if (isset($this->_data['printaction']) || isset($this->_data['printAction']) || isset($this->_data['ajax_print'])) { // build options array $defs = ReportDefinition::getDefinition('PrintCollection'); $dialog_options = array('type' => array('pdf' => '', 'xml' => '', 'csv' => ''), 'output' => array('print' => '', 'save' => '', 'email' => '', 'view' => ''), 'filename' => strtolower(str_replace(" ", "_", $report->description)) . '_' . date('d-m-Y')); // if ajax_print is not set we must be on the dialog if (!isset($this->_data['ajax_print'])) { return $dialog_options; } } // give smarty the title $this->view->set('title', $report->description); // unserialise the options from the db $options = unserialize($report->options); // overlay the defaults so we've got a full set of options $options = $this->expand_options($options, $report->tablename); // sort options by position $options = $this->sort_options($options); // vars $aggregate_fields = array(); $at_agg = FALSE; $fields = array(); $display_fields = array(); $measure_fields = array(); $search_fields = array(); $filter_fields = array(); $aggregate_methods = array(); // build arrays for use in the view foreach ($options as $field => $field_options) { // we need to check against legacy search options if ($field_options['field_type'] === 'search') { $flash->addError('Report has legacy search fields, please edit this report to update'); sendBack(); } // ignore the filter field... it really isn't a field if ($field == 'filter') { continue; } // iron out the field label if it exists if (isset($field_options['field_label']) && !empty($field_options['field_label'])) { $label = $field_options['field_label']; } else { $label = $field; } $position = $field_options['position']; // we're always dealing with normal fields now // no need for a switch statement // ignore fields that aren't meant to be displayed if ($field_options['normal_display_field'] !== 'false') { // build two arrays, the display fields array will include filter fields... for now $original_fields[$position] = $field; $display_fields[$position] = $field; if ($field_options['normal_break_on'] === "true") { $measure_fields[$position] = $field; } if (!empty($field_options['normal_method']) && $field_options['normal_method'] !== 'dont_total') { $aggregate_fields[$position] = $field; $aggregate_methods[$position] = $field_options['normal_method'] . '(' . $field . ') as ' . $field; // if we're setting an aggregate field... this must not be a display field unset($display_fields[$position]); } } // if the field is also a search field, add it to the search array if (isset($field_options['normal_enable_search']) && $field_options['normal_enable_search'] === 'true') { $search_fields[$field] = $field_options; } } // if the filters aren't empty, apply them one by one if (!empty($options['filter'])) { // loop through filter lines foreach (range(1, 3) as $number) { if (!isset($filter_cc)) { $filter_cc = new ConstraintChain(); } // filter line 1 will never have an operator if ($number === 1) { $operator = 'AND'; } else { $operator = $options['filter']['filter_' . $number . '_operator']; } $field = $options['filter']['filter_' . $number . '_field']; $condition = $options['filter']['filter_' . $number . '_condition']; $value = $options['filter']['filter_' . $number . '_value']; // if we're dealing with a valid filter line... if (($number === 1 or !empty($operator)) and !empty($value)) { // add the field to the display fields if (!array_search($field, $display_fields)) { $display_fields = array_merge($display_fields, array($field)); } // add the filter to the contraint chain $filter_cc->add(new Constraint($field, $condition, $value), $operator); } } } // NB: The follow idField is being passed by reference... it isn't passing a value, instead recieving one back $do = $report->createDataObject($display_fields, $idField, $this->getColumns($report->tablename)); $doc = new DataObjectCollection($do); $sh = new SearchHandler($doc, FALSE); $sh->setGroupby($display_fields); $sh->setOrderby($display_fields); if (!isset($this->_data['Search'])) { $this->_data['Search'] = array(); } // we don't need a condition here... always display the search box $this->search = $report->createSearch($search_fields, $this->_data['Search']); $cc = $this->search->toConstraintChain(); $cc->removeByField('report_id'); $sh->addConstraintChain($cc); // if the filter constraint chain has been set, use it if (isset($filter_cc)) { $sh->addConstraintChain($filter_cc); } $measure_fields = array_merge(array('' => 'report'), $measure_fields); /// merge the aggregate methods array in with the display fields array // the aggregate methods array is preset as an array to allow for empty values // we don't use the array_merge function as we want to maintain keys (representing position) $display_fields = (array) $display_fields + (array) $aggregate_methods; if (count($aggregate_fields) === 0) { $this->view->set('aggregate_count', 0); } // sort display fields by key (position) ksort($display_fields); // prepend the id field to the display fields... // at this stage the items are in order, so keys don't matter $display_fields = array_merge(array($idField), $display_fields); $sh->setFields($display_fields); $data = $doc->load($sh, null, RETURN_ROWS); $this->view->set('total_records', $doc->total_records); $headings = $doc->getHeadings(); // loop through headings... foreach ($headings as $key => $field) { if (!array_search($key, $original_fields)) { // if item isn't in original fields remove it from headings array unset($headings[$key]); } else { // if label exists, use that for heading if (!empty($options[$key]['normal_field_label'])) { $headings[$key] = $options[$key]['normal_field_label']; } } } $heading_keys = array_keys($headings); $this->view->set('headings', $headings); /* * Build the data array * * There is no point in processing everything just to output the * print dialog OR is we're CSVing the output. */ if (!isset($this->_data['printaction']) && !isset($this->_data['printAction']) || $this->_data['print']['printtype'] !== 'csv') { $response = $this->buildArray($data, $headings, $measure_fields, $aggregate_fields, $heading_keys, $options); $data_arr = $response['data_arr']; $sub_total_keys = $response['sub_total_keys']; } $this->view->set('options', $options); // are we being called from a print dialog or are we actually printing? if (isset($this->_data['printaction']) || isset($this->_data['printAction']) || isset($this->_data['ajax_print'])) { if ($this->_data['print']['printtype'] === 'csv') { $dialog_options['csv_source'] = $this->generate_csv($this->_data['print'], $data_arr, array_keys($headings)); } else { // build xml $xml = ''; $xml .= "<data>" . "\n"; if (!empty($data_arr)) { foreach ($data_arr as $key => $row) { // if row is a subtotal, construct an appropriate attribute $row_class = ''; if (isset($sub_total_keys[$key])) { $row_class = 'sub_total="true"'; } // build the xml // cannot utalise all of the output functions as we need to do some specific stuff $xml .= "\t" . "<record " . $row_class . ">" . "\n"; foreach ($row as $field => $value) { $cell_class = array(); if (isset($options[$field]['normal_red_negative_numbers']) && $options[$field]['normal_red_negative_numbers'] == "true" && $value < 0) { $cell_class[] = 'negative_number="true"'; } if ($options[$field]['normal_enable_formatting'] === 'true') { if (isset($options[$field]['normal_justify'])) { $cell_class[] = 'text-align="' . $options[$field]['normal_justify'] . '"'; } } $xml .= "\t\t" . "<" . $field . " " . implode(' ', $cell_class) . ">" . $value . "</" . $field . ">" . "\n"; } $xml .= "\t" . "</record>" . "\n"; } } $xml .= "</data>" . "\n"; // build xsl $col_widths = array(); if (isset($this->_data['col_widths'])) { $col_widths = $this->parse_column_widths($this->_data['col_widths']); } // Use the report defintion defined in DB, else use the standard list xsl if ($report->report_definition) { $def = new ReportDefinition(); $def->loadBy('id', $report->report_definition); $report_definition_name = $def->_data['name']; } else { $report_definition_name = 'PrintCollection'; } $xsl = $this->build_custom_xsl($doc, $report_definition_name, $report->description, $headings, $col_widths, $options); // set resources $dialog_options['xmlSource'] = $xml; $dialog_options['xslSource'] = $xsl; $search_options = $this->search->toString('fop'); if (!empty($search_options)) { $dialog_options['xslVars']['search_string'] = "Search options: " . $search_options; } else { $dialog_options['xslVars']['search_string'] = ''; } } $this->_data['print']['attributes']['orientation-requested'] = 'landscape'; // execute the print output function, echo the returned json for jquery echo $this->generate_output($this->_data['print'], $dialog_options); exit; } $this->view->set('report_array', $data_arr); $this->view->set('sub_total_keys', $sub_total_keys); }
public function PrintCollection($collection = NULL) { if (!$this->isPrinting()) { return parent::printCollection($collection); } if (!isset($this->_data) || !$this->loadData()) { $this->dataError(); sendBack(); } $dataset = $this->_uses[$this->modeltype]; $model = $this->newModel($dataset); $title = $model->getTitle(); $s_data = array(); $search_id = $_SESSION['printing'][$this->_data['session_key']]['search_id']; $collection = new DataObjectCollection($model, $this->_schema . '.' . $dataset->name . '_overview'); $collection->getHeadings(); $sh = $this->setSearchHandler($collection, $search_id, TRUE); $sh->setLimit(0); $this->load_collection($collection, $sh); parent::printCollection($collection); }
public function build_print_resources(DataObjectCollection $collection, $args = array()) { // by this point the collection must already have been loaded // create report title $report_title = $this->generate_collection_name(FALSE, $collection->title); // get the headings from the collection, loop through and remove and id fields $coll_headers = array(); $fields = $collection->getHeadings(); foreach ($fields as $field => $title) { if (substr($field, -2) != 'id') { $coll_headers[$field] = $title; } } // allow extra headers to be added if (isset($args['coll_headers'])) { $coll_headers = array_merge($coll_headers, $args['coll_headers']); } $col_widths = ''; if (isset($this->_data['col_widths'])) { $col_widths = $this->_data['col_widths']; } $measure_fields = array(); // get the data if (isset($_SESSION['printing'][$this->_data['index_key']]['break']['measure_fields'])) { $measure_fields = $_SESSION['printing'][$this->_data['index_key']]['break']['measure_fields']; } $aggregate_fields = array(); if (isset($_SESSION['printing'][$this->_data['index_key']]['break']['aggregate_fields'])) { $aggregate_fields = $_SESSION['printing'][$this->_data['index_key']]['break']['aggregate_fields']; } if (!empty($measure_fields) || !empty($aggregate_fields)) { $field_formatting = array(); if (isset($_SESSION['printing'][$this->_data['index_key']]['break']['field_formatting'])) { $field_formatting = $_SESSION['printing'][$this->_data['index_key']]['break']['field_formatting']; } $default_options = array('normal_field_label' => '', 'normal_display_field' => TRUE, 'normal_break_on' => FALSE, 'normal_method' => 'dont_total', 'normal_total' => 'none', 'normal_enable_formatting' => FALSE, 'normal_decimal_places' => 0, 'normal_red_negative_numbers' => FALSE, 'normal_thousands_seperator' => FALSE); foreach ($fields as $field => $title) { foreach ($default_options as $option => $value) { if (!isset($field_formatting[$field][$option])) { if ($option == 'normal_break_on' && isset($measure_fields[$field])) { $field_formatting[$field][$option] = TRUE; } else { $field_formatting[$field][$option] = $value; } } } } $formatting_options = array_merge($default_options, $field_formatting); $arr_data = $this->generate_subtotals($collection, $coll_headers, $measure_fields, $aggregate_fields, array_keys($coll_headers), $formatting_options); $coll_data = $arr_data['data_arr']; $subtotal_keys = $arr_data['sub_total_keys']; } else { if ($collection instanceof DataObjectCollection || is_array($collection)) { foreach ($collection as $detailRow) { $printDetail[] = $this->construct_line($detailRow, $coll_headers); } $coll_data = $printDetail; $formatting_options = array(); $subtotal_keys = array(); } } // build the custom XSL // $xsl = $this->build_custom_xsl($collection, 'CustomReport', $report_title, $coll_headers, $col_widths, $formatting_options); $xsl = $this->build_custom_xsl($collection, $this->_data['print']['report'], $report_title, $coll_headers, $col_widths, $formatting_options); if ($xsl === FALSE) { return FALSE; } // construct basic XML of data $xml = $this->build_custom_xml($coll_data, $coll_headers, $formatting_options, $subtotal_keys); return array('xml' => $xml, 'xsl' => $xsl); }