kenken999/php
0
1<?php2 3 4function create_reportfield($name, $type, $interval, $alias, $table, $connection, $cipherer)5{6 if( !$type )7 return;8 9 if( $type == 'char' )10 return new ReportCharField( $name, $interval, $alias, $table, $connection, $cipherer );11 12 if( $type == 'date' )13 return new ReportDateField( $name, $interval, $alias, $table, $connection, $cipherer );14 15 if( $type == 'numeric' )16 return new ReportNumericField( $name, $interval, $alias, $table, $connection, $cipherer );17 18 die('Unsupported group field type: `'.$type.'`');19}20 21class ReportField22{23 var $_interval = 0;24 var $_tName = '';25 var $_name = '';26 var $_alias = '';27 var $_sqlname = '';28 var $_start = 0;29 var $_caseSensitive = false;30 var $_recordBasedRequest = false;31 var $_rowsInSummary = 0;32 var $_rowsInHeader = 0;33 var $_viewFormat = '';34 var $_oldAlgorithm = false;35 // Instance of ProjectSettings36 var $pSet = null;37 38 var $cipherer = null;39 40 /**41 * @type Connection42 */43 var $_connection;44 45 function __construct($name, $interval, $alias, $table, $connection, $cipherer)46 {47 $this->_name = $name;48 $this->_interval = $interval;49 $this->_alias = $alias;50 $this->_sqlname = $alias;51 $this->_tName = $table;52 $this->_connection = $connection;53 $this->cipherer = $cipherer;54 if($table != '')55 $this->pSet = new ProjectSettings($table);56 }57 58 59 60 function getFieldName($fieldValue, $data = null, $pageObject = null ) { die; }61 62 63 function getGroup($data)64 {65 return $data[$this->alias()];66 }67 68 69 function getKey($data)70 {71 return $data[$this->alias()];72 }73 74 75 function setStart($start)76 {77 $this->_start = $start;78 $this->_sqlname = $this->alias();79 return $start + 1;80 }81 82 83 function name()84 {85 return $this->_name;86 }87 88 89 function alias()90 {91 return $this->_alias . $this->_start;92 }93 94 95 function overrideFormat()96 {97 return false;98 }99 100 function setCaseSensitive($cs)101 {102 $this->_caseSensitive = $cs;103 }104}105 106 107class ReportNumericField extends ReportField108{109 function __construct($name, $interval, $alias, $table, $connection, $cipherer)110 {111 parent::__construct($name, $interval, $alias, $table, $connection, $cipherer);112 }113 114 function getFieldName( $fieldValue, $data = null, $pageObject = null )115 {116 $value = $data[$this->_recordBasedRequest ? $this->_name : $this->_sqlname];117 if($value === null)118 return 'NULL';119 if($this->_interval > 0) {120 $start = DataSource::groupValueNumber( $value, $this->_interval );121 return $start . ' - ' . ( $start + $this->_interval - 1 );122 }123 else124 return $value;125 }126 127 function getKey($data)128 {129 if($this->_recordBasedRequest)130 {131 if($this->_interval > 0)132 return DataSource::groupValueNumber( $data[$this->_name], $this->_interval );133 else134 return $data[$this->_name];135 }136 else137 return ReportField::getKey($data);138 }139 140}141 142 143class ReportCharField extends ReportField144{145 function __construct($name, $interval, $alias, $table, $connection, $cipherer)146 {147 parent::__construct($name, $interval, $alias, $table, $connection, $cipherer);148 }149 150 function getFieldName($fieldValue, $data = null, $pageObject = null )151 {152 $value = $data[$this->_recordBasedRequest ? $this->_name : $this->_sqlname];153 if($value === null)154 return 'NULL';155 if($this->_interval > 0)156 return substr($value, 0, $this->_interval);157 else158 return $value;159 }160 161 function getKey($data)162 {163 if($this->_recordBasedRequest)164 {165 if($this->_interval > 0)166 {167 if($this->_caseSensitive)168 return substr($data[$this->_name], 0, $this->_interval);169 else170 return strtolower(substr($data[$this->_name], 0, $this->_interval));171 }172 else173 {174 if($this->_caseSensitive)175 return $data[$this->_name];176 else177 return strtolower($data[$this->_name]);178 }179 }180 else181 {182 if($this->_caseSensitive)183 return $data[$this->alias()];184 else185 return strtolower($data[$this->alias()]);186 }187 }188 189}190 191 192class ReportDateField extends ReportField193{194 function __construct($name, $interval, $alias, $table, $connection, $cipherer)195 {196 parent::__construct($name, $interval, $alias, $table, $connection, $cipherer);197 }198 199 function getFieldName($fieldValue, $data = null, $pageObject = null )200 {201 global $locale_info;202 203 $value = $data[ $this->_recordBasedRequest ? $this->_name : $this->_sqlname ];204 if($value == null || !$value || strcasecmp($value, 'null') == 0)205 return 'NULL';206 207 if($this->_interval == 0)208 {209 if($this->_viewFormat)210 {211 if( !$this->_recordBasedRequest )212 $data[ $this->_name ] = $value;213 214 return $pageObject->formatReportFieldValue($this->_name, $data);215 }216 else217 {218 $date = db2time($value);219 return str_format_datetime($date);220 }221 }222 return formatDateIntervalValue( $fieldValue, $this->_interval );223 224 }225 226 function getGroup($data)227 {228 if( $this->_interval == 0)229 return $data[$this->alias()];230 else231 {232 return DataSource::groupValueDate( $data[$this->alias()], $this->_interval );233 }234 }235 236 function getKey($data)237 {238 if(!$this->_recordBasedRequest)239 {240 return $data[$this->alias()];241 }242 else243 {244 return DataSource::groupValueDate( $data[ $this->_name ], $this->_interval );245 }246 }247 248 function overrideFormat()249 {250 return true;251 }252 253 254}255 256function getFormattedValue( $pageObject, $value, $fieldName, $strViewFormat, $total = '', $record = array() ) {257 if( $strViewFormat == FORMAT_TIME && is_numeric( $value ) ) {258 if( $total == 'AVG' )259 $value = round( $value, 0 );260 261 include_once getabspath('classes/controls/ViewTimeField.php');262 return ViewTimeField::getFormattedTotals(263 $fieldName,264 $value,265 $pageObject->pSet,266 $pageObject->pdfJsonMode(),267 $total == 'SUM'268 );269 }270 271 if( basicViewFormat( $strViewFormat ) ) {272 $arrValues = array( $fieldName => $value );273 } else {274 $arrValues = $record;275 $arrValues[ $fieldName ] = $value;276 }277 278 return $pageObject->formatReportFieldValue( $fieldName, $arrValues );279}280 281$cache_db2time = array();282function cached_db2time($strtime)283{284 global $cache_db2time;285 if(!isset($cache_db2time[$strtime]))286 {287 $res = db2time($strtime);288 $cache_db2time[$strtime] = $res;289 return $res;290 }291 else292 return $cache_db2time[$strtime];293}294 295$cache_getdayofweek = array();296function cached_getdayofweek($strtime)297{298 global $cache_getdayofweek;299 if(!isset($cache_getdayofweek[$strtime]))300 {301 $date = cached_db2time($strtime);302 $res = getdayofweek($date);303 $cache_getdayofweek[$strtime] = $res;304 return $res;305 }306 else307 return $cache_getdayofweek[$strtime];308}309 310$cache_getweekstart = array();311function cached_getweekstart($strtime)312{313 global $cache_getweekstart;314 if(!isset($cache_getweekstart[$strtime]))315 {316 $date = cached_db2time($strtime);317 $res = getweekstart($date);318 $cache_getweekstart[$strtime] = $res;319 return $res;320 }321 else322 return $cache_getweekstart[$strtime];323}324 325$cache_formatweekstart = array();326function cached_formatweekstart($strtime)327{328 global $cache_formatweekstart;329 if(!isset($cache_formatweekstart[$strtime]))330 {331 $start = cached_getweekstart($strtime);332 $end = adddays($start, 6);333 $res = format_shortdate($start)." - ".format_shortdate($end);334 $cache_formatweekstart[$strtime] = $res;335 return $res;336 }337 else338 return $cache_formatweekstart[$strtime];339}340 341///////////////////////////////////////////////////////////////////////////////////342class SQLStatement343{344 var $_fields = array();345 var $_hasDetails = true;346 var $_skipCount = 0;347 348 var $_reportGlobalSummary = true;349 350 var $_reportSummary = true;351 var $_details = true;352 var $_from = 0;353 354 /*355 * Total number elements (groups or records) to show356 * 0 - show all357 */358 var $_groupsTotal;359 360 361 var $_limitLevel = 0;362 var $_hasGroups = true;363 var $_recordBasedRequest = false;364 var $_oldAlgorithm = false;365 366 367 // report table info368 var $tName = '';369 var $shortTName = '';370 371 /*372 * number of group fields373 * @type int374 */375 var $repGroupFieldsCount = 0;376 377 var $repPageSummary = 0;378 var $repGlobalSummary = 0;379 var $repLayout = 0;380 var $showGroupSummaryCount = 0;381 var $repShowDet = 0;382 // report field info383 var $repGroupFields = array();384 // current table key fields385 var $tKeyFields = array();386 // if any field used for totals387 var $isExistTotalFields = false;388 // table fields list389 var $fieldsArr = array();390 // Order by fields info391 var $orderIndexes;392 // Instance of ProjectSettings393 var $pSet = null;394 395 /**396 * @type Connection397 */398 var $_connection;399 400 var $_cipherer;401 var $pageObject;402 403 404 405 function __construct($sql, $order, $groupsTotal, $connection, &$params, $cipherer, $pageObject )406 {407 // copy properties to object408 RunnerApply($this, $params);409 $this->_connection = $connection;410 $this->_cipherer = $cipherer;411 $this->pSet = new ProjectSettings($this->tName, PAGE_REPORT);412 $this->pageObject = $pageObject;413 if(!is_array($sql))414 die ('Invalid sql parameter');415 416 global $reportCaseSensitiveGroupFields;417 418 $start = 0;419 420 $fields = array();421 422 for($i=0; $i<count($this->repGroupFields); $i++)423 {424 for($j=0; $j<count($this->fieldsArr); $j++)425 {426 if ($this->repGroupFields[$i]['strGroupField'] == $this->fieldsArr[$j]['name'])427 {428 $add = array();429 $add['name'] = $this->fieldsArr[$j]['name'];430 if (IsNumberType($this->pSet->getFieldType($this->fieldsArr[$j]['name'])))431 {432 $add['type'] = 'numeric';433 }elseif (IsCharType($this->pSet->getFieldType($this->fieldsArr[$j]['name']))){434 $add['type'] = 'char';435 $add['case_sensitive'] = $reportCaseSensitiveGroupFields;436 }elseif (IsDateFieldType($this->pSet->getFieldType($this->fieldsArr[$j]['name']))){437 $add['type'] = 'date';438 }else{439 $add['type'] = 'char';440 }441 $add['interval'] = $this->repGroupFields[$i]['groupInterval'];442 $add['viewformat'] = $this->fieldsArr[$j]['viewFormat'];443 444 $add['rowsinsummary'] = 1;445 446 447 if ($this->fieldsArr[$j]['totalMax'] || $this->fieldsArr[$j]['totalMin'] || $this->fieldsArr[$j]['totalAvg'] || $this->fieldsArr[$j]['totalSum'])448 {449 $add['rowsinsummary'] ++;450 }451 452 453 if ($this->repLayout == REPORT_STEPPED)454 {455 $add['rowsinheader'] = 1;456 }elseif ($this->repLayout == REPORT_BLOCK){457 $add['rowsinheader'] = 0;458 }elseif ($this->repLayout == REPORT_OUTLINE || $this->repLayout == REPORT_ALIGN){459 if ($j == count($this->fieldsArr)-1)460 {461 $add['rowsinheader'] = 2;462 }else{463 $add['rowsinheader'] = 1;464 }465 }elseif ($this->repLayout == REPORT_TABULAR){466 $add['rowsinheader'] = 0;467 }468 469 $fields []= $add;470 }471 }472 }473 474 $this->_hasGroups = count($fields) > 0;475 476 foreach($fields as $field)477 {478 $f = create_reportfield($field['name'], $field['type'], $field['interval'], 'grp', $this->tName, $this->_connection, $this->_cipherer);479 $start = $f->setStart($start);480 if(isset($field['case_sensitive']))481 $f->setCaseSensitive($field['case_sensitive']);482 if(isset($field['rowsinsummary']))483 $f->_rowsInSummary = $field['rowsinsummary'];484 if(isset($field['rowsinheader']))485 $f->_rowsInHeader = $field['rowsinheader'];486 $f->_viewFormat = $field['viewformat'];487 $this->_fields []= $f;488 }489 490 491 $this->_reportSummary = $this->repPageSummary || $this->repGlobalSummary;492 $this->_groupsTotal = $groupsTotal;493 }494 495 function setRecordBasedRequest($recordBasedRequest)496 {497 $this->_recordBasedRequest = $recordBasedRequest;498 for($nCnt = 0; $nCnt < count($this->_fields); $nCnt++)499 $this->_fields[$nCnt]->_recordBasedRequest = $recordBasedRequest;500 }501 502 function getGroup($data)503 {504 return $this->_fields[0]->getGroup($data);505 }506 507 function field($num)508 {509 return $this->_fields[$num];510 }511 512 function setOldAlgorithm($useOldAlgorithm = true)513 {514 for($nCnt = 0; $nCnt < count($this->_fields); $nCnt ++)515 {516 $this->_fields[$nCnt]->_oldAlgorithm = $useOldAlgorithm;517 }518 519 $this->_oldAlgorithm = $useOldAlgorithm;520 }521}522 523////////////////////////////////////////////////////////////////////////////////////////524class Summarable525{526 /* Array of all values used building report totals527 * Elements:528 * summary - array529 <field name> - array of values involved in totals calculating530 count531 MIN532 MAX533 AVG534 SUM535 _first - array of field values from the database536 _begin - row?537 _end - row?538 values - array where keys are group keys539 <group key value> - another underlying summary540 541 */542 var $_summary = array();543 544 // report table info545 var $tName = '';546 var $shortTName = '';547 548 /*549 * number of group fields550 * @type int551 */552 var $repGroupFieldsCount = 0;553 var $repPageSummary = 0;554 var $repGlobalSummary = 0;555 var $repLayout = 0;556 var $showGroupSummaryCount = 0;557 var $repShowDet = 0;558 // report field info559 var $repGroupFields = array();560 // current table key fields561 var $tKeyFields = array();562 // if any field used for totals563 var $isExistTotalFields = false;564 // table fields list565 var $fieldsArr = array();566 567 var $cipherer = null;568 var $_from;569 570 571 function __construct(&$params)572 {573 RunnerApply($this, $params);574 Summarable::init();575 }576 577 function init($from = 0)578 {579 $this->_from = $from;580 $this->cipherer = new RunnerCipherer($this->tName);581 }582 583 function writeGroup(&$begin, &$end, $gkey, $grp, $nField, $values ) {}584 585 /*586 * Update summary totals with the new fetched record data587 *588 * $recordsMode - true if report is being built from raw SQL query and false if the query is grouped589 * $summary - a summary to update590 * $data - record fetched from the database591 * $nTotalRecords - global records counter592 */593 function addSummary($recordsMode, &$summary, $data, &$nTotalRecords)594 {595 $countInGroup = isset($summary['count']) ? $summary['count'] : 0;596 if ($this->isExistTotalFields)597 {598 if(!is_array($summary['summary']))599 $summary['summary']=array();600 $s =& $summary['summary'];601 }602 if($recordsMode)603 {604 // report is built from raw query results605 for($i=0; $i<count($this->fieldsArr); $i++)606 {607 $field = &$this->fieldsArr[$i];608 $fieldName = $field['name'];609 if (!$field['totalMax'] && !$field['totalMin'] && !$field['totalAvg'] && !$field['totalSum'])610 {611 // no summary to calculate612 continue;613 }614 if($data[$fieldName] === null)615 continue;616 617 if(!is_array($s[$fieldName]))618 $s[$fieldName] = array();619 620 if(!isset($s[$fieldName]['count']))621 $s[$fieldName]['count'] = 0;622 623 if ($field['totalMax'])624 {625 if(!isset($s[$fieldName]['MAX']) || $s[$fieldName]['MAX'] < $data[$fieldName])626 $s[$fieldName]['MAX'] = $data[$fieldName];627 }628 if ($field['totalMin']){629 if(!isset($s[$fieldName]['MIN']) || $s[$fieldName]['MIN'] > $data[$fieldName])630 $s[$fieldName]['MIN'] = $data[$fieldName];631 }632 if ($field['totalAvg']){633 if ($field['viewFormat'] == "Time")634 {635 $avg_value = $this->value2time($data[$fieldName]);636 }else{637 $avg_value = $data[$fieldName];638 }639 $s[$fieldName]['AVG'] = $s[$fieldName]['AVG']*$s[$fieldName]['count'] + $avg_value;640 $s[$fieldName]['count'] ++;641 if($s[$fieldName]['count']!=0)642 $s[$fieldName]['AVG'] = $s[$fieldName]['AVG']/$s[$fieldName]['count'];643 }644 if ($field['totalSum']){645 if ($field['viewFormat'] == "Time")646 {647 $s[$fieldName]['SUM'] += $this->value2time($data[$fieldName]);648 }else{649 $s[$fieldName]['SUM'] += $data[$fieldName];650 }651 }652 }653 $nTotalRecords ++;654 $countInGroup ++;655 }656 else657 {658 // report is built from grouped query results659 for($i=0; $i<count($this->fieldsArr); $i++)660 {661 $field = &$this->fieldsArr[$i];662 if ( !$field['totalMax'] && !$field['totalMin'] && !$field['totalAvg'] && !$field['totalSum'] )663 {664 // no summary to calculate665 continue;666 }667 $fieldName = $field['name'];668 if( !is_array( $s[$fieldName] ))669 $s[ $fieldName ] = array();670 $summaryField =& $s[$fieldName];671 672 673 if ($field['totalMax'])674 {675 if($data[$fieldName."MAX"] !== null)676 {677 if(!isset($summaryField['MAX']) || $summaryField['MAX'] < $data[$fieldName."MAX"])678 $summaryField['MAX'] = $data[$fieldName."MAX"];679 }680 }681 if ($field['totalMin']){682 if($data[$fieldName."MIN"] !== null)683 {684 if(!isset($summaryField['MIN']) || $summaryField['MIN'] > $data[$fieldName."MIN"])685 $summaryField['MIN'] = $data[$fieldName."MIN"];686 }687 }688 if ($field['totalAvg']){689 if($data[$fieldName."AVG"] !== null)690 {691 if ($field['viewFormat'] == "Time")692 {693 $avg_value = $this->value2time($data[$fieldName."AVG"]);694 }else{695 $avg_value = $data[$fieldName."AVG"];696 }697 $summaryField['AVG'] = $summaryField['AVG']*$summaryField['count'] + $avg_value*$data[$fieldName."NAVG"];698 $summaryField['count'] += $data[$fieldName."NAVG"];699 if($summaryField['count']!=0)700 $summaryField['AVG'] = $summaryField['AVG']/$summaryField['count'];701 }702 }703 if ($field['totalSum']){704 if($data[$fieldName."SUM"] !== null)705 {706 if ($field['viewFormat'] == "Time")707 {708 $summaryField['SUM'] += $this->value2time($data[$fieldName."SUM"]);709 }else{710 $summaryField['SUM'] += $data[$fieldName."SUM"];711 }712 }713 }714 }715 $nTotalRecords += $data['countField'];716 $countInGroup += $data['countField'];717 }718 $summary['count'] = $countInGroup;719 }720 721 function _makeSummary(&$summary, $deep)722 {723 if( !$summary['values'] )724 return;725 726 foreach($summary['values'] as $gkey => $group)727 {728 $grp =& $summary['values'][$gkey];729 if(isset($grp['values']))730 $this->_makeSummary($grp, $deep + 1);731 732 if(isset($grp['_begin']) && isset($grp['_end']))733 $this->writeGroup($grp['_begin'], $grp['_end'], $gkey, $grp, $deep, $grp['_first'] );734 735 if(!is_array($summary['summary']))736 $summary['summary']=array();737 for($i=0; $i<count($this->fieldsArr); $i++)738 {739 if(!is_array($summary['summary'][$this->fieldsArr[$i]['name']]))740 $summary['summary'][$this->fieldsArr[$i]['name']]=array();741 if(is_array($grp['summary']))742 {743 if(is_array($grp['summary'][$this->fieldsArr[$i]['name']]))744 {745 if ($this->fieldsArr[$i]['totalMax'])746 {747 if(isset($grp['summary'][$this->fieldsArr[$i]['name']]['MAX']))748 {749 if(!isset($summary['summary'][$this->fieldsArr[$i]['name']]['MAX']) || $summary['summary'][$this->fieldsArr[$i]['name']]['MAX'] < $grp['summary'][$this->fieldsArr[$i]['name']]['MAX'])750 $summary['summary'][$this->fieldsArr[$i]['name']]['MAX'] = $grp['summary'][$this->fieldsArr[$i]['name']]['MAX'];751 }752 }753 if ($this->fieldsArr[$i]['totalMin']){754 if(isset($grp['summary'][$this->fieldsArr[$i]['name']]['MIN']))755 {756 if(!isset($summary['summary'][$this->fieldsArr[$i]['name']]['MIN']) || $summary['summary'][$this->fieldsArr[$i]['name']]['MIN'] > $grp['summary'][$this->fieldsArr[$i]['name']]['MIN'])757 $summary['summary'][$this->fieldsArr[$i]['name']]['MIN'] = $grp['summary'][$this->fieldsArr[$i]['name']]['MIN'];758 }759 }760 if ($this->fieldsArr[$i]['totalAvg']){761 if(isset($grp['summary'][$this->fieldsArr[$i]['name']]['AVG']))762 {763 $summary['summary'][$this->fieldsArr[$i]['name']]['AVG'] =764 $summary['summary'][$this->fieldsArr[$i]['name']]['AVG']*$summary['summary'][$this->fieldsArr[$i]['name']]['count'] +765 $grp['summary'][$this->fieldsArr[$i]['name']]['AVG']*$grp['summary'][$this->fieldsArr[$i]['name']]['count'];766 $summary['summary'][$this->fieldsArr[$i]['name']]['count'] += $grp['summary'][$this->fieldsArr[$i]['name']]['count'];767 if($summary['summary'][$this->fieldsArr[$i]['name']]['count']!=0)768 $summary['summary'][$this->fieldsArr[$i]['name']]['AVG'] = $summary['summary'][$this->fieldsArr[$i]['name']]['AVG']/$summary['summary'][$this->fieldsArr[$i]['name']]['count'];769 }770 }if ($this->fieldsArr[$i]['totalSum']){771 if($grp['summary'][$this->fieldsArr[$i]['name']]['SUM'])772 $summary['summary'][$this->fieldsArr[$i]['name']]['SUM'] += $grp['summary'][$this->fieldsArr[$i]['name']]['SUM'];773 }774 }775 }776 }777 778 $summary['count'] += $grp['count'];779 }780 }781 782 function value2time($value)783 {784 $res = 0;785 $arr = parsenumbers($value);786 if(isset($arr[0]))787 $res += $arr[0] * 60 * 60;788 if(isset($arr[1]))789 $res += $arr[1] * 60;790 if(isset($arr[2]))791 $res += $arr[2];792 return $res;793 }794 795 function time2printable($time)796 {797 return array(intval($time / (60 * 60)), intval($time / 60), $time % 60);798 }799}800 801class ReportGroups extends Summarable802{803 var $_report;804 var $_global;805 var $_totalRecords;806 var $_maxpages;807 var $_nGroup;808 var $_oldFirst;809 var $_sql;810 811 /*812 * Total number elements (groups or records) to show813 * 0 - show all814 * @type int815 */816 var $_groupsTotal;817 818 819 /**820 * @type Connection821 */822 var $_connection;823 var $_allGroupsUsed;824 var $_countGroups;825 826 // report table info827 var $tName = '';828 var $shortTName = '';829 830 /*831 * number of group fields832 * @type int833 */834 var $repGroupFieldsCount = 0;835 836 var $repPageSummary = 0;837 var $repGlobalSummary = 0;838 var $repLayout = 0;839 var $showGroupSummaryCount = 0;840 var $repShowDet = 0;841 // report field info842 var $repGroupFields = array();843 // current table key fields844 var $tKeyFields = array();845 // if any field used for totals846 var $isExistTotalFields = false;847 // table fields list848 var $fieldsArr = array();849 850 function __construct(&$sql, $connection, $groupsTotal, &$params, $report )851 {852 // copy properties to object853 parent::__construct($params);854 $this->init();855 $this->_groupsTotal = $groupsTotal;856 $this->_sql =& $sql;857 $this->_connection = $connection;858 $this->_report = $report;859 }860 861 function init($from = 0)862 {863 Summarable::init($from);864 $this->_global = array();865 $this->_totalRecords = 0;866 $this->_maxpages = -1;867 $this->_from = $from;868 $this->_nGroup = -1;869 $this->_oldFirst = '';870 $this->_allGroupsUsed = false;871 $this->_countGroups = 0;872 }873 874 function setGlobalSummary($recordsMode, $data)875 {876 $this->addSummary($recordsMode, $this->_global, $data, $this->_totalRecords);877 }878 879 function setGroup($data)880 {881 $field = $this->_sql->field(0);882 $firstKey = $field->getKey($data);883 if($firstKey !== $this->_oldFirst)884 {885 $this->_nGroup ++;886 $this->_oldFirst = $firstKey;887 }888 }889 890 function isVisibleGroup()891 {892 return $this->_nGroup >= $this->_from && $this->_nGroup < $this->_from + $this->_groupsTotal;893 }894 895 function getDisplayGroups($from)896 {897 $this->init($from);898 899 if( !$this->_groupsTotal )900 {901 // request 'All Groups'902 return array();903 }904 else905 {906 $groups = array();907 $this->_allGroupsUsed = false;908 909 if ($this->repGroupFieldsCount)910 {911 912 $dc = $this->_report->pageObject->getSubsetDataCommand();913 $dc->totals = array(914 array(915 "alias" => "grp0",916 "field" => $this->repGroupFields[0]["strGroupField"],917 "modifier" => $this->repGroupFields[0]["groupInterval"],918 "direction" => $this->_report->groupOrderDirection( 0 )919 )920 );921 $dc->startRecord = $this->_from;922 $dc->reccount = $this->_groupsTotal;923 $qResult = $this->_report->pageObject->getDataSource()->getTotals( $dc );924 925 926 while( ($data = $this->cipherer->DecryptFetchedArray( $qResult->fetchAssoc() )) && count($groups) < $this->_groupsTotal )927 {928 $groups[] = $data["grp0"];929 }930 if(count($groups) < $this->_groupsTotal)931 $this->_allGroupsUsed = true;932 }933 934 if($from > 0)935 {936 $this->_allGroupsUsed = false;937 }938 939 $this->_countGroups = count($groups);940 941 return $groups;942 }943 }944 945 function getCountGroups($fullRequest = false)946 {947 if ($this->repGroupFieldsCount)948 {949 if($this->_nGroup >= 0 && $fullRequest)950 {951 return $this->_nGroup + 1;952 }953 else954 {955 if($this->_allGroupsUsed)956 {957 return $this->_countGroups;958 }959 else960 {961 $dc = $this->_report->pageObject->getSubsetDataCommand();962 $dc->totals = array(963 array(964 "alias" => "grp0",965 "field" => $this->repGroupFields[0]["strGroupField"],966 "modifier" => $this->repGroupFields[0]["groupInterval"]967 )968 );969 return $this->_report->pageObject->getDataSource()->getTotalCount( $dc );970 }971 }972 }else{973 return 0;974 }975 }976 977 function getSummary()978 {979 return $this->_global;980 }981 982 function allGroupsUsed()983 {984 return $this->_allGroupsUsed;985 }986}987 988class ReportLogic extends Summarable989{990 var $_list;991 var $_totalRecords;992 var $_pages;993 /*994 * Total number elements (groups or records) to show995 * 0 - show all996 */997 var $_groupsTotal;998 999 /*1000 * Number elements (groups or records) to be displayed per page.1001 * 0 - don't paginate1002 */1003 var $_groupsPerPage;1004 1005 var $_groupCounter = 0;1006 1007 var $_from = 0;1008 1009 /**1010 * @type Connection1011 */1012 var $_connection;1013 var $_sql;1014 var $_groups;1015 1016 /*1017 * An 0-based array containing a single element for each group field.1018 * The element for each group is the group key - field value in simplest case.1019 * The array is used when report is built from the raw data1020 */1021 var $_groupKeys;1022 1023 var $_fullRequest = false;1024 var $_recordBasedRequest = false;1025 var $_doPaging = false;1026 var $_lastPageNumber = 0;1027 var $_pageSummary;1028 var $_printRecordCount = 0;1029 var $_listedRows = 0;1030 var $_oldLevels;1031 1032 1033 // report table info1034 var $tName = '';1035 var $shortTName = '';1036 1037 /*1038 * number of group fields1039 * @type int1040 */1041 var $repGroupFieldsCount = 0;1042 1043 var $repPageSummary = 0;1044 var $repGlobalSummary = 0;1045 var $repLayout = 0;1046 var $showGroupSummaryCount = 0;1047 var $repShowDet = 0;1048 // report field info1049 var $repGroupFields = array();1050 // current table key fields1051 var $tKeyFields = array();1052 // if any field used for totals1053 var $isExistTotalFields = false;1054 // table fields list1055 var $fieldsArr = array();1056 1057 var $cipherer = null;1058 1059 /**1060 * Instance of RunnerPage or ViewControlsContainer1061 * @var {object}1062 */1063 var $pageObject = null;1064 var $pSet = null;1065 1066 function __construct( $order, $connection, $groupsTotal, $groupsPerPage, &$params, $pageObject = null )1067 {1068 parent::__construct($params);1069 $this->_connection = $connection;1070 $this->cipherer = new RunnerCipherer($this->tName);1071 $this->_sql = new SQLStatement( array(), $order, $groupsTotal, $connection, $params, $this->cipherer, $pageObject );1072 $this->_groups = new ReportGroups($this->_sql, $connection, $groupsTotal, $params, $this );1073 $this->_groupsTotal = $groupsTotal;1074 $this->_groupsPerPage = $groupsPerPage;1075 $this->pSet = new ProjectSettings($this->tName, PAGE_REPORT);1076 1077 if(is_null($pageObject))1078 {1079 include_once getabspath('classes/controls/ViewControlsContainer.php');1080 $this->pageObject = new ViewControlsContainer($this->pSet, PAGE_REPORT);1081 }1082 else1083 $this->pageObject = $pageObject;1084 1085 $this->init();1086 }1087 1088 function init($from = 0)1089 {1090 Summarable::init($from);1091 $this->_sql->_from = $from;1092 $this->_list = array();1093 $this->_totalRecords = 0;1094 $this->_pages = array();1095 $this->_groupKeys = array();1096 $this->_lastPageNumber = 0;1097 $this->_pageSummary = array();1098// $this->_printRecordCount = 0;1099 $this->_listedRows = 0;1100 $this->_oldLevels = array();1101 1102 $this->cipherer = new RunnerCipherer($this->tName);1103 }1104 1105 function getPages()1106 {1107 return $this->_pages;1108 }1109 1110 /// logic1111 function getFormattedRow($value) {}1112 function writeGroup(&$begin, &$end, $gkey, $grp, $nField, $values) {}1113 function _writePage(&$page, $src, $count) {}1114 function writeGlobalSummary($source) {}1115 1116 function writePageSummary()1117 {1118 if($this->_doPaging)1119 {1120 for($nCnt = 0; $nCnt < count($this->_list); $nCnt++)1121 {1122 if(!isset($this->_pages[$nCnt]))1123 $this->_pages[$nCnt]=array();1124 $result =& $this->_pages[$nCnt];1125 if(isset($this->_pageSummary[$nCnt]))1126 {1127 $page = $this->_pageSummary[$nCnt];1128 $this->_writePage($result,1129 isset($page['summary']) ? $page['summary'] : array(),1130 isset($page['count']) ? $page['count'] : 0);1131 }1132 else1133 $this->_writePage($result, array(), 0);1134 }1135 }1136 else1137 {1138 $result = array();1139 $page = $this->_summary;1140 $this->_writePage($result,1141 isset($page['summary']) ? $page['summary'] : array(),1142 isset($page['count']) ? $page['count'] : 0);1143 $this->_summary = $result;1144 }1145 1146 if(0 == count($this->_pages) && count($this->_list) > 0)1147 $this->_pages []= $this->_summary;1148 }1149 1150 function makeSummary()1151 {1152 $this->_makeSummary($this->_summary, 0);1153 }1154 1155 /*1156 * Update report with another record. Create a summary if needed.1157 *1158 * $recordsMode - true if report is being built from raw SQL query and false if the query is grouped1159 * $data - record fetched from the database1160 * $rowToAppend - record with formatted values to append (show raw data option)1161 */1162 function setSummary($recordsMode, $data, $rowToAppend = null)1163 {1164 $level =& $this->_summary;1165 1166 $setBegin = false;1167 if ($this->repGroupFieldsCount)1168 {1169 // get array of keys for current record1170 $recordkeys = array();1171 for( $i = 0; $i < count( $this->repGroupFields ); $i++ )1172 {1173 $groupIndex = $this->repGroupFields[ $i ][ 'groupOrder' ] - 1;1174 $field = $this->_sql->field( $groupIndex );1175 $recordkeys[ $groupIndex ] = $field->getKey( $data );1176 }1177 1178 // add empty record for each closed group to hold its summary1179 if( count($this->_groupKeys) > 0 )1180 {1181 $changed = false;1182 $nKey = 0;1183 for(; $nKey < count($recordkeys); $nKey ++)1184 {1185 if($recordkeys[$nKey] != $this->_groupKeys[$nKey])1186 {1187 $changed = true;1188 break;1189 }1190 }1191 if($changed)1192 {1193 // in reverse order1194 for($nKey2 = count($recordkeys) - 1; $nKey2 >= $nKey; $nKey2 --)1195 {1196 $emptyRow =& $this->appendRow(array());1197 $field = $this->_sql->field($nKey2);1198 $this->_printRecordCount += $field->_rowsInSummary;1199 $this->_listedRows ++;1200 $this->_oldLevels[$nKey2]['_end'] =& $emptyRow;