This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/modules/report/class.Level.php
anubis fae6352bf2 Update to PEAR 1.7.2, Image_Canvas 0.3.1, Image_Color 1.0.3, Image_Graph 0.7.2, XML_Parser 1.3.1.
Removed PHP_Compat, and references to it.
Removed ionCube/Zend/mmCache compatibility checks in test.php script.
Changed minimum PHP requirement to 5.0 in test.php script.
2009-01-04 19:22:54 -05:00

1058 lines
31 KiB
PHP

<?php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software; you can redistribute it and/or
* modify it under the terms of the Open AgileBill License
* License as published at http://www.agileco.com/agilebill/license1-4.txt
*
* For questions, help, comments, discussion, etc., please join the
* Agileco community forums at http://forum.agileco.com/
*
* @link http://www.agileco.com/
* @copyright 2004-2008 Agileco, LLC.
* @license http://www.agileco.com/agilebill/license1-4.txt
* @author Tony Landis <tony@agileco.com> and Thralling Penguin, LLC <http://www.thrallingpenguin.com>
* @package AgileBill
* @version 1.4.93
*/
class LevelGraph extends Level_Base {
var $lev_setting;
var $lev_items;
var $SQL_filtered;
var $group_level;
var $grouping_criteria;
var $formatter;
var $graph;
var $plotarea;
var $dataset;
var $canvas;
function LevelGraph (
$title = '',
$width=800,
$height=300,
$type='bar',
$direction = 'vertical',
$x_angle = 90)
{
if(!strlen($direction)) $direction = 'vertical';
$this->lev_setting = array(
"title" => $title,
"width" => $width,
"height" => $height,
"y_label_angle" => 0,
"x_label_angle" => intval($x_angle),
"type" => $type,
"direction" => $direction,
"SQL_criteria" => ''
);
}
function addDataset ($SQL_select, $SQL_criteria='', $SQL_order='')
{
$this->dataset[] = array(
"SQL_select" => $SQL_select,
"SQL_criteria" => $SQL_criteria,
"SQL_order" => $SQL_order
);
}
function display ($grouping_criteria = Null, $grouping_aggregate = Null, &$formatter)
{
$this->formatter =& $formatter;
$this->formatter->setLevel($this);
$this->grouping_criteria = $grouping_criteria;
$this->grouping_aggregate = $grouping_aggregate;
$this->group_level = false;
if (count($this->lev_items) > 0) {
$this->group_level = true;
}
set_include_path(get_include_path().PATH_SEPARATOR.PATH_INCLUDES."pear");
include_once 'Image/Graph.php';
include_once 'Image/Canvas.php';
$this->canvas =& Image_Canvas::factory('png', array(
'width' => $this->lev_setting["width"],
'height' => $this->lev_setting["height"],
'antialias' => 'native'
));
$this->graph =& Image_Graph::factory('graph', $this->canvas);
$this->plotarea =& $this->graph->addNew('plotarea',array(
'Image_Graph_Axis_Category', 'Image_Graph_Axis', $this->lev_setting['direction']
));
$this->plotarea->setFillColor('black@0.1');
#$this->plotarea->showShadow();
$AxisX =& $this->plotarea->getAxis(IMAGE_GRAPH_AXIS_X);
$AxisY =& $this->plotarea->getAxis(IMAGE_GRAPH_AXIS_Y);
$AxisX->setFontAngle($this->lev_setting["x_label_angle"]);
$AxisY->setFontAngle($this->lev_setting["y_label_angle"]);
foreach($this->dataset as $dset) {
$SQL_criteria = '';
if ($dset['SQL_criteria'] != '') {
$SQL_criteria = $this->addToFilter($SQL_criteria,
$dset['SQL_criteria']);
}
#echo "C1: ".$SQL_criteria."<BR>";
if ($this->lev_setting['SQL_criteria'] != '') {
$SQL_criteria = $this->addToFilter($SQL_criteria,
$this->lev_setting['SQL_criteria']);
}
#echo "C2: ".$SQL_criteria."<BR>";
if (count($this->grouping_criteria) > 0) {
foreach ($this->grouping_criteria as $key => $value) {
$SQL_criteria = $this->addToFilter($SQL_criteria,
"$key = $value",
$this->grouping_aggregate[$key]
);
}
}
#echo "C3: ".$SQL_criteria."<BR>";
$this->SQL_filtered = $this->shuffleSQL($dset["SQL_select"].$SQL_criteria." ".$dset["SQL_order"]);
if(defined('REPORT_DEBUG'))
echo "<br>The SQL_filtered is: " . $this->SQL_filtered . "<br>";
$db =& DB();
$result = $db->Execute($this->SQL_filtered);
if(!$result) {
echo "SQL: ".$this->SQL_filtered."<br>".$db->ErrorMsg();
exit;
}
$num_rows = $result->RecordCount();
if ($num_rows == 0) {
return;
}
$Dataset =& Image_Graph::factory('dataset');
while(!$result->EOF) {
$Dataset->addPoint($result->fields[0],$result->fields[1]);
$result->MoveNext();
}
$Plot =& $this->plotarea->addNew($this->lev_setting["type"], &$Dataset);
}
$file = tempnam($this->formatter->output_path."/", "s");
@unlink($file);
$file .= ".png";
$this->graph->done(
array('filename' => $file)
);
# add to output
$this->formatter->insertImage(
$file,
$this->lev_setting["width"],
$this->lev_setting["height"]
);
#intersperse and whatnot
if ($this->group_level === true) {
$this->formatter->endTable();
}
if ($this->group_level === true) {
$this->intersperse($this->grouping_criteria,$this->grouping_aggregate);
}
}
}
class Level extends Level_Base {
var $lev_setting;
var $lev_fields;
var $lev_items;
var $indent_html;
var $SQL_filtered;
var $group_level;
var $grouping_criteria;
var $has_title;
var $formatter;
var $add_headers = 0;
var $class;
function Level ($title='',
$SQL_select='', $SQL_criteria='', $SQL_order='',
$title_table_class='title', $title_class='', $indent=0,
$lev_field_width = '',
$lev_field_class = 'row', $lev_label_class = '', $lev_table_class = 'level',
$lev_tot_class = 'rc-lev-tot1', $lev_colspan_label_class = 'rc-lev-colspan-label1')
{
if($lev_field_class == 'row') {
$lev_field_class = new ReportStyle;
$lev_field_class->backgroundColor(230,230,230);
}
if($lev_label_class == '') {
$lev_label_class = new ReportStyle;
$lev_label_class->bold();
$lev_label_class->fontFamily('arial');
$lev_label_class->is_heading = true;
}
$this->lev_setting = array(
"title" => $title,
"SQL_select" => $SQL_select,
"SQL_criteria" => $SQL_criteria,
"SQL_order" => $SQL_order,
"title_class_html" => $title_class,
"title_table_class_html" => $title_table_class,
"indent" => $indent,
"lev_field_width" => $lev_field_width,
"lev_field_class" => $lev_field_class,
"lev_label_class" => $lev_label_class,
"lev_table_class_html" => $lev_table_class,
"lev_tot_class" => $lev_tot_class,
"lev_colspan_label_class" => $lev_colspan_label_class,
"class" => ''
);
}
function setTitle($t)
{
$this->lev_setting["title"] = $t;
}
function setSql($s)
{
$this->lev_setting["SQL_select"] = $s;
}
function setCriteria($c)
{
$this->lev_setting["SQL_criteria"] = $c;
}
function setOrderby($o)
{
$this->lev_setting["SQL_order"] = $o;
}
function setIndent($i)
{
$this->lev_setting["indent"] = $i;
return $i;
}
function setClass($c)
{
$this->lev_setting["class"] = $c;
}
function addField ($label, $name, $isAggregate = false, $width = '', $format = '',
$group_children_by = false, $visible = true, $hide_dups = false,
$class = '', $lev_class_also = false, $label_class = '', $lev_label_class_also = false,
$condition = '', $cond_class = '',
$SQL_select = '', $SQL_criteria = '',
$colspan = 0, $colspan_label = '', $colspan_label_class = '', $lev_colspan_class_also = false,
$has_tot = false, $tot_label = '', $tot_format = '', $tot_class = '', $lev_tot_class_also = false,
$link = '')
{
//NB every field added MUST be in the source SQL
//if a grouping variable, then set group_children_by to True
//if a field is an aggregate, then it must be True. This causes it's usage to be in HAVING clause, instead of WHERE
if ($link != "") {
$is_link = True;
$link_text_start = $link["link_text_start"];
$link_text_end = $link["link_text_end"];
$link_title_start = $link["link_title_start"];
$link_title_end = $link["link_title_end"];
$link_href_start = $link["link_href_start"];
$link_href_end = $link["link_href_end"];
} else {
$is_link = False;
$link_text_start = "";
$link_text_end = "";
$link_title_start = "";
$link_title_end = "";
$link_href_start = "";
$link_href_end = "";
}
if($tot_class == '') {
$tot_class = new ReportStyle;
$tot_class->backgroundColor(200,200,200);
}
$this->lev_fields[$name] = array("field_label"=>$label,
"field_name"=>$name,
"field_aggregate"=>$isAggregate,
"colspan"=>$colspan,
"colspan_label"=>$colspan_label,
"colspan_label_class"=>$colspan_label_class,
"lev_colspan_class_also"=>$lev_colspan_class_also,
"field_SQL_select"=>$SQL_select,
"field_SQL_criteria"=>$SQL_criteria,
"group_children_by"=>$group_children_by,
"visible"=>$visible,
"hide_duplicates"=>$hide_dups,
"field_width"=>$width,
"field_format"=>$format,
"field_class"=>$class,
"lev_class_also" =>$lev_class_also,
"field_label_class"=>$label_class,
"lev_label_class_also"=>$lev_label_class_also,
"field_condition"=>$condition,
"field_cond_class"=>$cond_class,
"has_tot"=>$has_tot,
"tot_label"=>$tot_label,
"field_tot_format"=>$tot_format,
"field_tot_class"=>$tot_class,
"lev_tot_class_also"=>$lev_tot_class_also,
"is_link"=>$is_link,
"link_text_start"=>$link_text_start,
"link_text_end"=>$link_text_end,
"link_title_start"=>$link_title_start,
"link_title_end"=>$link_title_end,
"link_href_start"=>$link_href_start,
"link_href_end"=>$link_href_end
);
}
function display ($grouping_criteria = Null, $grouping_aggregate = Null, &$formatter)
{
$this->formatter =& $formatter;
$this->formatter->setLevel($this);
$this->grouping_criteria = $grouping_criteria;
$this->grouping_aggregate = $grouping_aggregate;
#echo "Freshly received grouping criteria: " . print_r($this->grouping_criteria); //check
$this->group_level = false;
if (count($this->lev_items) > 0) {
$this->group_level = true;
}
$SQL_criteria = '';
if ($this->lev_setting['SQL_criteria'] != '') {
$SQL_criteria = $this->addToFilter($SQL_criteria,
$this->lev_setting['SQL_criteria']);
}
if (count($this->grouping_criteria) > 0) {
foreach ($this->grouping_criteria as $key => $value) {
$SQL_criteria = $this->addToFilter($SQL_criteria,
"$key = $value",
$this->grouping_aggregate[$key]
);
}
}
//echo "<br>The row filter clause is: " . $SQL_criteria , "<br>"; //check
// 2-2) put select, where, and order clauses together
$this->SQL_filtered = $this->shuffleSQL($this->lev_setting["SQL_select"].$SQL_criteria." ".$this->lev_setting["SQL_order"]);
if(defined('REPORT_DEBUG'))
echo "<br>The SQL_filtered is: " . $this->SQL_filtered . "<br>"; //check
$db =& DB();
$result = $db->Execute($this->SQL_filtered);
if(!$result) {
echo "SQL: {$this->SQL_filtered}<br>".$db->ErrorMsg();
exit;
}
$num_rows = $result->RecordCount();
if ($num_rows == 0) {
return;
}
$this->indent_html = $this->setIndent($this->lev_setting['indent']);
// 3-3) insert level title if needed
$this->has_title = False;
if ($this->lev_setting["title"] != '') {
$this->has_title = true;
}
$heading = '';
if ($this->has_title === true) {
if(is_a($this->formatter,'HTML_ReportFormatter')) {
$this->formatter->setIndent($this->indent_html);
$heading = '<div id="title">'.$this->lev_setting["title"].'</div>';
} else {
$this->formatter->setIndent($this->indent_html);
$this->formatter->addTable($this->lev_setting["title_table_class_html"]);
$this->formatter->addRow();
$this->formatter->addColumn($this->lev_setting["title"],
$this->lev_setting["title_class_html"]
);
$this->formatter->endRow();
$this->formatter->endTable();
}
}
//if a final row, use header-style labels
if ($this->group_level === false) {
$this->formatter->setIndent($this->indent_html);
$this->addHeaderLabels($heading);
}
/*set these up once before rows begin (needed for hide_duplicates)*/
foreach ($this->lev_fields as $field) {
$content[$field['field_name']] = ''; //seed/reset
$last_content[$field['field_name']] = ''; //seed/reset
//each of these is an array with an item for each field value in the row
}
// 4) DISPLAY EACH ROW >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
while (!$result->EOF) {
$row = $result->fields;
$result->MoveNext();
// 4-1) display each visible field (from supplied field argument) within row
//if level is group level (no header row) need to start table and body (one for each level)
if ($this->group_level === true) {
if(strlen($this->lev_setting['class']))
$this->formatter->write('<div id="'.$this->lev_setting["class"].'">');
$this->formatter->setIndent($this->indent_html);
$this->formatter->addTable($this->lev_setting["lev_table_class_html"],$heading);
}
$this->formatter->addRow();
foreach ($this->lev_fields as $field) {
// 4-1-0) only display field if visible
if ($field['visible'] === false) {
continue; //skip this field
}
// 4-1-1) set up class(es)
//only make label classes html if a group level
if ($this->group_level === true) {
/*must create class html here - it is a combination of level and
field class settings */
$field_label_class_html = $this->classHtml($field["field_label_class"],
$this->lev_setting["lev_label_class"],
$field["lev_class_also"]);
}
/*if a conditional class, see if condition met. If it is, use field_conditional class
instead of standard field class*/
$condition_met = false; //initialise
if ($field['field_condition'] != '') {
//get condition
$condition_met = $this->makeCondition($field['field_condition'],
$row, $this->lev_fields
);
}
if ($condition_met === true) {
$field_class = $field['field_cond_class'];
} else {
$field_class =$field['field_class'];
}
$field_class_html = $this->classHtml($field_class,
$this->lev_setting['lev_field_class'],
$field['lev_class_also']);
$field_width_html = $this->setWidth ($field["field_width"], $this->lev_setting["lev_field_width"]);
if ($field["field_SQL_select"] != '') { //if this field has its own data source ...
/* 5-1-3-1) set up WHERE/HAVING clause using both parent-derived criteria
(if the level above is team='CommunityCare' then this record source needs to be filtered to
only include data for the CommunityCare team*/
$field_SQL_criteria = "";
if ($field["field_SQL_criteria"] != "") {
$field_SQL_criteria = $this->addToFilter($field_SQL_criteria,
$field["field_SQL_criteria"]);
}
/*
if (count($this->grouping_criteria) > 0) {
foreach ($this->grouping_criteria as $key => $value) {
$field_SQL_criteria = $this->addToFilter($field_SQL_criteria, "$key = $value");
}
}
*/
if($field["field_name"]!="") {
$dba = DB();
$field_SQL_criteria = $this->addToFilter($field_SQL_criteria, $field["field_name"]." = ".$dba->qstr($row[$field["field_name"]]));
}
//echo "<br>The field filter clause is: " . $field_SQL_criteria , "<br>"; //check
/* 4-1-3-2) put select, where (but not order - not applicable -
order derived from other fields) parts of SQL statement together*/
$field_SQL_filtered = $this->shuffleSQL($field["field_SQL_select"] . $field_SQL_criteria);
#echo "<br>The field_SQL_filtered is: " . $field_SQL_filtered . "<br>"; //check
// 4-1-3-3) get the content according to the SQL statement
$db = DB();
$rs = $db->Execute($field_SQL_filtered);
if($rs && $rs->RecordCount()) {
$content[$field["field_name"]] = $rs->fields[0];
}
} else { //take content from field
$content[$field["field_name"]] = $row[$field["field_name"]];
}
/*if a final level, hide_duplicates = True, and it is a duplicate,
make $field_content = "" and skip to display*/
$duplicate = false; //seed/reset
if ($last_content[$field["field_name"]] == $content[$field["field_name"]]) {
$duplicate = true;
}
//set last content for next comparison (if any)
$last_content[$field["field_name"]] = $content[$field["field_name"]];
if ($this->group_level === false
AND $duplicate === true
AND $field["hide_duplicates"] === true) {
$field_content = "";
//skipping formatting and linking
} else {
// 4-1-5) set up formatting e.g. decimal places
$style = $this->getStyle($field["field_format"]);
$dp = $this->getDp($field["field_format"]);
$date_format = $this->getDateFormat($field["field_format"]);
//echo "<br>Field content before formatting is: " . $content[$field["field_name"]];
//echo "<br>Field array contains: " . print_r($field) . "<br>"; //check
$field_content = $this->myFormat($content[$field["field_name"]],
$style, $dp, $date_format);
// 4-1-6) put in link if required
if ($field["is_link"] === true) {
$field_content = "<a href=\"" . $field["link_href_start"] . rawurlencode($field_content) . $field["link_href_end"] . "\" " .
"title=\"" . $field["link_title_start"] . $field_content . $field["link_title_end"] . "\">" .
$field["link_text_start"] . $field_content . $field["link_text_end"] .
"</a>";
}
}
// 4-1-7) display field
if ($this->group_level === true) {
$this->formatter->addColumn($field["field_label"], $field_label_class_html);
$this->formatter->addColumn($field_content, $field_class_html);
} else {
$this->formatter->addColumn($field_content, $field_class_html);
}
}
$this->formatter->endRow();
$this->add_headers = 0;
if ($this->group_level === true) { //a separate table for each group by level
$this->formatter->endTable();
}
//5-1) add additional grouping criteria to $grouping_criteria
//loop through all fields in level - add to grouping_criteria filter if new_group_by is True
foreach ($this->lev_fields as $field) {
if ($field["group_children_by"] != true) { //only process this field if adding to filter
continue;
}
$key = "`" . $field["field_name"] . "`";
$value = $row[$field["field_name"]];
if (strpos($field["field_format"],"num") === false) {
$value = $db->qstr($value);
}
$this->grouping_criteria[$key] = $value;
$this->grouping_aggregate[$key] = $field['field_aggregate'];
}
//echo "<br>The grouping_criteria are now set to: " . print_r($this->grouping_criteria) . "<br>"; //check */
if ($this->group_level === true) {
$this->intersperse($this->grouping_criteria,$this->grouping_aggregate);
if(strlen($this->lev_setting["class"]))
$this->formatter->write('</div>');
}
}
// 6 DISPLAY TOTALS (only if a final level and only if one required)
/*any fields which have 'have_tot' equal True? Loop through them, and build array of field names.
If the array has any values, proceed (and pass on array to provide headstart building source query*/
if ($this->group_level === false) {
$this->addTotal($db);
$this->formatter->endTable();
}
}
function addHeaderLabels ($heading)
{
if($this->add_headers>0) return;
$this->add_headers++;
$this->formatter->addTable($this->lev_setting["lev_table_class_html"], $heading);
$this->formatter->addRow();
foreach ($this->lev_fields as $field) {
// only display field if visible
if ($field['visible'] === False) {
continue; //skip this field
}
$field_label_class_html = $this->classHtml($field["field_label_class"],
$this->lev_setting["lev_label_class"],
$field["lev_label_class_also"]);
$field_width_html = $this->setWidth ($field["field_width"], $this->lev_setting["lev_field_width"]);
// c) display
$this->formatter->addColumn($field["field_label"], $field_label_class_html);
}
$this->formatter->endRow();
}
function addTotal (&$db)
{
// 0 ) check to see if totals are required for any of the fields >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// (and build SQL select statement for totals row)
$SQL_select_tot = '';
foreach ($this->lev_fields as $field) {
if ($field['has_tot'] === True) {
if ($SQL_select_tot == '') {
$SQL_select_tot =
"SELECT Sum(" . $field["field_name"] . ") AS `Tot_" . $field["field_name"] . "`" ;
} else {
$SQL_select_tot .=
", Sum(" . $field["field_name"] . ") AS `Tot_" . $field["field_name"] . "`";
}
}
}
if ($SQL_select_tot == '') {
return false;
}
$group_by = "";
if (count($this->grouping_criteria) > 0) {
$group_by = "GROUP BY ";
foreach ($this->grouping_criteria as $key=>$value) {
$group_by .= (($group_by === "GROUP BY ") ? $key : ", " . $key);
}
}
//echo "<br>Group by is now: " .$group_by;
$SQL_tot_filtered = $this->shuffleSQL("$SQL_select_tot FROM (" . $this->SQL_filtered .
") AS Source "); #$group_by"; //each key in grouping criteria
# echo "<br>The SQL tot filtered is: " . $SQL_tot_filtered . "<br>";
$result1 = $db->Execute($SQL_tot_filtered);
while (!$result1->EOF) {
$row = $result1->fields;
$result1->MoveNext();
$this->formatter->addRow();
foreach ($this->lev_fields as $field) {
if ($field["visible"] === False) {
continue;
}
//must create class html here - it is a combination of field and level class settings
$field_tot_class_html = $this->classHtml($field["field_tot_class"],
$this->lev_setting["lev_tot_class"],
$field["lev_tot_class_also"]);
$field_width_html = $this->setWidth ($field["field_width"], $this->lev_setting["lev_field_width"]);
if ($field["has_tot"] === True) {
// 6-2-1-1) set up field content (whether a value or a format)
if ($field["tot_label"] != "") {
// 6-2-1-1-1) set up label
$field_content = $field["tot_label"];
} else {
// 6-2-1-1-2) set up formatting e.g. decimal places (only run when a cell to display)
$field_tot = "Tot_" . $field["field_name"];
$field_content = $this->myFormat($row["$field_tot"],
$this->getStyle($field["field_tot_format"]),
$this->getDp($field["field_tot_format"]),
$this->getDateFormat($field["field_format"]));
}
// 6-2-1-2) display row
$this->formatter->addColumn($field_content, $field_tot_class_html);
} else {
// 6-2-2) display row
$this->formatter->addColumn(" ", $field_tot_class_html);
}
}
$this->formatter->endRow();
}
return true; //i.e. had totals
}
}
/**
* This is the base Level class, any and all types of rendered chunks MUST inherit from this.
*/
class Level_Base {
/**
* Add a user criteria to the WHERE clause
*/
function addFieldCriteria($sql, $bIsAggregate = false, $field = '')
{
$this->lev_setting['SQL_criteria'] =
$this->addToFilter($this->lev_setting['SQL_criteria'],
$sql, $bIsAggregate);
if(strlen($this->lev_setting['SQL_order'])>0) {
$sql = $this->lev_setting['SQL_order'];
if( ($p=stripos($sql,'GROUP BY')) !== false) {
if( ($t=$this->find_next_sql_keyword($sql,$p+1)) !== false) {
$groupby = substr($sql,$p,$t[1]-$p);
if(stripos($groupby,$field)===false)
$sql = str_replace($groupby,$groupby.", {$field}",$sql);
}
}
$this->lev_setting['SQL_order'] = $sql;
} else {
$this->lev_setting['SQL_order'] = "GROUP BY ".$field;
}
if(isset($this->dataset)) {
for($i=0;$i<count($this->dataset);$i++) {
if(strlen($this->dataset[$i]['SQL_order'])>0) {
$sql = $this->dataset[$i]['SQL_order'];
if( ($p=stripos($sql,'GROUP BY')) !== false) {
if( ($t=$this->find_next_sql_keyword($sql,$p+1)) !== false) {
$groupby = substr($sql,$p,$t[1]-$p);
if(stripos($groupby,$field)===false)
$sql = str_replace($groupby,$groupby.", {$field}",$sql);
}
}
$this->dataset[$i]['SQL_order'] = $sql;
} else {
$this->dataset[$i]['SQL_order'] = "GROUP BY ".$field;
}
}
}
}
/**
* Add a sub-object to render beneath the current object
*/
function append (&$item)
{
$this->lev_items[] =& $item;
}
function addBreak ()
{
$this->lev_items[] = new Report_BreakAdaptor;
}
function addDiv($id)
{
$item = new Report_BreakAdaptor;
$item->id = $id;
$this->lev_items[] =& $item;
}
/**
* This calls all sub-objects of the current object to tell them to build their output
*/
function intersperse ($grouping_criteria, $grouping_aggregate)
{
if(isset($this->lev_items) && is_array($this->lev_items)) {
foreach ($this->lev_items as $item) {
#if(strlen($this->lev_setting['class']))
# $this->formatter->write('<div id="'.$this->lev_setting["class"].'">');
$c = $this->formatter->indent;
$item->display($grouping_criteria, $grouping_aggregate, $this->formatter);
$this->formatter->indent = $c;
#if(strlen($this->lev_setting["class"]))
# $this->formatter->write('</div>');
}
}
}
/**
* Build onto the SQL WHERE/HAVING clause
*/
function addToFilter ($full_criteria, $new_criterion, $aggregate = false)
{
/*
echo "<BR>";
echo "full_criteria = ".$full_criteria."<br>";
echo "new_criterion = ".$new_criterion."<br>";
echo "aggregate = ".$aggregate."<br>";
*/
$new_criterion = str_replace(" "," ",$new_criterion);
$new_criterion = str_replace("WHERE HAVING","HAVING",$new_criterion);
$t = "WHERE";
if($aggregate) {
$t = "HAVING";
}
if ($full_criteria == "") {
if(strpos($new_criterion,$t)!==false)
return $new_criterion;
else
return " $t " . $new_criterion;
break;
}
#echo "t:".$t."<br>fc:".$full_criteria."<br>nc:".$new_criterion."<BR>";
if (strpos($full_criteria, $t) === False && strpos($new_criterion, $t)===false) {
if($t == "WHERE") {
$r = " WHERE ".$full_criteria;
if(strlen($new_criterion))
$r .= " AND ".$new_criterion;
return $r;
} else {
return $full_criteria." $t " . $new_criterion;
}
} else if(strpos($full_criteria, $t)!==false && strpos($new_criterion, $t) !== false) {
$sql = $full_criteria . " AND " . substr($new_criterion, strpos($new_criterion,$t)+strlen($t));
$sql = str_replace("AND HAVING","HAVING",$sql);
#echo 'OUTPUT:'.$sql."<br>";
return $sql;
} else {
#echo "fc1:".$full_criteria."<br>nc:".$new_criterion."<BR>";
if(strncasecmp(trim($new_criterion),"having",6)==0)
return $full_criteria . ' '. $new_criterion;
else
return $full_criteria . " AND " . $new_criterion;
}
}
function find_next_sql_keyword($sql,$offset=0)
{
$ret = false;
if(is_string($sql) && is_numeric($offset)) {
$arr = array(
'WHERE',
'GROUP BY',
'ORDER BY',
'LIMIT',
'HAVING'
);
$bFound = false;
foreach($arr as $k) {
if( ($t=stripos($sql,$k,$offset)) !== false) {
if($ret === false) {
$ret = array($k,$t);
$bFound = true;
}
}
}
if($bFound == false) {
$ret = array('',strlen($sql));
}
}
return $ret;
}
function shuffleSQL($sql, $groupBy='')
{
if( ($p=stripos($sql,'HAVING')) !== false) {
# found a having clause
$leading = '';
$having = '';
$groupby = '';
$orderby = '';
$limit = '';
if( ($t=$this->find_next_sql_keyword($sql,$p+1)) !== false) {
$having = substr($sql,$p,$t[1]-$p);
$sql = str_replace($having,'',$sql);
}
if( ($p=stripos($sql,'GROUP BY')) !== false) {
if( ($t=$this->find_next_sql_keyword($sql,$p+1)) !== false) {
$groupby = substr($sql,$p,$t[1]-$p).$groupBy;
$sql = str_replace($groupby,'',$sql);
}
}
if( ($p=stripos($sql,'ORDER BY')) !== false) {
if( ($t=$this->find_next_sql_keyword($sql,$p+1)) !== false) {
$orderby = substr($sql,$p,$t[1]-$p);
$sql = str_replace($orderby,'',$sql);
}
}
if( ($p=stripos($sql,'LIMIT')) !== false) {
if( ($t=$this->find_next_sql_keyword($sql,$p+1)) !== false) {
$limit = substr($sql,$p,$t[1]-$p);
$sql = str_replace($limit,'',$sql);
}
}
#echo "having=$having<br>groupby=$groupby<br>orderby=$orderby<br>limit=$limit<br>";
$sql .= $groupby.' '.$having.' '.$orderby.' '.$limit;
}
return $sql;
}
function makeCondition ($condition, $row, $fields)
{
//replace bracketed text with data from field in row with same name
//numeric data does not need to be unquoted as long as == is used instead of ===
//date data must be wrapped in strtotime on both sides of comparison to work (NB Unix time 1970 onwards only)
//replace brackets with PHP code then use eval to run generated string as PHP code
$condition = str_replace('[','$row[\'',$condition);
$condition = str_replace(']','\']',$condition);
$condition = "if($condition){\$condition_met=True;}else{\$condition_met=False;}";
//echo "<br>Test expression as generated: $condition";//check
eval($condition);
return $condition_met;
}
function setIndent ($indent)
{
return $this->formatter->setIndent($indent);
}
function myFormat ($value, $style, $dp, $date_format)
{
switch ($style) {
case "upper":
return strtoupper($value);
break;
case "perc":
return sprintf("%01." . $dp . "f", $value) . "%";
break;
case "dol":
return "$" . number_format($value, $dp);
break;
case "num":
return number_format($value, $dp);;
break;
case "date":
if ($value != "") {
/*echo "Date format: " . $date_format . ";
Value: " . $value . "Date: " . date($date_format, strtotime($value)); //check*/
return date($date_format, $value);
} else {
return $value;
}
break;
default:
return $value;
break;
}
}
function getStyle ($format)
{
$field_format = explode(",", $format);
return $field_format[0];
}
function getDp ($format)
{
$field_format = explode(",", $format);
return (count($field_format) > 1 ? $field_format[1] : 0);
}
function getDateFormat ($format)
{
$field_format = explode(",", $format);
return (count($field_format) > 2 ? $field_format[2] : "m/d/Y");
}
function setWidth ($field_width, $level_field_width)
{
$width = (($field_width != "") ? $field_width : $level_field_width);
return (($width != "") ? " width='" . $width . "'" : "" );
}
/**
* This is worthless junk from the original author, should be refactored
*/
function classHtml ($field_class, $lev_class, $both = False)
{
if(is_a($field_class,'ReportStyle'))
return $field_class;
if(is_a($lev_class,'ReportStyle'))
return $lev_class;
if ($field_class == "" AND $lev_class == "") { //nothing to set
return "";
}
switch ($both) {
case true: //use both classes
return "$field_class $lev_class";
break;
case false: //only use on class (field takes precedence over level)
if ($field_class != '') {
return $field_class;
} else {
return $lev_class;
}
break;
}
}
}
?>