phpDocumentor SpoolTemplate
[ Back ] [ class tree: SpoolTemplate ] [ index: SpoolTemplate ] [ all elements ]

Source for file sptpl_clsBlock.php

Documentation is available at sptpl_clsBlock.php

  1. <?php
  2. /**
  3. * @copyright sptpl_clsBlock.php is part of Sptpl project {@link http://www.andrioli.com/en/sptpl.html} and it is LGPL
  4. * @author Andrioli Darvin <darvin (inside) andrioli (dot) com>
  5. * @version $Header: d:\cvs/classistd/sptpl/sptpl_clsBlock.php,v 2.6 2005/03/02 21:00:54 Darvin Exp $
  6. */
  7. /*
  8. * +-------------------------------------------------------------------------+
  9. * | Sptpl |
  10. * +-------------------------------------------------------------------------+
  11. * | Copyright (c) 2003-2005 Andrioli Darvin |
  12. * | Email <darvin (inside) andrioli (dot) com> |
  13. * | Web http://www.andrioli.com/en/sptpl.html |
  14. * | Download http://www.phpclasses.org/browse.html/package/1326.html |
  15. * | |
  16. * +-------------------------------------------------------------------------+
  17. * | This library is free software; you can redistribute it and/or modify |
  18. * | it under the terms of the GNU Lesser General Public License as |
  19. * | published by the Free Software Foundation; either version 2 of the |
  20. * | License, or (at your option) any later version. |
  21. * | |
  22. * | This library is distributed in the hope that it will be useful, but |
  23. * | WITHOUT ANY WARRANTY; without even the implied warranty of |
  24. * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
  25. * | Lesser General Public License for more details. |
  26. * | |
  27. * | You should have received a copy of the GNU Lesser General Public |
  28. * | License along with this library; if not, write to the Free Software |
  29. * | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
  30. * +-------------------------------------------------------------------------+
  31. */
  32.  
  33. class CBlock {
  34. /**
  35. * reference to the instance of DataManager, created by the class sptpl
  36. * @var object CDataStorage $DataMgr
  37. */
  38. var $DataMgr;
  39.  
  40. var $SuggestedId;
  41.  
  42. var $MyId;
  43.  
  44. var $Param;
  45.  
  46. /**
  47. * Block type:
  48. * block (block of rows), single (single row)
  49. * @var string
  50. */
  51. var $Type;
  52. /**
  53. * Id of the columnset to use to print the block's contents
  54. * default='' =no columnset required
  55. * @var string
  56. */
  57. var $ColumnSet;
  58. /**
  59. * The array contains the parameters for each level of grouping
  60. * @var array
  61. * @see ParseXml()
  62. */
  63. var $Levels;
  64.  
  65. /**
  66. * Groups definition
  67. * @var array
  68. * @see ParseXml()
  69. */
  70. var $Groups;
  71.  
  72. /**
  73. * Parameters to connect to the db to extract tha data
  74. * @var array
  75. */
  76. var $Db;
  77. /**
  78. * Name of tha global array where look for the information to printout
  79. * @var array
  80. */
  81. var $Source;
  82.  
  83. /**
  84. * Type of data source configured for the block.
  85. * Values: Sql, Variable, Function
  86. * @var string
  87. */
  88. var $SourceType;
  89.  
  90. var $Rows;
  91. /**
  92. * reference to the instance of PageManager created by the class sptpl
  93. * @var object CPageMgr
  94. */
  95. var $PageMgr;
  96. /**
  97. * Array holding the name of the counters defined
  98. * in this block.
  99. * @var array
  100. */
  101. var $Counters;
  102. /**
  103. * Array holding the name of the counters defined at block
  104. * level
  105. * @var array
  106. */
  107. var $GlobalCounters;
  108.  
  109. /**
  110. * Class constructor
  111. * @param object CDataStorage &$RefToDataMgr
  112. * @param object CPageMgr &$clsPageMgr
  113. * @param string $id
  114. * @param object CXml2Array $Node
  115. */
  116. function CBlock(&$RefToDataMgr,&$clsPageMgr,$id,$Node)
  117. {
  118. if(DEBUG) $GLOBALS['dbg']->f_in('CBlock');
  119. $this->DataMgr=&$RefToDataMgr;
  120. $this->MyId="";
  121. $this->SuggestedId=$id;
  122. $this->Param=array();
  123. $this->Db=array();
  124. $this->Counters=array();
  125. $this->GlobalCounters=array();
  126. $this->ColumnSet='';
  127. $this->PageMgr=&$clsPageMgr;
  128. if(!is_object($this->PageMgr))
  129. trigger_error('Internal error. CBlock second parameter should be an object',E_USER_ERROR);
  130.  
  131. switch (strtolower($Node->GetNodeName())) {
  132. case 'row':
  133. $this->_SingleRowBlock($Node);
  134. break;
  135. case 'block':
  136. $this->ParseXml($Node);
  137. break;
  138. case 'newpage':
  139. $this->_NewPageBlock($Node);
  140. break;
  141. }
  142.  
  143. if(DEBUG) $GLOBALS['dbg']->f_out();
  144. }
  145.  
  146. /**
  147. * Returns the block Id
  148. * @access public
  149. */
  150. function GetId()
  151. {
  152. return($this->MyId);
  153. }
  154.  
  155.  
  156. /**
  157. * Parse the block tag and its childs and set the intenal structure
  158. *
  159. * @param object CXml2Array $Node
  160. * @access public
  161. */
  162. function ParseXml($Cfg)
  163. {
  164. if(DEBUG) $GLOBALS['dbg']->f_in('ParseXml');
  165. // Check some attribute
  166. while(($ret=$Cfg->EachAttribute())!=FALSE)
  167. {
  168. list($AttribName,$value)=$ret;
  169. switch(strtolower($AttribName))
  170. {
  171. case 'id':
  172. if($this->MyId=="")
  173. $this->MyId=$value;
  174. else
  175. trigger_error("You cannot change the id to an existing block",E_USER_ERROR);
  176. break;
  177. case 'columnset':
  178. $this->ColumnSet=$value;
  179. break;
  180. }
  181. }
  182. // No Id from the configuration node, use the suggested
  183. if($this->MyId=="") {$this->MyId=$this->SuggestedId;}
  184. $this->Type='Block';
  185. $this->Levels=array();
  186. $this->Groups=array();
  187. // loop on root's child
  188. while(($ret=$Cfg->EachChild())!=FALSE)
  189. {
  190. list($ChildName,$child)=$ret;
  191. switch(strtolower($ChildName)) {
  192. case 'counter':
  193. $this->_NewBlockCounter($child);
  194. break;
  195. case 'datasource' :
  196. $this->_BlockAddDataSource($child);
  197. break;
  198. case 'group' :
  199. $this->_BlockAddGroup($child);
  200. break;
  201. case 'openbody' :
  202. $this->_BlockBodyRows($child,'openbody',CURRENTVALUE);
  203. break;
  204. case 'closebody' :
  205. $this->_BlockBodyRows($child,'closebody',OLDVALUE);
  206. break;
  207. case 'body' :
  208. $this->_BlockAddBody($child);
  209. break;
  210. case 'endgroup' :
  211. $this->_BlockCloseGroup($child);
  212. break;
  213. case 'font' :
  214. $this->PageMgr->NewFont($child);
  215. break;
  216. default:
  217. trigger_error('Unknown tag '.$ChildName,E_USER_ERROR);
  218. break;
  219. }
  220. }
  221. if(DEBUG) $GLOBALS['dbg']->f_out();
  222. return;
  223. }
  224.  
  225. /**
  226. * Create a new counter at block level.
  227. *
  228. * @parameter object CXml2Array $Node
  229. * @access private
  230. */
  231. function _NewBlockCounter($Node)
  232. {
  233. if(DEBUG) $GLOBALS['dbg']->f_in('_NewBlockCounter');
  234. $c_name=$this->DataMgr->AddCounter($Node);
  235. $this->Counters[]=$c_name;
  236. $this->GlobalCounters[]=$c_name;
  237. if(DEBUG) $GLOBALS['dbg']->f_out();
  238. }
  239.  
  240. /**
  241. * Create a new counter for the group $Name.
  242. *
  243. * @parameter object CXml2Array $Node
  244. * @parameter string $Name group name
  245. * @access private
  246. */
  247. function _NewGroupCounter($Node,$Name)
  248. {
  249. if(DEBUG) $GLOBALS['dbg']->f_in('_NewGroupCounter');
  250. $c_name=$this->DataMgr->AddCounter($Node);
  251. $this->Counters[]=$c_name;
  252. $this->Groups[$Name]['counters'][]=$c_name;
  253. if(DEBUG) $GLOBALS['dbg']->f_out();
  254. }
  255.  
  256.  
  257. /**
  258. * Load the rows from openbody tag.
  259. * Notice: the tag may contains only text or many row childs
  260. *
  261. * @param object CXml2Array $Cfg
  262. * @param string which tag I'm parsing from the configuration, openbody or closebody
  263. * @param string OLDVALUE, CURRENTVALUE, constant to pass to crow. OLDVALUE is used by
  264. * closebody, CURRENTVALUE is iused by openbody
  265. * @see OLDVALUE
  266. * @see CURRENTVALUE
  267. * @see CRow()
  268. * @access private
  269. */
  270. function _BlockBodyRows($Cfg,$index,$valueType)
  271. {
  272. if(DEBUG) $GLOBALS['dbg']->f_in('_BlockBodyRows');
  273. $this->Rows[$index]=array();
  274. // If I've some text add it as normal row
  275. $InnerText=$Cfg->GetText();
  276. if($InnerText<>'')
  277. $this->Rows[$index][]=new CRow($this->DataMgr,$child,$valueType);
  278. // loop over the row childs
  279. while(($ret=$Cfg->EachChild())!=FALSE)
  280. {
  281. list($ChildName,$child)=$ret;
  282. switch(strtolower($ChildName)) {
  283. case 'row' :
  284. $this->Rows[$index][]=new CRow($this->DataMgr,$child,$valueType);
  285. break;
  286. }
  287. }
  288. if(DEBUG) $GLOBALS['dbg']->f_out();
  289. }
  290.  
  291.  
  292. /**
  293. * Set the data source information for the current block
  294. *
  295. * @param object CXml2Array $Cfg
  296. * @access private
  297. */
  298. function _BlockAddDataSource($Cfg)
  299. {
  300. if(DEBUG) $GLOBALS['dbg']->f_in('_BlockAddDataSource');
  301. while(($ret=$Cfg->EachChild())!=FALSE)
  302. {
  303. list($ChildName,$child)=$ret;
  304. switch(strtolower($ChildName)) {
  305. case 'dbname' :
  306. case 'dbserver' :
  307. case 'dbuser' :
  308. case 'dbpasswd' :
  309. case 'dbclass' :
  310. $this->Db[$ChildName]=$child->GetText();
  311. break;
  312. case 'sql' :
  313. // it allows many sql statement
  314. $this->Db['sql'][]=$child->GetText();
  315. $this->SourceType='Sql';
  316. break;
  317. case 'varname' :
  318. // Global variable name
  319. $this->Source=$child->GetText();
  320. $this->SourceType='Variable';
  321. break;
  322. case 'function' :
  323. // Function to call
  324. $this->Source=$child->GetText();
  325. $this->SourceType='Function';
  326. break;
  327. default:
  328. trigger_error('Unknown tag '.$ChildName,E_USER_ERROR);
  329. break;
  330. }
  331. }
  332. if(DEBUG) $GLOBALS['dbg']->f_out();
  333. }
  334.  
  335.  
  336. /**
  337. * Set the grouping information for the current block
  338. *
  339. * @param object CXml2Array $Cfg
  340. * @access private
  341. */
  342. function _BlockAddGroup($Cfg)
  343. {
  344. if(DEBUG) $GLOBALS['dbg']->f_in('_BlockAddGroup');
  345. $Level=-1;
  346. $Name='';
  347. $Key='';
  348. while(($ret=$Cfg->EachAttribute())!=FALSE)
  349. {
  350. list($AttribName,$value)=$ret;
  351. if(strtolower($AttribName)=='level') { $Level=$value;}
  352. if(strtolower($AttribName)=='name') { $Name=$value;}
  353. if(strtolower($AttribName)=='key') { $Key=$value;}
  354. }
  355.  
  356. if($Level==-1)
  357. trigger_error('Group level not specified',E_USER_ERROR);
  358.  
  359. if($Name=='')
  360. trigger_error('Group name not specified',E_USER_ERROR);
  361.  
  362. if($Key=='')
  363. trigger_error('Group key not specified',E_USER_ERROR);
  364.  
  365. if(array_key_exists($Level,$this->Levels))
  366. trigger_error('Level '.$Level.' for group '.$Name.' already exists',E_USER_ERROR);
  367.  
  368. if(array_key_exists($Level,$this->Groups))
  369. trigger_error('Group name '.$Name.' already exists',E_USER_ERROR);
  370.  
  371. $this->Groups[$Name]['key']=$Key;
  372. $this->Groups[$Name]['level']=$Level;
  373. $this->Groups[$Name]['open']=array();
  374. $this->Groups[$Name]['counters']=array();
  375. $this->Groups[$Name]['close']=array();
  376. $this->Levels[$Level]['groupname']=$Name;
  377. $this->Levels[$Level]['key']=$Key;
  378. $this->Levels[$Level]['value']='';
  379. // the open group may contains many row tag
  380. while(($ret=$Cfg->EachChild())!=FALSE)
  381. {
  382. list($ChildName,$child)=$ret;
  383. switch(strtolower($ChildName)) {
  384. case 'row' :
  385. $this->Groups[$Name]['open'][]=new CRow($this->DataMgr,$child);
  386. break;
  387. case 'counter':
  388. $this->_NewGroupCounter($child,$Name);
  389. break;
  390. }
  391. }
  392.  
  393. if(DEBUG) $GLOBALS['dbg']->f_out();
  394. }
  395.  
  396. /**
  397. * Set the body
  398. *
  399. * @param object CXml2Array $Cfg
  400. * @access private
  401. */
  402. function _BlockAddBody($Cfg)
  403. {
  404. if(DEBUG) $GLOBALS['dbg']->f_in('_BlockAddBody');
  405. $this->Rows['row']=array();
  406. $this->Rows['header']=array();
  407. while(($ret=$Cfg->EachChild())!=FALSE)
  408. {
  409. list($ChildName,$child)=$ret;
  410. switch(strtolower($ChildName)) {
  411. case 'row' :
  412. case 'header' :
  413. $this->Rows[strtolower($ChildName)][]=new CRow($this->DataMgr,$child);
  414. break;
  415. default:
  416. trigger_error('Unknown tag '.$ChildName,E_USER_ERROR);
  417. break;
  418. }
  419. }
  420. if(DEBUG) $GLOBALS['dbg']->f_out();
  421. }
  422.  
  423.  
  424. /**
  425. * Set the text for the closing group row.
  426. *
  427. * @param object CXml2Array $Cfg
  428. * @access private
  429. */
  430. function _BlockCloseGroup($Cfg)
  431. {
  432. if(DEBUG) $GLOBALS['dbg']->f_in('_BlockCloseGroup');
  433. $Name='';
  434. while(($ret=$Cfg->EachAttribute())!=FALSE)
  435. {
  436. list($AttribName,$value)=$ret;
  437. switch(strtolower($AttribName))
  438. {
  439. case 'name' :
  440. $Name=$value;
  441. break;
  442. }
  443. }
  444. if($Name=='')
  445. trigger_error('Endgroup name not specified',E_USER_ERROR);
  446. // the open group may contains many row tag
  447. while(($ret=$Cfg->EachChild())!=FALSE)
  448. {
  449. list($ChildName,$child)=$ret;
  450. switch(strtolower($ChildName)) {
  451. case 'row' :
  452. $this->Groups[$Name]['close'][]=new CRow($this->DataMgr,$child,OLDVALUE);
  453. break;
  454. }
  455. }
  456. if(DEBUG) $GLOBALS['dbg']->f_out();
  457. }
  458.  
  459. /**
  460. * Parse the tag row and add it to the array report as block
  461. * with only a single row. Return the block id assigned or what I get
  462. * from the attribute id.
  463. *
  464. * @param object CXml2Array $Cfg
  465. * @access private
  466. */
  467. function _SingleRowBlock($Cfg)
  468. {
  469. if(DEBUG) $GLOBALS['dbg']->f_in('_SingleRowBlock');
  470. // Check some attribute
  471. $idBlock=$this->SuggestedId;
  472. while(($ret=$Cfg->EachAttribute())!=FALSE)
  473. {
  474. list($AttribName,$value)=$ret;
  475. if(strtolower($AttribName)=='id') { $idBlock=$value;}
  476.  
  477. }
  478. $this->Type='row';
  479. $this->Rows['row'][]=new CRow($this->DataMgr,$Cfg);
  480. $this->Levels=array();
  481. $this->Groups=array();
  482. $this->MyId=$idBlock;
  483. if(DEBUG) $GLOBALS['dbg']->f_out();
  484. return;
  485. }
  486.  
  487. /**
  488. * Parse the tag newpage and add it to the array report as block
  489. * with only a single row. Return the block id assigned or what I get
  490. * from the attribute id.
  491. *
  492. * @param object CXml2Array $Cfg
  493. * @access private
  494. */
  495. function _NewPageBlock($Cfg)
  496. {
  497. if(DEBUG) $GLOBALS['dbg']->f_in('_NewPageBlock');
  498. // Check some attribute
  499. $idBlock=$this->SuggestedId;
  500. while(($ret=$Cfg->EachAttribute())!=FALSE)
  501. {
  502. list($AttribName,$value)=$ret;
  503. if(strtolower($AttribName)=='id') { $idBlock=$value;}
  504. }
  505. $this->Type='row';
  506. $this->Rows['row'][]=new CNewPage();
  507. $this->Levels=array();
  508. $this->Groups=array();
  509. $this->MyId=$idBlock;
  510. if(DEBUG) $GLOBALS['dbg']->f_out();
  511. return;
  512. }
  513.  
  514.  
  515. //********************************************************************************
  516.  
  517. /**
  518. * Draw one block. In this function I establish wich type block I've
  519. * and run the right function to manage it
  520. *
  521. * @access public
  522. */
  523. function RunBlock()
  524. {
  525. if(DEBUG) $GLOBALS['dbg']->f_in('RunBlock');
  526. // single row block?
  527. // var_dump($this->Groups);
  528. if(!is_object($this->PageMgr))
  529. trigger_error('Internal error. RunBlock, first parameter should be an object',E_USER_ERROR);
  530. // Set the required columnset (if set)
  531. if($this->ColumnSet!='')
  532. $this->PageMgr->NewColumnSet($this->ColumnSet);
  533. if($this->Type=='row')
  534. {
  535. // Single row type, I'm expecting to get the row key
  536. if(array_key_exists('row',$this->Rows))
  537. $this->_RunBlockSingleRow();
  538. else
  539. trigger_error('Internal error, block without any row',E_USER_ERROR);
  540. }
  541. else
  542. {
  543. // block type. Loop over many row.
  544. // Switch between the diifferent source types
  545. switch($this->SourceType)
  546. {
  547. case 'Sql': // Data from database
  548. $this->_RunBlockFromDb();
  549. break;
  550. case 'Variable': // Data from GLOBAL array
  551. $this->_RunBlockFromArray();
  552. break;
  553. case 'Function': // Data from custom function
  554. $this->_RunBlockFromFunction();
  555. break;
  556. default:
  557. trigger_error('ERROR: undefined block\'s datasource.',E_USER_ERROR);
  558. }
  559. }
  560. if(DEBUG) $GLOBALS['dbg']->f_out();
  561. }
  562.  
  563. /**
  564. * Block without repetition
  565. */
  566. function _RunBlockSingleRow()
  567. {
  568. if(DEBUG) $GLOBALS['dbg']->f_in('_RunBlockSingleRow');
  569. $this->DataMgr->ResetCounter($this->GlobalCounters);
  570. $this->_WriteDataBlock(array(),0,0);
  571. if(DEBUG) $GLOBALS['dbg']->f_out();
  572. }
  573.  
  574. /**
  575. * Open db connection, run the query, and loop through the returned rows
  576. *
  577. * @access private
  578. */
  579. function _RunBlockFromDb()
  580. {
  581. if(DEBUG) $GLOBALS['dbg']->f_in('RunBlockFromDb');
  582. $RepDb=$this->Db;
  583. // open the connection to the db
  584. // From DbClass, I establish which class use to connect to the db
  585. if(!array_key_exists('dbclass',$RepDb))
  586. trigger_error('Undefined dbclass for block id:'.$this->MyId,E_USER_ERROR);
  587. eval('$DbConn=new '.$RepDb['dbclass'].'();');
  588. $ConStr='$DbConn->DbOpen(';
  589. //Db server
  590. if(!array_key_exists('dbserver',$RepDb))
  591. trigger_error('Undefined dbserver for block id:'.$this->MyId,E_USER_ERROR);
  592. $ConStr.='"'.$RepDb['dbserver'].'",';
  593. //dbUser
  594. if(!array_key_exists('dbuser',$RepDb))
  595. trigger_error('Undefined dbuser for block id:'.$this->MyId,E_USER_ERROR);
  596. $ConStr.='"'.$RepDb['dbuser'].'",';
  597. //dbpasswd
  598. if(array_key_exists('dbpasswd',$RepDb))
  599. $ConStr.='"'.$RepDb['dbpasswd'].'",';
  600. else
  601. $ConStr.='"",';
  602. //dbname
  603. if(!array_key_exists('dbname',$RepDb))
  604. trigger_error('Undefined dbname for block id:'.$this->MyId,E_USER_ERROR);
  605. $ConStr.='"'.$RepDb['dbname'].'");';
  606. // Open the connection
  607. eval($ConStr);
  608.  
  609. //Run all query
  610. foreach($RepDb['sql'] as $sql)
  611. {
  612. $DbConn->DbExecSql($sql);
  613. }
  614. $NumLevels=$this->_InitGrouping();
  615. //loop over all returned data row
  616. $counter=0;
  617. $this->DataMgr->ResetCounter($this->GlobalCounters);
  618. while($fields=$DbConn->DbGetValue())
  619. {
  620. $this->_WriteDataBlock($fields,$NumLevels,!$counter);
  621. $counter++;
  622. }
  623. $this->_CloseAllGroups($NumLevels);
  624. $DbConn->DbClose();
  625. if(DEBUG) $GLOBALS['dbg']->f_out();
  626. }
  627.  
  628. /**
  629. * Printout all record form a given array (from $GLOBAL)
  630. *
  631. * @access private
  632. */
  633. function _RunBlockFromArray()
  634. {
  635. if(DEBUG) $GLOBALS['dbg']->f_in('RunBlockFromArray');
  636. $ArrayName=$this->Source;
  637. if(!array_key_exists($ArrayName,$GLOBALS))
  638. trigger_error('Array '.$ArrayName.' does not exist in $GLOBAL',E_USER_ERROR);
  639. $DataArray=$GLOBALS[$ArrayName];
  640. // Init tha grouping index
  641. $NumLevels=$this->_InitGrouping();
  642. //loop over all keys
  643. $counter=0;
  644. $this->DataMgr->ResetCounter($this->GlobalCounters);
  645. foreach($DataArray as $fields)
  646. {
  647. $this->_WriteDataBlock($fields,$NumLevels,!$counter);
  648. $counter++;
  649. }
  650. $this->_CloseAllGroups($NumLevels);
  651. if(DEBUG) $GLOBALS['dbg']->f_out();
  652. }
  653.  
  654. /**
  655. * Printout all data from the values returned by the custom function
  656. * Note: the function must return an associative array.
  657. * The names of the fields are the indexes of the array.
  658. *
  659. * @access private
  660. */
  661. function _RunBlockFromFunction()
  662. {
  663. if(DEBUG) $GLOBALS['dbg']->f_in('RunBlockFromFunction');
  664. if(!function_exists($this->Source))
  665. trigger_error('The function '.$this->Source.' does not exist in $GLOBAL',E_USER_ERROR);
  666. // Init the grouping index
  667. $NumLevels=$this->_InitGrouping();
  668. //loop over all keys
  669. $counter=0;
  670. $this->DataMgr->ResetCounter($this->GlobalCounters);
  671. eval('$fields='.$this->Source.'();');
  672. while($fields)
  673. {
  674. $this->_WriteDataBlock($fields,$NumLevels,!$counter);
  675. $counter++;
  676. eval('$fields='.$this->Source.'();');
  677. }
  678. $this->_CloseAllGroups($NumLevels);
  679. if(DEBUG) $GLOBALS['dbg']->f_out();
  680. }
  681.  
  682. /**
  683. * Initialize the variable used to manage the grouping for the specified block
  684. * The function return the max level specified. 0 if none.
  685. * @return integer
  686. * @access private
  687. */
  688. function _InitGrouping()
  689. {
  690. if(DEBUG) $GLOBALS['dbg']->f_in('_InitGrouping');
  691. // var_dump($this->Levels);
  692. if(!count($this->Levels))
  693. return(0);
  694.  
  695. $MaxLevel=0;
  696. foreach($this->Levels as $key=>$level)
  697. {
  698. if($key>$MaxLevel)
  699. $MaxLevel=$key;
  700. $this->Levels[$key]['value']='';
  701. }
  702. if(DEBUG) $GLOBALS['dbg']->f_out();
  703. return($MaxLevel);
  704. }
  705.  
  706.  
  707. /**
  708. * Main draw function.
  709. * Manage the grouping, run the open/close group
  710. * Menage the open/close table (with header) and write the row
  711. *
  712. * @parameter array $fields Data field for the current row.
  713. * @parameter integer $NumLevels number of nested level for the current block
  714. * @parameter boolean $FirstRow Is the first time for the current block?
  715. * @access private
  716. *
  717. */
  718.  
  719. function _WriteDataBlock($fields,$NumLevels,$FirstRow)
  720. {
  721. if(DEBUG) $GLOBALS['dbg']->f_in('_WriteDataBlock');
  722. // var_dump($NumLevels);
  723. $this->DataMgr->ToValue($fields);
  724. $ChangeKey=false;
  725. $CurrentLevel=1;
  726. // check if some key is changed
  727. while($CurrentLevel<$NumLevels+1&&!$ChangeKey)
  728. {
  729. if(!$this->DataMgr->ExistValue($this->Levels[$CurrentLevel]['key']))
  730. trigger_error('The key for grouping '.$this->Levels[$CurrentLevel]['key'].' does not exists',E_USER_ERROR);
  731. if($this->Levels[$CurrentLevel]['value']!=$this->DataMgr->GetVar($this->Levels[$CurrentLevel]['key']))
  732. {
  733. // We have some change
  734. if($this->Levels[$CurrentLevel]['value']!='')
  735. {
  736. // Ok, I need to run the closing group from the inner to the outer
  737. for($i=$NumLevels;!$i<$CurrentLevel;$i--)
  738. $this->_CloseGroup($i);
  739. }
  740. // Open the group for the new key value
  741. for($i=$CurrentLevel;!($i>$NumLevels);$i++)
  742. {
  743. if(!$this->DataMgr->ExistValue($this->Levels[$i]['key']))
  744. trigger_error('The key for grouping '.$this->Levels[$i]['key'].' does not exists',E_USER_ERROR);
  745. $this->Levels[$i]['value']=$this->DataMgr->GetVar($this->Levels[$i]['key']);
  746. $this->_OpenGroup($i);
  747. }
  748. $ChangeKey=true;
  749. } // if key change
  750. $CurrentLevel++;
  751. } // while
  752.  
  753. if($ChangeKey||$FirstRow)
  754. {
  755. if(array_key_exists('openbody',$this->Rows))
  756. {
  757. foreach($this->Rows['openbody'] as $Key => $Value)
  758. $Value->WriteOut($this->PageMgr);
  759. }
  760. $this->PageMgr->PrintColumnsHeader(); // If the columns have its own headers
  761. if(array_key_exists('header',$this->Rows))
  762. {
  763. foreach($this->Rows['header'] as $Key => $Value)
  764. $Value->WriteOut($this->PageMgr);
  765. }
  766. }
  767. // Update All counters
  768. $this->DataMgr->UpdateCounters($this->Counters);
  769. // print "<br>out:".$this->MyId."<br>";
  770. // and finally print out the row
  771. foreach($this->Rows['row'] as $Key => $Value)
  772. $Value->WriteOut($this->PageMgr);
  773.  
  774. $this->DataMgr->RemoveFromValue($fields);
  775. if(DEBUG) $GLOBALS['dbg']->f_out();
  776. }
  777.  
  778.  
  779. /**
  780. * Print out the opening row for the group level $Level
  781. * @parameter integer $Level group level to close
  782. * @access private
  783. */
  784. function _OpenGroup($Level)
  785. {
  786. if(DEBUG) $GLOBALS['dbg']->f_in('_OpenGroup');
  787. $GroupName=$this->Levels[$Level]['groupname'];
  788. $Group=$this->Groups[$GroupName];
  789. if(array_key_exists('open',$Group))
  790. {
  791. foreach($Group['open'] as $Key => $Value)
  792. $Value->WriteOut($this->PageMgr);
  793. }
  794. $this->DataMgr->ResetCounter($this->Groups[$GroupName]['counters']);
  795. if(DEBUG) $GLOBALS['dbg']->f_out();
  796. }
  797.  
  798. /**
  799. * Print out the closing row for the group level $Level
  800. * @parameter integer $Level group level to close
  801. * @access private
  802. */
  803. function _CloseGroup($Level)
  804. {
  805. if(DEBUG) $GLOBALS['dbg']->f_in('_CloseGroup');
  806. $GroupName=$this->Levels[$Level]['groupname'];
  807. // $Group=$this->Groups[$GroupName];
  808. if(array_key_exists('close',$this->Groups[$GroupName]))
  809. {
  810. foreach($this->Groups[$GroupName]['close'] as $Key => $Value)
  811. $Value->WriteOut($this->PageMgr);
  812. }
  813. if(DEBUG) $GLOBALS['dbg']->f_out();
  814. }
  815.  
  816. /**
  817. * Close all opend groups.
  818. * @param integer $NumLevels
  819. * @access private
  820. */
  821. function _CloseAllGroups($NumLevels)
  822. {
  823. for($i=$NumLevels;$i>0;$i--)
  824. $this->_CloseGroup($i);
  825. }
  826.  
  827. }
  828.  
  829. ?>

Documentation generated on Mon, 28 Mar 2005 15:13:11 +0200 by phpDocumentor 1.3.0RC3