root/trunk/lib/SGL/BlockLoader.php

Revision 3147, 9.3 kB (checked in by demian, 3 weeks ago)

synching to trunk

Line 
1 <?php
2 /* Reminder: always indent with 4 spaces (no tabs). */
3 // +---------------------------------------------------------------------------+
4 // | Copyright (c) 2006, Demian Turner                                         |
5 // | All rights reserved.                                                      |
6 // |                                                                           |
7 // | Redistribution and use in source and binary forms, with or without        |
8 // | modification, are permitted provided that the following conditions        |
9 // | are met:                                                                  |
10 // |                                                                           |
11 // | o Redistributions of source code must retain the above copyright          |
12 // |   notice, this list of conditions and the following disclaimer.           |
13 // | o Redistributions in binary form must reproduce the above copyright       |
14 // |   notice, this list of conditions and the following disclaimer in the     |
15 // |   documentation and/or other materials provided with the distribution.    |
16 // | o The names of the authors may not be used to endorse or promote          |
17 // |   products derived from this software without specific prior written      |
18 // |   permission.                                                             |
19 // |                                                                           |
20 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
21 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         |
22 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR     |
23 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      |
24 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     |
25 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT          |
26 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     |
27 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     |
28 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       |
29 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE     |
30 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.      |
31 // |                                                                           |
32 // +---------------------------------------------------------------------------+
33 // | Seagull 0.6                                                               |
34 // +---------------------------------------------------------------------------+
35 // | BlockLoader.php                                                           |
36 // +---------------------------------------------------------------------------+
37 // | Author:   Demian Turner <demian@phpkitchen.com>                           |
38 // +---------------------------------------------------------------------------+
39 // $Id: BlockLoader.php,v 1.7 2005/05/16 23:55:23 demian Exp $
40
41 /**
42  * BlockLoader manages units of content that can be dynamically positioned in a
43  * page's left or right columns.
44  *
45  * @package SGL
46  * @author  Demian Turner <demian@phpkitchen.com>
47  * @version $Revision: 1.7 $
48  * @access  public
49  */
50 class SGL_BlockLoader
51 {
52     /**
53      * Temporary container for processing blocks.
54      *
55      * @access  private
56      * @var     array
57      */
58     var $_aData = array();
59
60     /**
61      * Array of processed blocks
62      *
63      * Left/right blocks stored as $this->aBlocks['left'],
64      * $this->aBlocks['right'].
65      *
66      * @access  public
67      * @var     array
68      */
69     var $aBlocks = array();
70
71     /**
72      * The role id, used so blocks can be cached per role.
73      *
74      * @access  private
75      * @var     int
76      */
77     var $_rid = 0;
78
79     /**
80      * SectionId is currently roughtly equivalent to page id.
81      *
82      * @access  private
83      * @var     int
84      * @todo    change to pageId, also rename section table
85      */
86     var $_currentSectionId = 0;
87
88     /**
89      * Constructor - sets the sectionId.
90      *
91      * @access  public
92      * @return  void
93      */
94     function SGL_BlockLoader($sectionId)
95     {
96         $this->_rid = (int)SGL_Session::get('rid');
97         if (isset($sectionId)) {
98             $this->_currentSectionId = $sectionId;
99         }
100         $c = &SGL_Config::singleton();
101         $this->conf = $c->getAll();
102     }
103
104     /**
105      * Initialises Block Mgr, loads blocks into temporary array
106      * $_aData for later processing.
107      *
108      * @author  Andy Crain <apcrain@fuse.net>>
109      * @access  private
110      * @return  array   array of block objects
111      */
112     function render(&$output)
113     {
114         //  put data generated so far into class scope
115         $this->output = &$output;
116         $cache = & SGL_Cache::singleton();
117         $currLang = (isset($output->currLang))
118             ? $output->currLang
119             : '';
120         $charset = (isset($output->charset))
121             ? $output->charset
122             : '';
123         $cacheId = $this->_currentSectionId . $this->_rid
124             . $currLang . $charset;
125         if ($data = $cache->get($cacheId, 'blocks')) {
126             $this->aBlocks = unserialize($data);
127
128             //  update uncached blocks
129             $this->_loadBlocks(false);
130
131             SGL::logMessage('blocks from cache', PEAR_LOG_DEBUG);
132         } else {
133             $this->_loadBlocks();
134             $data = serialize($this->aBlocks);
135             $cache->save($data, $cacheId, 'blocks');
136             SGL::logMessage('blocks from db', PEAR_LOG_DEBUG);
137         }
138         return $this->aBlocks;
139     }
140
141     /**
142      * Loads blocks from DB.
143      *
144      * @access  private
145      * @return  void
146      */
147     function _loadBlocks($getAll = true)
148     {
149         $dbh = & SGL_DB::singleton();
150         $addWhere = $getAll ? '' : "AND b.is_cached = 0 ";
151         $query = "
152             SELECT
153                 b.block_id, b.name, b.title, b.title_class,
154                 b.body_class, b.position, b.params, b.is_cached
155             FROM    {$this->conf['table']['block']} b, {$this->conf['table']['block_assignment']} ba,
156                     {$this->conf['table']['block_role']} br
157             WHERE   b.is_enabled = 1 " . $addWhere .
158             "AND     (br.block_id = b.block_id AND
159                       (br.role_id = '" . SGL_Session::getRoleId() . "' OR br.role_id = '" . SGL_ANY_ROLE . "')
160                     )
161             AND     b.block_id = ba.block_id
162             AND     ( ba.section_id = ".SGL_ANY_SECTION." OR ba.section_id = " . $this->_currentSectionId . ' )
163             ORDER BY b.blk_order
164         ';
165
166         $aResult = $dbh->getAll($query);
167
168         if (!DB::isError($aResult)) {
169             $this->_aData = $aResult;
170
171             //  render content from each class
172             $this->_buildBlocks();
173         } else {
174             SGL::raiseError('section ID not found', SGL_ERROR_NODATA);
175         }
176     }
177
178     /**
179      * With block structures in place, block contents are built.
180      *
181      * Each block is a class in the modules/block/classes/blocks directory,
182      * containing static HTML or dynamic content
183      *
184      * @access  private
185      * @return  void
186      */
187     function _buildBlocks()
188     {
189         //  render content
190         if (count($this->_aData) > 0 ) {
191             foreach ($this->_aData as $index => $oBlock) {
192                 $blockClass = $oBlock->name;
193                 preg_match('/^(.*)_.*_(.*)$/', $blockClass, $aMatches);
194                 @$blockPath = strtolower($aMatches[1]) . '/blocks/' . $aMatches[2];
195
196                 //  load CMS blocks if installed
197                 if (SGL::moduleIsEnabled('cms') && $blockPath == 'navigation/blocks/Navigation') {
198                     $blockPath = 'cms/blocks/Navigation';
199                     $blockClass = 'Cms_Block_Navigation';
200                 }
201                 if (file_exists(SGL_MOD_DIR . '/' . $blockPath . '.php')) {
202                     require_once SGL_MOD_DIR . '/' . $blockPath . '.php';
203                 } else {
204                     unset($this->_aData[$index]);
205                     SGL::raiseError('cannot load ' . $blockClass . '; '
206                         . $blockPath . '.php does not exist',
207                         SGL_ERROR_NOFILE);
208                 }
209                 if (!class_exists($blockClass)) {
210                     unset($this->_aData[$index]);
211                     SGL::raiseError($blockClass . ' is not a valid block classname',
212                         SGL_ERROR_NOCLASS);
213                 } else {
214                     if (is_scalar($aParams = @unserialize($oBlock->params))) {
215                         $aParams = array();
216                     }
217                     @$obj = & new $blockClass();
218                     if ($data = $obj->init($this->output, $oBlock->block_id, $aParams)) {
219                         $this->_aData[$index]->content = $data;
220                     } else {
221                         //  remove the whole block if a false is captured
222                         unset($this->_aData[$index]);
223                     }
224                 }
225             }
226             $this->_sort();
227         }
228     }
229
230     /**
231      * Sorts tmp array $_aData into order within block positions.
232      *
233      * easier to manage in Controller
234      *
235      * @access  private
236      * @return  void
237      */
238     function _sort()
239     {
240         if (count($this->_aData) > 0) {
241             foreach ($this->_aData as $oBlock) {
242                 $this->aBlocks[$oBlock->position][$oBlock->block_id] = $oBlock;
243             }
244         }
245         unset($this->_aData);
246     }
247 }
248 ?>
249
Note: See TracBrowser for help on using the browser.