/** Format data for display @param $data a two dimensional array of data @param $headers a header row (optional) @param $format output format (html | xls | csv) @return formatted string */ public function render_data($data, $headers = array(), $footers = array(), $format = 'html') { $url = $this->config->get('URL'); $ret = ""; switch (strtolower($format)) { case 'html': if ($this->multi_counter == 1) { if (!$this->new_tablesorter) { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { // windows has trouble with symlinks $this->add_css_file($url . 'src/javascript/tablesorter-2.0.5b/themes/blue/style.css'); } else { $this->add_css_file($url . 'src/javascript/tablesorter/themes/blue/style.css'); } } else { $this->add_css_file($url . 'src/javascript/tablesorter-2.22.1/css/theme.bootstrap.css'); } if (!$this->window_dressing) { $ret .= '<!DOCTYPE html><html><head>' . '<meta http-equiv="Content-Type" ' . 'content="text/html; charset=iso-8859-1">' . '</head><body>'; $ret .= '<script type="text/javascript"> function highlightCell(e) { if ($(this).css(\'background-color\') != \'rgb(255, 255, 0)\') { $(this).css(\'background-color\',\'yellow\'); } else { $(this).css(\'background-color\',\'\'); } } </script>'; } $ret .= '<div id="pre-report-content">'; $uri = filter_input(INPUT_SERVER, 'REQUEST_URI'); if (\COREPOS\Fannie\API\data\DataConvert::excelSupport()) { $ret .= sprintf('<a href="%s%sexcel=xls">Download Excel</a> ', $uri, strstr($uri, '?') === false ? '?' : '&'); } $json = FormLib::queryStringtoJSON(filter_input(INPUT_SERVER, 'QUERY_STRING')); $ret .= sprintf('<a href="%s%sexcel=csv">Download CSV</a> <a href="?json=%s">Back</a>', $uri, strstr($uri, '?') === false ? '?' : '&', base64_encode($json)); $ret = array_reduce($this->defaultDescriptionContent(count($data)), function ($carry, $line) { return $carry . (substr($line, 0, 1) == '<' ? '' : '<br />') . $line; }, $ret); $ret = array_reduce($this->report_description_content(), function ($carry, $line) { return $carry . (substr($line, 0, 1) == '<' ? '' : '<br />') . $line; }, $ret); $ret .= '</div>'; } if ($this->sortable || $this->no_sort_but_style) { $ret .= '<table class="mySortableTable tablesorter tablesorter-bootstrap">'; } else { $ret .= '<table class="mySortableTable" cellspacing="0" cellpadding="4" border="1">' . "\n"; } break; case 'csv': foreach ($this->defaultDescriptionContent(count($data)) as $line) { $ret .= $this->csvLine(array(strip_tags($line))); } foreach ($this->report_description_content() as $line) { $ret .= $this->csvLine(array(strip_tags($line))); } case 'xls': break; } if (!empty($headers)) { $headers1 = $this->select_headers(False); if (!$this->multi_report_mode && strtolower($format) != 'xls') { $this->header_index++; } switch (strtolower($format)) { case 'html': $ret .= '<thead>' . "\n"; $ret .= $this->htmlLine($headers1, True); $ret .= '</thead>' . "\n"; break; case 'csv': $ret .= $this->csvLine($headers1); break; case 'xls': break; } } for ($i = 0; $i < count($data); $i++) { switch (strtolower($format)) { case 'html': if ($i == 0) { $ret .= "<tbody>\n"; } $ret .= $this->htmlLine($data[$i]); if ($i == count($data) - 1) { $ret .= "</tbody>\n"; } break; case 'csv': $ret .= $this->csvLine($data[$i]); break; case 'xls': break; } } if (!empty($footers)) { switch (strtolower($format)) { case 'html': $ret .= '<tfoot>'; // A single footer row if (!is_array($footers[0])) { $ret .= $this->htmlLine($footers, True); // More than one footer row } else { foreach ($footers as $footer) { $ret .= $this->htmlLine($footer, True); } } $ret .= '</tfoot>'; break; case 'csv': // A single footer row if (!is_array($footers[0])) { $ret .= $this->csvLine($footers); // More than one footer row } else { foreach ($footers as $footer) { $ret .= $this->csvLine($footer); } } break; case 'xls': break; } } switch (strtolower($format)) { case 'html': $ret .= '</table>'; $ret = array_reduce($this->report_end_content(), function ($carry, $line) { return $carry . (substr($line, 0, 1) == '<' ? '' : '<br />') . $line; }, $ret); if (!$this->no_jquery && !$this->new_tablesorter) { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { // windows has trouble with symlinks $this->add_script($url . 'src/javascript/jquery-1.11.1/jquery-1.11.1.min.js'); } else { $this->add_script($url . 'src/javascript/jquery.js'); } } if (!$this->new_tablesorter) { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { // windows has trouble with symlinks $this->add_script($url . 'src/javascript/tablesorter-2.0.5b/jquery.tablesorter.js'); } else { $this->add_script($url . 'src/javascript/tablesorter/jquery.tablesorter.js'); } } else { $this->add_script($url . 'src/javascript/tablesorter-2.22.1/js/jquery.tablesorter.js'); $this->add_script($url . 'src/javascript/tablesorter-2.22.1/js/jquery.tablesorter.widgets.js'); } $sort = sprintf('[[%d,%d]]', $this->sort_column, $this->sort_direction); if ($this->sortable) { if (!$this->new_tablesorter) { $this->add_onload_command("\$('.mySortableTable').tablesorter({sortList: {$sort}, widgets: ['zebra']});"); } else { $this->add_onload_command("\$.tablesorter.themes.bootstrap['active'] = 'info';"); $this->add_onload_command("\$.tablesorter.themes.bootstrap['table'] += ' tablesorter-core table-condensed small';"); $this->add_onload_command("\$.tablesorter.themes.bootstrap['header'] += ' table-condensed small';"); $this->add_onload_command("\$('.mySortableTable').tablesorter({sortList: {$sort}, theme:'bootstrap', headerTemplate: '{content} {icon}', widgets: ['uitheme','zebra']});"); } } elseif ($this->new_tablesorter) { /** New bootstrap-themed tablesorter requires more setup to style correctly even when sorting isn't used. Simply including a CSS file is not sufficient. */ $this->add_onload_command("\$.tablesorter.themes.bootstrap['active'] = 'info';"); $this->add_onload_command("\$.tablesorter.themes.bootstrap['table'] += ' tablesorter-core table-condensed small';"); $this->add_onload_command("\$.tablesorter.themes.bootstrap['header'] += ' table-condensed small';"); $this->add_onload_command("\$('.mySortableTable thead th').data('sorter', false);\n"); $this->add_onload_command("\$('.mySortableTable').tablesorter({theme:'bootstrap', headerTemplate: '{content} {icon}', widgets: ['uitheme','zebra']});"); } break; case 'csv': header('Content-Type: application/ms-excel'); header('Content-Disposition: attachment; filename="' . $this->header . '.csv"'); foreach ($this->report_end_content() as $line) { $ret .= $this->csvLine(array(strip_tags($line))); } break; case 'xls': // headers empty in multi-report-mode if (!empty($headers)) { $headers1 = $this->select_headers(True); array_unshift($data, $headers1); } if (!$this->multi_report_mode) { $data = $this->xlsMeta($data); } for ($i = 0; $i < count($data); $i++) { for ($j = 0; $j < count($data[$i]); $j++) { if (isset($data[$i][$j])) { $data[$i][$j] = $this->excelFormat($data[$i][$j]); } } } $xlsdata = $data; // footers empty in multi-report-mode if (!empty($footers)) { // A single footer row if (!is_array($footers[0])) { array_push($xlsdata, $footers); // More than one footer row } else { $xlsdata = array_reduce($footers, function ($carry, $footer) { $carry[] = $footer; return $carry; }, $xlsdata); } } $xlsdata = array_reduce($this->report_end_content(), function ($carry, $line) { $carry[] = strip_tags($line); return $carry; }, $xlsdata); $xlsdata = array_merge(array_reduce($this->report_description_content(), function ($carry, $line) { $carry[] = strip_tags($line); return $carry; }, array()), $xlsdata); // prepend $xlsdata = array_merge(array_reduce($this->defaultDescriptionContent(count($data)), function ($carry, $line) { $carry[] = strip_tags($line); return $carry; }, array()), $xlsdata); // prepend $ext = \COREPOS\Fannie\API\data\DataConvert::excelFileExtension(); $ret = \COREPOS\Fannie\API\data\DataConvert::arrayToExcel($xlsdata); header('Content-Type: application/ms-excel'); header('Content-Disposition: attachment; filename="' . $this->header . '.' . $ext . '"'); break; } $this->multi_counter++; $this->header_index++; return $ret; }