CoolFace
Apppublic

kenken999/php

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
crosstable_report.php1073 linesDownload Raw Back to classes
1<?php2$group_sort_y = array();3class CrossTableReport4{5	/**6	 * the report table name7	 */8	protected $tableName;9 10	/**11	 * the current teport page type ( report, print )12	 */13	protected $pageType;14 15	/**16	 * An instance of the 'ViewControlsContainer' class17	 * @type Object18	 */19	protected $viewControls;20 21 22	/**23	 * An Instance of the 'ProjectSettings' class24	 * @type Object25	 */26	protected $pSet = null;27 28	/**29	 * @type Connection30	 */31	protected $connection;32 33	protected $dataSource;34 35 36	protected $group_header = array();37	protected $col_summary = array();38	protected $rowinfo = array();39	protected $total_summary;40 41	protected $showXSummary;42	protected $showYSummary;43	protected $showTotalSummary;44	protected $groupFieldsData;45	protected $fieldsTotalsData;46 47	protected $xFName;48	protected $yFName;49 50	protected $xIntervalType;51	protected $yIntervalType;52 53	/**54	 * The report current data field name55	 */56	protected $dataField = "";57 58	/**59	 * The selected data field settings packed in an array.60	 * @type Array61	 */62	protected $dataFieldSettings = null;63 64	/**65	 * The report current aggregate function66	 */67	protected $dataGroupFunction = "";68 69	protected $pdfJSON = false;70 71	protected $selectedAxis ;72 73	protected $pageObject;74 75	protected $sort_groups;76 77	protected $sortGroupOrder = 'ASC';78	79	/**80	 * @constructor81	 * @param Array params82	 */83	function __construct( $params, $pageObject )84	{85		$this->pageObject = $pageObject;86		$this->dataSource = $pageObject->getDataSource();87 88		$this->pageType	= $params["pageType"];89		$this->tableName = $params["tableName"];90		$this->setDbConnection();91 92		$this->pSet = new ProjectSettings($this->tableName, PAGE_REPORT);93		include_once getabspath("classes/controls/ViewControlsContainer.php");94		$this->viewControls = new ViewControlsContainer( $this->pSet, PAGE_REPORT );95 96		$this->pdfJSON = $params["pdfJSON"];97 98		$this->groupFieldsData = $params["groupFields"];99		$this->fieldsTotalsData = $params["totals"];100 101		$this->selectedAxis = $params["selectedAxis"];102		$this->showXSummary = $params["xSummary"];103		$this->showYSummary = $params["ySummary"];104		$this->showTotalSummary = $params["totalSummary"];105 106		$this->xFName = $this->getGroupFieldByParam( "x", $params["x"] );107		$this->yFName = $this->getGroupFieldByParam( "y", $params["y"], $this->xFName );108		$this->dataField = $this->getDataFieldByParam( $params["data"] );109 110		$this->dataFieldSettings = $params["totals"][ $this->dataField ];111		$this->dataGroupFunction = $this->getDataGroupFunction( $params["operation"] );112 113		$this->xIntervalType = $this->getIntervalTypeByParam( "x", $this->xFName, $params["xType"] );114		$this->yIntervalType = $this->getIntervalTypeByParam( "y", $this->yFName, $params["yType"] );115 116		$this->correctCrosstabParams();117 118		$this->fillGridData( $params["headerClass"], $params["dataClass"] );119	}120 121	/**122	 * @param String headerClass123	 * @param String dataClass124	 */125	protected function fillGridData( $headerClass, $dataClass )126	{127		$qResult = $this->dataSource->getTotals( $this->getDataCommand() );128 129		$group_y = array();130		$group_x = array();131 132		$arrdata = array();133		$arravgsum = array();134		$arravgcount = array();135 136		$avgsumx = array();137		$avgcountx = array();138 139		$space = $this->pdfJsonMode() ? "' '" : "&nbsp;";140 141		// data 1 y value; //data 2 x value; //data 0 data field value // data 3 avg_sum//data 4 avg count142		while( $data = $qResult->fetchNumeric() )143		{144			if( !in_array( $data[1], $group_y ) )145			{146				$group_y[] = $data[1];147			}148 149			if( !in_array( $data[2], $group_x ) )150			{151				$group_x[] = $data[2];152				$this->col_summary["data"][ count($group_x) - 1 ]["col_summary"] = $space;153				$this->col_summary["data"][ count($group_x) - 1 ]["id_col_summary"] = "total_x_".( count($group_x) - 1);154			}155 156			$key_y = array_search( $data[1], $group_y );157 158			$key_x = array_search( $data[2], $group_x );159 160			$avgsumx[ $key_x ] = 0;161			$avgcountx[ $key_x ] = 0;162 163			$arrdata[ $key_y ][ $key_x ] = $data[0];164			$arravgsum[ $key_y ][ $key_x ] = $data[3];165			$arravgcount[ $key_y ][ $key_x ] = $data[4];166		}167 168		$this->sort_groups = &$group_x;169		$sort_indices = array_keys( $group_x );170		$this->sortGroupOrder = $this->getGroupOrderDirection( $this->xFName );171		usort( $sort_indices, array( $this, "groupSort" ) );172		173		$newColSummary = array();174		foreach( $sort_indices as $i ) {175			$newColSummary[] =& $this->col_summary["data"][$i];176		}177		$this->col_summary["data"] =& $newColSummary;178 179 180		$this->rowinfo = $this->getBasicRowsData( $group_y, $group_x, $sort_indices, $arrdata, $dataClass );181 182		foreach( $sort_indices as $key_x )183		{184			$value_x = $group_x[ $key_x ];185			if( $value_x != "" )186				$this->group_header["data"][ $key_x ]["gr_value"] = $this->pageObject->formatGroupValue( $this->xFName, $this->xIntervalType, $value_x );187			else188				$this->group_header["data"][ $key_x ]["gr_value"] = $space;189 190			$this->group_header["data"][ $key_x ]["gr_x_class"] = $headerClass;191		}192 193		$arravgsum = $this->sortAvgTotalsData( $arravgsum, $sort_indices );194		$arravgcount = $this->sortAvgTotalsData( $arravgcount, $sort_indices );195		196		$this->setSummariesData( $arravgsum, $arravgcount, $avgsumx, $avgcountx );197 198		$this->updateRecordsDisplayedFields();199	}200	201	/**202	 * Update x axis indices in avg totals data203	 * @param Array data204	 * @param Array sort_indices205	 * @return Array206	 */207	protected function sortAvgTotalsData( $data, $sort_x ) {208		$sorted = array();209		210		foreach( $data as $key_y => $value_y ) {211			$sorted[ $key_y ] = array();212			213			foreach( $sort_x as $display_x => $key_x ) {214				if( array_key_exists( $key_x, $value_y ) ) {215					$sorted[ $key_y ][ $display_x ] = $value_y[ $key_x ];216				}217			}218		}219		220		return $sorted;221	}222	223	public function groupSort( $i1, $i2 ) {224		$a = $this->sort_groups[ $i1 ];225		$b = $this->sort_groups[ $i2 ];226		227		if( $a > $b )228			return $this->sortGroupOrder == 'DESC' ? -1 : 1;229		if( $a < $b )230			return $this->sortGroupOrder == 'DESC'? 1 : -1;231		return 0;232	}233 234	/**235	 * @return Array236	 */237	protected function getBasicRowsData( $group_y, $group_x, $sort_x, $arrdata, $dataClass )238	{239		$crossRowsData = array();240		$ftype = $this->pSet->getFieldType( $this->dataField );241 242		$space = $this->pdfJsonMode() ? "' '" : "&nbsp;";243 244		foreach( $group_y as $key_y => $value_y )245		{246			$crossRowsData[ $key_y ]["row_summary"] = $space;247			$crossRowsData[ $key_y ]["group_y"] = $this->pageObject->formatGroupValue( $this->yFName, $this->yIntervalType, $value_y );248			$crossRowsData[ $key_y ]["id_row_summary"] = "total_y_".$key_y;249			$crossRowsData[ $key_y ]["summary_class"] = $dataClass;250			//$crossRowsData[ $key_y ]["gr_y_class"] = "";251 252			if( !array_key_exists( $key_y, $arrdata ) )253				continue;254 255			if( !$crossRowsData[ $key_y ]["row_record"] ) {256				$crossRowsData[ $key_y ]["row_record"] = array();257			}258			$crossRowsData[ $key_y ]["row_record"]["data"] = array();259			$row =& $crossRowsData[ $key_y ]["row_record"]["data"];260	261			// prefill row to ensure right ordering262			foreach( $sort_x as $key_x ) {263				$row[] = array();264			}265 266			foreach( $sort_x as $display_x => $key_x )267			{268				$value_x = $group_x[ $key_x ];269				$rowValue = $space;270 271				if( array_key_exists( $key_x, $arrdata[ $key_y ] ) && !is_null( $arrdata[ $key_y ][ $key_x ] ) )272				{273					$rowValue = $arrdata[ $key_y ][ $key_x ];274					if( $this->dataGroupFunction == "avg" && !IsTimeType( $ftype ) )275						$rowValue = $rowValue;276				}277 278				$row[ $display_x ]["row_value"] = $rowValue;279				$row[ $display_x ]["row_value_class"] = $dataClass;280				$row[ $display_x ]["id_data"] = $key_y."_".$display_x;281			}282		}283 284		return $crossRowsData;285	}286 287	/**288	 * ???289	 */290	protected function setSummariesData( $arravgsum, $arravgcount, $avgsumx, $avgcountx )291	{292		$space = $this->pdfJsonMode() ? "' '" : "&nbsp;";293 294		$this->total_summary = $space;295 296		$xSummaty = array();297		$ySummary = array();298		$totaxSummary = array();299 300		foreach( $this->rowinfo as $key_y => $yData )301		{302			foreach( $yData["row_record"]["data"] as $key_x => $value )303			{304				if( $value["row_value"] == $space )305					continue;306 307				switch( $this->dataGroupFunction )308				{309					case "sum":310						if( $this->rowinfo[ $key_y ]["row_summary"] === $space ) {311							$this->rowinfo[ $key_y ]["row_summary"] = 0;312						}313						if( $this->col_summary["data"][ $key_x ]["col_summary"] === $space ) {314							$this->col_summary["data"][ $key_x ]["col_summary"] = 0;315						}316						if( $this->total_summary === $space ) {317							$this->total_summary = 0;318						}319						$this->rowinfo[ $key_y ]["row_summary"] += (double)$value["row_value"];320						$this->col_summary["data"][ $key_x ]["col_summary"] += (double)$value["row_value"];321						$this->total_summary += (double)$value["row_value"];322					break;323 324					case "min":325						if( $this->rowinfo[ $key_y ]["row_summary"] === $space || $value["row_value"] < $this->rowinfo[ $key_y ]["row_summary"] )326							$this->rowinfo[ $key_y ]["row_summary"] = $value["row_value"];327 328						if( $this->col_summary["data"][ $key_x ]["col_summary"] === $space || $this->col_summary["data"][ $key_x ]["col_summary"] > $value["row_value"] )329							$this->col_summary["data"][ $key_x ]["col_summary"] = $value["row_value"];330 331						if( $this->total_summary === $space || $this->total_summary > $value["row_value"] )332							$this->total_summary = $value["row_value"];333					break;334 335					case "max":336						if( $this->rowinfo[ $key_y ]["row_summary"] === $space || $value["row_value"] > $this->rowinfo[ $key_y ]["row_summary"] )337							$this->rowinfo[ $key_y ]["row_summary"] = $value["row_value"];338 339						if( $this->col_summary["data"][ $key_x ]["col_summary"] === $space || $this->col_summary["data"][ $key_x ]["col_summary"] < $value["row_value"] )340							$this->col_summary["data"][ $key_x ]["col_summary"] = $value["row_value"];341 342						if( $this->total_summary === $space || $this->total_summary < $value["row_value"] )343							$this->total_summary = $value["row_value"];344					break;345 346					case "avg":347						$this->rowinfo[ $key_y ]["avgsumy"] += $arravgsum[ $key_y ][ $key_x ];348						$this->rowinfo[ $key_y ]["avgcounty"] += $arravgcount[ $key_y ][ $key_x ];349						$this->rowinfo[ $key_y] ["row_record"]["data"][ $key_x ]["avgsumx"] += $arravgsum[ $key_y ][ $key_x ];350						$this->rowinfo[ $key_y ]["row_record"]["data"][ $key_x ]["avgcountx"] += $arravgcount[ $key_y ][ $key_x ];351					break;352				}353 354				if( $this->showXSummary && !is_null( $this->col_summary["data"][ $key_x ]["col_summary"] ) )355				{356					if( is_numeric( $this->col_summary["data"][ $key_x ]["col_summary"] ) )357						$this->col_summary["data"][ $key_x ]["col_summary"] = $this->col_summary["data"][ $key_x ]["col_summary"];358				}359				else360					$this->col_summary["data"][ $key_x ]["col_summary"] = $space;361			}362 363			if( $this->showYSummary && !is_null( $this->rowinfo[ $key_y ]["row_summary"] ) )364			{365				if( is_numeric( $this->rowinfo[ $key_y ]["row_summary"] ) )366					$this->rowinfo[ $key_y ]["row_summary"] = $this->rowinfo[ $key_y ]["row_summary"];367			}368			else369				$this->rowinfo[ $key_y ]["row_summary"] = $space;370		}371 372		if( $this->dataGroupFunction == "avg" )373		{374			$total_sum = 0;375			$total_count = 0;376 377			foreach( $this->rowinfo as $key_y => $valuey )378			{379				if( $valuey["avgcounty"] )380				{381					if ( $this->showYSummary )382					{383						$this->rowinfo[ $key_y ]["row_summary"] = $valuey["avgsumy"] / $valuey["avgcounty"];384					}385 386					$total_sum += $valuey["avgsumy"];387					$total_count += $valuey["avgcounty"];388				}389 390				foreach( $valuey["row_record"]["data"] as $key_x => $valuex )391				{392					if( $valuex["avgcountx"] )393					{394						$avgsumx[ $key_x ] += $valuex["avgsumx"];395						$avgcountx[ $key_x ] += $valuex["avgcountx"];396						$total_sum += $valuex["avgsumx"];397						$total_count += $valuex["avgcountx"];398					}399				}400			}401 402			if ( $this->showXSummary )403			{404				foreach( $avgsumx as $key => $value )405				{406					if( $avgcountx[ $key ] )407						$this->col_summary["data"][ $key ]["col_summary"] = $value / $avgcountx[$key];408				}409			}410 411			if( $total_count )412				$this->total_summary = $total_sum / $total_count;413		}414 415		if( !$this->showTotalSummary )416			$this->total_summary = $space;417		elseif( is_numeric($this->total_summary) )418			$this->total_summary = $this->total_summary;419	}420 421	/**422	 * Get view value basing on 'view as'423	 * @param String|Number value424	 * @return String|Number425	 */426	function getViewValue( $value ) {		427		if( $this->pSet->getViewFormat( $this->dataField ) == FORMAT_TIME && is_numeric( $value ) ) {			428			if( $this->dataGroupFunction == "avg" )429				$value = round( $value, 0 );			430 431			include_once getabspath('classes/controls/ViewTimeField.php');		432			return ViewTimeField::getFormattedTotals( 433				$this->dataField, 434				$value, 435				$this->pSet, 436				$this->pdfJsonMode(), 437				$this->dataGroupFunction == "sum" 438			);439		} 440		441		$controlData = array( $this->dataField => $value );442		return $this->showDBValue( $this->dataField, $controlData );443	}444 445	/**446	 * Update the records and summaries data basing on 'view as' and 'total' settings447	 */448	protected function updateRecordsDisplayedFields()449	{450		if( !$this->rowinfo )451			return;452 453		$space = $this->pdfJsonMode() ? "' '" : "&nbsp;";454 455		foreach($this->rowinfo as $key_y => $data)456		{457			foreach($data["row_record"]["data"] as $key_x => $fieldData)458			{459				if( $fieldData["row_value"] == $space )460					continue;461 462				$this->rowinfo[ $key_y ]["row_record"]["data"][ $key_x ]["row_value"] = $this->getViewValue( $fieldData["row_value"] );463			}464 465			if( $data["row_summary"] != $space )466			{467				$this->rowinfo[ $key_y ]["row_summary"] = $this->getViewValue( $data["row_summary"] );468			}469		}470 471		if( $this->total_summary != $space )472		{473			$this->total_summary = $this->getViewValue( $this->total_summary );474		}475 476		foreach($this->col_summary["data"] as $key => $summaryData)477		{478			if( $summaryData["col_summary"] == $space )479				continue;480 481			$this->col_summary["data"][ $key ]["col_summary"] = $this->getViewValue( $summaryData["col_summary"] );482		}483	}484 485	public function getCrossTableData()486	{487		return $this->rowinfo;488	}489 490	/**491	 * @return Boolean492	 */493	public function isEmpty()494	{495		return !$this->rowinfo;496	}497 498	public function getCrossTableHeader()499	{500		return $this->group_header;501	}502 503	public function getCrossTableSummary()504	{505		return $this->col_summary;506	}507 508	public function getTotalSummary()509	{510		return $this->total_summary;511	}512 513	/**514	 * Assign 'connection' property515	 */516	protected function setDbConnection()517	{518		global $cman;519		$this->connection = $cman->byTable( $this->tableName ); //#9875520	}521 522	/**523	 * @param String axis524	 * @param String crossName525	 * @param String userIntType526	 * @return Number527	 */528	protected function getIntervalTypeByParam( $axis, $crossName, $userIntType )529	{530		$iType = $this->getRefineIntervalType( $userIntType, $crossName );531 532		$int_type = -1;533		$intTypes = array();534		foreach( $this->groupFieldsData as $fData )535		{536			if( $fData["name"] == $crossName && ( $fData["group_type"] == "all" || $fData["group_type"] == $axis ) )537			{538				if( !strlen( $userIntType ) || $iType == $fData["int_type"] )539				{540					$int_type = $fData["int_type"];541					break;542				}543 544				$intTypes[] = $fData["int_type"];545			}546		}547 548		if( $int_type != -1 )549			return $int_type;550 551		if( count( $intTypes ) > 0 )552			return $intTypes[0];553 554		// something went wrong555		return 0;556	}557 558	protected function getDataFieldByParam( $paramField ) 559	{560		if( $this->fieldsTotalsData[ $paramField ] ) {561			return $paramField;562		}563		$dataFields = array_keys( $this->fieldsTotalsData );564		if( count( $dataFields ) ) {565			return $dataFields[0];566		}567		return "";568	}569 570	protected function getGroupFieldByParam( $axis, $paramField, $otherField = "" )571	{572		$firstField = "";573		foreach( $this->groupFieldsData as $fData )574		{575			if( $fData["group_type"] == "all" || $fData["group_type"] == $axis ) {576				if( $fData["name"] == $paramField )577				{578					return $paramField;579				}580				if( $firstField === "" && (!$otherField || $otherField !== $firstField ))581					$firstField = $fData["name"];582			}583		}584		return $firstField;585	}586 587	protected function getDataCommand() {588		$dc = $this->pageObject->getSubsetDataCommand();589 590		$ftype = $this->pSet->getFieldType( $this->dataField );591 592		$dc->totals[] = array(593			"field" => $this->dataField,594			"total" => $this->dataGroupFunction,595			"timeToSec" => $this->pSet->getViewFormat( $this->dataField ) == FORMAT_TIME || IsTimeType($ftype)596		);597 598		$dc->totals[] = array(599			"field" => $this->yFName,600			"modifier" => $this->yIntervalType,601			"direction" => $this->getGroupOrderDirection( $this->yFName )602		);603 604		$dc->totals[] = array(605			"field" => $this->xFName,606			"modifier" => $this->xIntervalType607		);608 609		if( $this->dataGroupFunction == "avg" && !IsDateFieldType($ftype) ) {610			$dc->totals[] = array(611				"field" => $this->dataField,612				"alias" => "avg_sum",613				"total" => "sum",614				"timeToSec" => $this->pSet->getViewFormat( $this->dataField ) == FORMAT_TIME || IsTimeType($ftype)615			);616 617			$dc->totals[] = array(618				"field" => $this->dataField,619				"alias" => "avg_count",620				"total" => "count"621			);622		} else {623			$dc->totals[] = array(624				"alias" => "avg_sum",625				"total" => "count"626			);627			$dc->totals[] = array(628				"alias" => "avg_count",629				"total" => "count"630			);631		}632 633		$BeforeQueryReport = $this->pageType == PAGE_REPORT634			&& tableEventExists("BeforeQueryReport", $this->tableName);635		$BeforeQueryReportPrint = $this->pageType == PAGE_RPRINT636			&& tableEventExists("BeforeQueryReportPrint", $this->tableName);637 638		if( $BeforeQueryReport || $BeforeQueryReportPrint ) {639			$prep = $this->dataSource->prepareSQL( $dc );640			$where = $prep["where"];641 642			$eventObj = getEventObject( $this->tableName );643 644			if( $BeforeQueryReport )645				$eventObj->BeforeQueryReport( $where );646			else647				$eventObj->BeforeQueryReportPrint( $where );648 649			if( $where != $prep["where"] )650				$this->dataSource->overrideWhere( $dc, $where );651		}652 653 654		return $dc;655	}656	657	protected function getGroupOrderDirection( $fName ) {658		$orderIndices =& $this->pSet->getOrderIndexes();	659		$fieldIdx = $this->pSet->getFieldIndex( $fName );660		foreach( $orderIndices as $o ) {661			if( $o[0] == $fieldIdx ) {662				return $o[1];663			}664		}665		return 'ASC';		666	}667 668	/**669	 * @return Array670	 */671	public function getSelectedValue()672	{673		$arr = array();674		$firstarr = array();675		foreach( $this->fieldsTotalsData as $key => $value )676		{677			if(count($firstarr) == 0)678				$firstarr[] = $value["name"];679 680			if($value["min"] == true || $value["max"] == true || $value["sum"] == true || $value["avg"] == true)681			{682				$arr[] = $value["name"];683			}684		}685		if(count($arr) == 0)686			$arr = $firstarr;687		return $arr;688	}689 690	/**691	 * @return Array692	 */693	public function getCurrentOperationList()694	{695		$names = array();696		$names["sum"] = "Sum";697		$names["min"] = "Min";698		$names["max"] = "Max";699		$names["avg"] = "Avg";700 701		$opData = array();702 703		foreach( $names as $o => $n )704		{705			if( !$this->dataFieldSettings[$o] )706				continue;707 708			$opData[] = array(709				"value" => $o,710				"selected" => $this->dataGroupFunction == $o ? "selected" : "",711				"label" => $n712			);713		}714 715		return $opData;716	}717 718	/**719	 * @param String $axis720	 * @return Array721	 */722	 public function getCrossFieldsData( $axis )723	{724		$dataList = array();725 726		foreach( $this->groupFieldsData as $data )727		{728			if( ( $axis != "x" || $data["group_type"] != "x" )729				&& ( $axis != "y" || $data["group_type"] != "y" )730					&& $data["group_type"] != "all" ) {731				continue;732			}733 734 735			$selected = "";736			if( $axis == "x" && $data["name"] == $this->xFName && $data["int_type"] == $this->xIntervalType737			 || $axis == "y" && $data["name"] == $this->yFName && $data["int_type"] == $this->yIntervalType )738				$selected = "selected";739 740			$intervalType =	$data["uniqueName"]	? "" : $this->getIntervalParam( $data["int_type"], $data["name"] );741 742			$dataList[] = array(743				"value" => $data["name"],744				"selected" => $selected,745				"label" => $data["label"],746				"intervalType" => $intervalType747			);748		}749 750		return $dataList;751	}752 753	/**754	 *755	 */756	protected function getRefineIntervalType( $intType, $fName )757	{758		if( $intType === 0 )759			return "normal";760 761		$ftype = $this->pSet->getFieldType( $fName );762 763		if( IsNumberType( $ftype ) )764			return substr( $intType, 1 );765 766		if( IsCharType( $ftype ) )767			return substr( $intType, strlen("first") );768 769		if( IsDateFieldType( $ftype ) )770		{771			switch( $intType )772			{773				case "year":774					return 1;775				case "quarter":776					return 2;777				case "month":778					return 3;779				case "week":780					return 4;781				case "day":782					return 5;783				case "hour":784					return 6;785				case "minute":786					return 7;787			}788		}789 790		return -1;791	}792 793	/**794	 * @param Number intType795	 * @return String796	 */797	protected function getIntervalParam( $intType, $fName )798	{799		if( $intType == 0 )800			return "normal";801 802		$ftype = $this->pSet->getFieldType( $fName );803 804		if( IsNumberType( $ftype ) )805			return "n".$intType;806 807		if( IsCharType( $ftype ) )808			return "first".$intType;809 810		if( IsDateFieldType( $ftype ) )811		{812			switch( $intType )813			{814				case 1:815					return "year";816				case 2:817					return "quarter";818				case 3:819					return "month";820				case 4:821					return "week";822				case 5:823					return "day";824				case 6:825					return "hour";826				case 7:827					return "minute";828				default:829					return "";830			}831		}832 833		return "";834	}835 836	/**837	 * @return Array838	 */839	public function getDataFieldsList()840	{841		$listData = array();842 843		foreach( $this->fieldsTotalsData as $key => $value )844		{845			if($value["min"] == true || $value["max"] == true || $value["sum"] == true || $value["avg"] == true)846			{847				$selected = $value["name"] == $this->dataField ? "selected" : "";848				$listData[] = array( "value" => $value["name"], "selected" => $selected, "label" => $value["label"] );849			}850		}851 852		return $listData;853	}854 855	/**856	 * Get the report print header html-markup857	 * @return String858	 */859	public function getPrintCrossHeader()860	{861		if( $this->pdfJsonMode() )862			return $this->getPdfCrossHeader();863 864		return "<div>"."Group X"865			.":<b>".$this->fieldsTotalsData[ $this->xFName ]["label"]."</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"."Group Y"866			.":<b>".$this->fieldsTotalsData[ $this->yFName ]["label"]."</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"."Field"867			.":<b>".$this->fieldsTotalsData[ $this->dataField ]["label"]."</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"."Group function"868			.":<b>".$this->dataGroupFunction."</b></div>";869	}870 871	protected function getPdfCrossHeader()872	{873		$parts = array();874		$parts[] = "{ text: '"."Group X".":'}";875		$parts[] = "{ text: '". $this->getXGroupLabel() ."     ', bold: true }";876		$parts[] = "{ text: '"."Group Y".":'}";877		$parts[] = "{ text: '". $this->getYGroupLabel() ."     ', bold: true }";878		$parts[] = "{ text: '"."Field".":'}";879		$parts[] = "{ text: '". $this->getDataFieldLabel() ."     ', bold: true }";880		$parts[] = "{ text: '"."Group function".":'}";881		$parts[] = "{ text: '". jsreplace( $this->dataGroupFunction ) ."', bold: true }";882 883		return implode( $parts, "," );884	}885 886	public function getXGroupLabel()887	{888		if( $this->pdfJsonMode() )889			return "'". jsreplace( $this->fieldsTotalsData[ $this->xFName ]["label"] ) ."'";890 891		return $this->fieldsTotalsData[ $this->xFName ]["label"];892	}893 894	public function getYGroupLabel()895	{896		if( $this->pdfJsonMode() )897			return "'". jsreplace( $this->fieldsTotalsData[ $this->yFName ]["label"] ) ."'";898 899		return $this->fieldsTotalsData[ $this->yFName ]["label"];900	}901 902	public function getDataFieldLabel()903	{904		if( $this->pdfJsonMode() )905			return "'". jsreplace( $this->fieldsTotalsData[ $this->dataField ]["label"] ) ."'";906 907		return $this->fieldsTotalsData[ $this->dataField ]["label"];908	}909 910	protected function _getTotalsName()911	{912		switch( $this->dataGroupFunction )913		{914			case "sum":915				return "Sum";916			break;917			case "min":918				return "Min";919			break;920			case "max":921				return "Max";922			break;923			case "avg":924				return "Average";925			break;926			default:927				return "";928		}929	}930 931	/**932	 * @param String operation933	 * @return String934	 */935	public function getTotalsName()936	{937		if( $this->pdfJsonMode() )938			return "'". jsreplace( $this->_getTotalsName() ) ." '";939 940		return $this->_getTotalsName();941	}942 943	/**944	 * Checks whether passed function name is valid945	 * @param String operation946	 * @return String947	 */948	protected function getDataGroupFunction( $operation )949	{950		//	good951		if( $this->dataFieldSettings[ $operation ] == true )952			return $operation;953 954		//	bad, set first possible955		$gfuncs = array("sum", "max", "min", "avg");956		foreach($gfuncs as $gf)957		{958			if( $this->dataFieldSettings[ $gf ] == true )959				return $gf;960		}961 962		// default963		return "sum";964	}965 966	/**967	 * Get the current group function name968	 * @return String969	 */970	public function getCurrentGroupFunction()971	{972		return $this->dataGroupFunction;973	}974 975	/**976	 *977	 */978	public static function getCrossIntervalName( $ftype, $int_type )979	{980		if( IsDateFieldType( $ftype ) )981		{982			if($int_type == 1) // DATE_INTERVAL_YEAR983				return "year";984			if($int_type == 2) // DATE_INTERVAL_QUARTER985				return "quarter";986			if($int_type == 3) // DATE_INTERVAL_MONTH987				return "month";988			if($int_type == 4) // DATE_INTERVAL_WEEK989				return "week";990			if($int_type == 5) // DATE_INTERVAL_DAY991				return "day";992			if($int_type == 6) // DATE_INTERVAL_HOUR993				return "hour";994			if($int_type == 7) // DATE_INTERVAL_MINUTE995				return "minute";996		}997		return $int_type;998	}999 1000	protected function pdfJsonMode()1001	{1002		return $this->pdfJSON;1003	}1004 1005	function showDBValue( $field, &$data )1006	{1007		$control = $this->viewControls->getControl( $field );1008 1009		if( $this->pdfJsonMode() ) {1010			return $control->getPdfValue( $data, "" );1011		}1012		return $control->showDBValue( $data, "" );1013	}1014 1015	/**1016	 * Indicates which axis to change in case when both axes point to the same field/interval1017	 * Returns 'x','y' or ''1018	 */1019	protected function getFreeAxis() {1020		if( $this->selectedAxis )1021			return $this->selectedAxis == "y" ? "x" : "y";1022 1023		// select axis where there are more than one option available1024		$xCount = 0;1025		$yCount = 0;1026		foreach( $this->groupFieldsData as $fData )1027		{1028			if( $fData["group_type"] == "all" ) {1029				++$xCount;1030				++$yCount;1031			} else if( $fData["group_type"] == "x" ) {1032				++$xCount;1033			} else {1034				++$yCount;1035			}1036			if( $xCount > 1 ) {1037				return 'x';1038			}1039			if( $yCount > 1 ) {1040				return 'y';1041			}1042		}1043		return '';1044	}1045 1046	/**1047	 * Change crosstab parameters to ensure X(field+interval) != Y(field+interval)1048	 */1049	protected function correctCrosstabParams() {1050		if( $this->xFName != $this->yFName || $this->xIntervalType != $this->yIntervalType)1051			return;1052		// determine which axis to change1053		$freeAxis = $this->getFreeAxis();1054		if( !$freeAxis ) {1055			return;1056		}1057		foreach( $this->groupFieldsData as $fData )1058		{1059			if( $fData["group_type"] == "all" || $fData["group_type"] == $freeAxis ) {1060				if( $this->xFName !== $fData["name"] || $this->xIntervalType !== $fData["int_type"] ) {1061					if( $freeAxis === 'x' ) {1062						$this->xFName = $fData["name"];1063						$this->xIntervalType = $fData["int_type"];1064					} else {1065						$this->yFName = $fData["name"];1066						$this->yIntervalType = $fData["int_type"];1067					}1068					break;1069				}1070			}1071		}1072	}1073}