fn = $fn; if (!is_null($this->fn)) if (!$this->loadTemplateFile($fn)) throw new Exception("Cannot open template file $fn (or file is empty)."); else { // we got the template $this->extractSubReports(); } } public function loadTemplateFile($fn) { if ((!$fn) ) { throw new Exception("Cannot open template file $fn"); } if (file_exists($fn)) $this->templateBody = @file_get_contents($fn); else if (file_exists(getcwd()."/".$fn)) $this->templateBody = @file_get_contents(getcwd()."/".$fn); else return false; if ((!$this->templateBody) or (strlen($this->templateBody) < 1) ) return false; else return true; } private function extractSubReports() { $tokens = array(); if (preg_match_all('/(.*)/sim',$this->templateBody, $tokens) <= 0) return; $this->subReports = array(); $this->subReportsBands = array(); if ( (is_array($tokens)) && (isset($tokens[1])) && (sizeof($tokens[1])>0) ) foreach ($tokens[1] as $k => $v) { $this->subReports[strtolower($v)] = $tokens[0][$k]; $this->extractBandsForSubReport($v); $this->extractAdditionalSubReportParameters($v); $this->extractFieldsToWatchForSubReport($v); } } private function extractFieldsToWatchForSubReport($name) { if (!isset($this->subReports[$name])) throw new Exception("Tried to extract FIELDS TO WATCH for subreport that do not exist ($name)."); $this->subReportsFieldsToSum[$name] = array(); if (preg_match_all('/\\(%(\\w+)\\.(\\w+)%\\)/sim', $this->subReports[$name], $tokens)>0) { if ( (is_array($tokens)) && (isset($tokens[1])) && (sizeof($tokens[1])>0) ) { foreach ($tokens[1] as $k => $v) { if (strtolower($v) == "avg") $this->subReportsFieldsToSum[$name][] = $tokens[2][$k]; else if (strtolower($v) == "sum") $this->subReportsFieldsToSum[$name][] = $tokens[2][$k]; } $this->subReportsFieldsToSum[$name] = array_unique($this->subReportsFieldsToSum[$name]); } } } private function extractAdditionalSubReportParameters($name) { if (!isset($this->subReports[$name])) throw new Exception("Tried to extract ADDITIONAL PARAMETERS of subreport that do not exist ($name)."); $this->subReportsParameters[$name] = array(); if (preg_match_all('//sim',$this->subReports[$name], $tokens) <= 0) return; if ( (is_array($tokens)) && (isset($tokens[0][0])) ) { $opts = array(); if (preg_match_all('/(\\w+=\\"\\w+\\")+/sim',$tokens[0][0], $opts) <= 0) return; if ( (is_array($opts)) && (isset($opts[0])) ) foreach ($opts[0] as $v) { $o = explode("=",$v); $this->subReportsParameters[$name][$o[0]] = substr($o[1],1,-1); } } } private function extractBandsForSubReport($name) { $name = strtolower($name); $tokens = array(); if (preg_match_all('/(.*)/sim',$this->subReports[$name], $tokens) <= 0) return; $this->subReportsBands[$name] = array(); if ( (is_array($tokens)) && (isset($tokens[3])) && (sizeof($tokens[3])>0) ) foreach ($tokens[3] as $k => $v) $this->subReportsBands[strtolower($name)][$v] = $tokens[2][$k]; } public function hasSubReports() { return (is_array($this->subReports) && (sizeof($this->subReports) > 0) ); } private function getSubReportsHeaderBand($name) { if (!isset($this->subReports[$name])) throw new Exception("Tried to open HEADER band of subreport that do not exist ($name)."); if (isset($this->subReportsBands[$name]["header"])) return ($this->subReportsBands[$name]["header"]); else { // here add some logic to determine what is header if no bands are marked in subreport return ''; } } private function getSubReportsDetailBand($name) { if (!isset($this->subReports[$name])) throw new Exception("Tried to open DETAIL band of subreport that do not exist ($name)."); if (isset($this->subReportsBands[$name]["detail"])) return ($this->subReportsBands[$name]["detail"]); else { // no detail band, so if there is no header and no footer then, all is detail if ( (!isset($this->subReportsBands[$name]["header"])) && (!isset($this->subReportsBands[$name]["footer"])) ) return ($this->subReports[$name]); else return ''; } } private function getSubReportsDetailEmptyBand($name) { if (!isset($this->subReports[$name])) throw new Exception("Tried to open DETAIL_EMPTY band of subreport that do not exist ($name)."); if (isset($this->subReportsBands[$name]["detail_empty"])) return ($this->subReportsBands[$name]["detail_empty"]); else { // no detail band, so if there is no header and no footer then, all is detail if ( (!isset($this->subReportsBands[$name]["header"])) && (!isset($this->subReportsBands[$name]["footer"])) ) return ($this->subReports[$name]); else return ''; } } private function getSubReportsFooterBand($name) { if (!isset($this->subReports[$name])) throw new Exception("Tried to open FOOTER band of subreport that do not exist ($name)."); if (isset($this->subReportsBands[$name]["footer"])) return ($this->subReportsBands[$name]["footer"]); else { // here add some logic to determine what is header if no bands are marked in subreport return ''; } } private function getSubReportParameter($subReportName,$parameterName) { if (isset($this->subReportsParameters[$subReportName][$parameterName])) return ($this->subReportsParameters[$subReportName][$parameterName]); else return null; } private function replaceAllTokensInText(&$text,$vars) { $tokens = array(); if ( preg_match_all('/\\(%(\\w+)%\\)/sim', $text, $tokens) > 0 ) { foreach ($tokens[1] as $v) $this->replaceOneTokenPlaceholderWithValue($text,$v,$vars[$v]); } } private function replaceAllTokensInCurrentSubReportRow(&$text,$name,$currentArrayIndex) { $this->replaceAllTokensInText($text,$this->vars[$name][$currentArrayIndex]); $tokens = array(); if ( preg_match_all('/\\(%(\\w+)\\.(\\w+)%\\)/sim', $text, $tokens) > 0 ) { if ( (is_array($tokens[1])) && (count($tokens[1])>0) ) foreach ($tokens[1] as $k => $v) { if ($v == "sum") $this->replaceOneTokenPlaceholderWithValue($text,"sum.".$tokens[2][$k],$this->subReportsSums[$name][$tokens[2][$k]]); } } } private function replaceOneTokenPlaceholderWithValue(&$text,$tokenname,$tokenvalue) { $text = str_ireplace("(%".$tokenname."%)",$tokenvalue,$text); } private function updateSubReportsWatches($subReportName, $currentArrayIndex) { isset($this->subReportsCounts[$subReportName]) ? $this->subReportsCounts[$subReportName]++ : $this->subReportsCounts[$subReportName] = 1; isset($this->subReportsGlobalCounts[$subReportName]) ? $this->subReportsGlobalCounts[$subReportName]++ : $this->subReportsGlobalCounts[$subReportName] = 1; if (count($this->subReportsFieldsToSum[$subReportName]) > 0) foreach ($this->subReportsFieldsToSum[$subReportName] as $fn) { isset($this->subReportsSums[$subReportName][$fn]) ? $this->subReportsSums[$subReportName][$fn] += $this->vars[$subReportName][$currentArrayIndex][$fn] : $this->subReportsSums[$subReportName][$fn] = $this->vars[$subReportName][$currentArrayIndex][$fn]; isset($this->subReportsGlobalSums[$subReportName][$fn]) ? $this->subReportsGlobalSums[$subReportName][$fn] += $this->vars[$subReportName][$currentArrayIndex][$fn] : $this->subReportsGlobalSums[$subReportName][$fn] = $this->vars[$subReportName][$currentArrayIndex][$fn]; } } private function resetSubReportsTemporaryWatches($name) { $this->subReportsSums[$name] = array(); $this->subReportsCounts[$name] = 0; } private function parseSingleSubReport($name) { if (!isset($this->subReports[$name])) return ; $breakColumnName = $this->getSubReportParameter($name,"break"); $breakingThisSubReport = ((!is_null($breakColumnName)) && isset($this->vars[$name][0][$breakColumnName])) ? true : false; $result = ''; if ( (isset($this->vars[$name])) && (is_array($this->vars[$name])) && (sizeof($this->vars[$name])>0) ) { if ($breakingThisSubReport) $previousKey = $this->vars[$name][0][$breakColumnName]; $rowcount = sizeof($this->vars[$name]); for ($i = 0; $i < $rowcount; $i++) { $v = $this->vars[$name][$i]; $firstTime = ($i == 0); if ( ($firstTime) || ( $breakingThisSubReport && ($previousKey != $v[$breakColumnName])) ) { $result .= $this->getSubReportsHeaderBand($name); $this->resetSubReportsTemporaryWatches($name); } $result .= $this->getSubReportsDetailBand($name); if ( ( ($i >= ($rowcount-1)) ) || ( ($breakingThisSubReport) && ($v[$breakColumnName] != $this->vars[$name][$i+1][$breakColumnName]) ) ) $result .= $this->getSubReportsFooterBand($name); if ($breakingThisSubReport) $previousKey = $v[$breakColumnName]; $this->updateSubReportsWatches($name, $i); $this->replaceAllTokensInCurrentSubReportRow($result, $name, $i); } } else { $result .= $this->getSubReportsHeaderBand($name); $result .= $this->getSubReportsDetailEmptyBand($name); $result .= $this->getSubReportsFooterBand($name); } $this->body = preg_replace('/(.*)/sim',$result, $this->body); } private function parseSubReports() { if (!$this->hasSubReports()) return; foreach ($this->subReports as $name => $value) { $this->parseSingleSubReport($name); } } public function assign($name, $value) { $this->vars[$name] = $value; } public function parse($andShow = true) { $this->body = $this->templateBody; $this->parseSubReports(); //$this->parseTokens(); if ($andShow) echo $this->body; } } // class ?>