root/trunk/lib/SGL/Manager.php

Revision 4410, 14.3 kB (checked in by demian, 3 years ago)

wrong case was returned for mgr name -1

Line 
1 <?php
2 /* Reminder: always indent with 4 spaces (no tabs). */
3 // +---------------------------------------------------------------------------+
4 // | Copyright (c) 2010, 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 1.0                                                               |
34 // +---------------------------------------------------------------------------+
35 // | Manager.php                                                               |
36 // +---------------------------------------------------------------------------+
37 // | Author:   Demian Turner <demian@phpkitchen.com>                           |
38 // +---------------------------------------------------------------------------+
39 // $Id: Manager.php,v 1.19 2005/06/13 12:00:25 demian Exp $
40
41 /**
42  * Abstract model controller for all the 'manager' classes.
43  *
44  * @package SGL
45  * @author  Demian Turner <demian@phpkitchen.com>
46  * @version $Revision: 1.19 $
47  * @abstract
48  */
49 class SGL_Manager
50 {
51     /**
52      * Page master-template name.
53      *
54      * @access  public
55      * @var     string
56      */
57
58     var $masterTemplate = 'master.html';
59     /**
60      * Page template name.
61      *
62      * @access  public
63      * @var     string
64      */
65     var $template = '';
66
67     /**
68      * Page title, displayed in template and HTML title tags.
69      *
70      * @access  public
71      * @var     string
72      */
73     var $pageTitle = 'default';
74
75     /**
76      * Flag indicated is Page validation passed.
77      *
78      * @access  public
79      * @var     boolean
80      */
81     var $validated = false;
82
83     /**
84      * Sortby flag, used in child classes.
85      *
86      * @access  public
87      * @var     string
88      */
89     var $sortBy = '';
90
91     /**
92      * Array of action permitted by mgr subclass.
93      *
94      * @access  private
95      * @var     array
96      */
97     var $_aActionsMapping = array();
98
99     var $conf = array();
100     var $dbh = null;
101
102
103     /**
104      * Constructor.
105      *
106      * @access  public
107      * @return  void
108      */
109     function __construct()
110     {
111         SGL::logMessage(null, PEAR_LOG_DEBUG);
112
113         $c = SGL_Config::singleton();
114         $this->conf = $c->getAll();
115         $this->dbh = $this->_getDb();
116
117         //  detect if trans2 support required
118         if (SGL_Config::get('translation.container') == 'db') {
119             $this->trans SGL_Translation::singleton();
120         }
121
122         //  determine the value for the masterTemplate
123         if (SGL_Config::get('site.masterTemplate')) {
124             $this->masterTemplate = SGL_Config::get('site.masterTemplate');
125         }
126     }
127
128     function &_getDb()
129     {
130         $locator = SGL_ServiceLocator::singleton();
131         $dbh = $locator->get('DB');
132         if (!$dbh) {
133             $dbh SGL_DB::singleton();
134             $locator->register('DB', $dbh);
135         }
136         return $dbh;
137     }
138
139     function getConfig()
140     {
141         $c = SGL_Config::singleton();
142         return $c;
143     }
144
145     /**
146      * Specific validations are implemented in sub classes.
147      *
148      * @abstract
149      *
150      * @access  public
151      * @param   SGL_Request     $req    SGL_Request object received from user agent
152      * @param   SGL_Registry    $input  SGL_Registry for storing data
153      * @return  void
154      */
155     function validate($req, &$input) {}
156
157     /**
158      * Super class for implementing authorisation checks, delegates specific processing
159      * to child classses.
160      *
161      * @access  public
162      * @param   SGL_Registry    $input  Input object received from validate()
163      * @param   SGL_Output      $output Processed result
164      * @return  mixed           true on success or PEAR_Error on failure
165      */
166     function process($input, $output)
167     {
168         SGL::logMessage(null, PEAR_LOG_DEBUG);
169
170         $mgrName = SGL_Inflector::caseFix(get_class($this));
171         $defaultMgrLoaded = false;
172
173         if (SGL_Error::count()) {
174             $oLastError = SGL_Error::getLast();
175             if ($oLastError->getCode() == SGL_ERROR_RESOURCENOTFOUND) {
176                 $defaultMgrLoaded = true;
177                 $output->setStatusCode(404);
178             }
179
180         //  determine if action param from $_GET is valid
181         } elseif (!(array_key_exists($input->action, $this->_aActionsMapping))) {
182             return SGL::raiseError('The specified method, ' . $input->action .
183                 ' does not exist', SGL_ERROR_NOMETHOD);
184         }
185         if (!count($this->conf)) {
186             return SGL::raiseError('It appears you forgot to fire SGL_Manager\'s '.
187                 'constructor - please add "parent::__construct();" in your '.
188                 'manager\'s constructor.', SGL_ERROR_NOCLASS);
189         }
190         //  only implement authorisation check on demand
191         if ( isset($this->conf[$mgrName]['requiresAuth'])
192                 && $this->conf[$mgrName]['requiresAuth'] == true
193                 && $this->conf['debug']['authorisationEnabled'])
194         {
195             //  determine global manager perm, ie that is valid for all actions
196             //  in the mgr
197             $mgrPerm = SGL_String::pseudoConstantToInt('SGL_PERMS_' . strtoupper($mgrName));
198
199             //  check authorisation
200             $ok = $this->_authorise($mgrPerm, $mgrName, $input);
201             if ($ok !== true) {
202
203                 //  test for possible errors
204                 if (is_array($ok) && count($ok)) {
205
206                     list($className, $methodName) = $ok;
207                     SGL::logMessage('Unauthorised user '.SGL_Session::getUid() .' attempted to access ' .
208                         $className . '::' .$methodName, PEAR_LOG_WARNING);
209
210                     //  make sure no infinite redirections
211                     $lastRedirected = SGL_Session::get('redirected');
212                     $now = time();
213                     SGL_Session::set('redirected', $now);
214
215                     //  if redirects happen less than 2 seconds apart, and there are greater
216                     //  than 2 of them, recursion is happening
217                     if ($now - $lastRedirected < 2) {
218                         $redirectTimes = SGL_Session::get('redirectedTimes');
219                         $redirectTimes ++;
220                         SGL_Session::set('redirectedTimes', $redirectTimes);
221                     } else {
222                         SGL_Session::set('redirectedTimes', 0);
223                     }
224                     if (SGL_Session::get('redirectedTimes') > 2) {
225                         return PEAR::raiseError('infinite loop detected, clear cookies and check perms',
226                             SGL_ERROR_RECURSION);
227                     }
228                    // redirect to current or default screen
229                     SGL::raiseMsg('authorisation failed');
230                     $aHistory = SGL_Session::get('aRequestHistory');
231                     $aLastRequest = isset($aHistory[1]) ? $aHistory[1] : false;
232                     if ($aLastRequest) {
233                         $aRedir = array(
234                             'managerName'   => $aLastRequest['managerName'],
235                             'moduleName'    => $aLastRequest['moduleName'],
236                             );
237                     } else {
238                         $aRedir = $this->getDefaultPageParams();
239                     }
240                     SGL_HTTP::redirect($aRedir);
241                 } else {
242                     return PEAR::raiseError('unexpected response during authorisation check',
243                         SGL_ERROR_INVALIDAUTH);
244                 }
245             }
246         }
247         if (!$defaultMgrLoaded) {
248             //  all tests passed, execute relevant method
249             foreach ($this->_aActionsMapping[$input->action] as $methodName) {
250                 $methodName = '_cmd_'.$methodName;
251                 $this->{$methodName}($input, $output);
252             }
253         }
254         return true;
255     }
256
257     /**
258      * Perform authorisation on specified action methods.
259      *
260      * @param integer $mgrPerm
261      * @param string  $mgrName
262      * @param SGL_Registry $input
263      * @return mixed true on success, array of class/method names on failure
264      */
265     function _authorise($mgrPerm, $mgrName, $input)
266     {
267         // if user has no global manager perms check for each action
268         if (!SGL_Session::hasPerms($mgrPerm) && !SGL::runningFromCLI()) {
269
270             // and if chained methods to be called are allowed
271             $ret = true;
272             foreach ($this->_aActionsMapping[$input->action] as $methodName) {
273
274                 //  allow redirects without perms
275                 if (preg_match("/redirect/", $methodName)) {
276                     continue;
277                 }
278                 $methodName = '_cmd_' . $methodName;
279
280                 //  build relevant perms constant
281                 $perm = SGL_String::pseudoConstantToInt('SGL_PERMS_' . strtoupper($mgrName . $methodName));
282
283                 //  return false if user doesn't have method specific or classwide perms
284                 if (SGL_Session::hasPerms($perm) === false) {
285                     $ret = array($mgrName, $methodName);
286                     break;
287                 }
288             }
289         } else {
290             $ret = true;
291         }
292         return $ret;
293     }
294
295     /**
296      * Parent page display method.
297      *
298      * Sets CSS file if supplied in request
299      *
300      * @abstract
301      *
302      * @access  public
303      * @param   SGL_Output  $output Input object that has passed through validation
304      * @return  void
305      */
306     function display($output)
307     {
308         //  reinstate dynamically added css
309         if (!$output->manager->isValid()) {
310             if (!count($output->aCssFiles)) {
311                 //  get action
312                 $cssFile = $output->request->get('cssFile');
313                 if (!is_null($cssFile)) {
314                     $output->addCssFile($cssFile);
315                 }
316             }
317         }
318     }
319
320     /**
321      * Return true if child class has validated.
322      *
323      * @return boolean
324      */
325     function isValid()
326     {
327         return $this->validated;
328     }
329
330     /**
331      * Default redirect for all Managers.
332      *
333      * @param SGL_Registry $input
334      * @param SGL_Output $output
335      */
336     function _cmd_redirectToDefault($input, $output)
337     {
338         //  must not logmessage here
339
340         //  if no errors have occured, redirect
341         if (!SGL_Error::count()) {
342             SGL_HTTP::redirect();
343
344         //  else display error with blank template
345         } else {
346             $output->template = 'error.html';
347         }
348     }
349
350     /**
351      * Returns details of the module/manager/params defaults
352      * set in configuration, used for logouts and redirects.
353      *
354      * @return array
355      */
356     function getDefaultPageParams()
357     {
358         $moduleName     = $this->conf['site']['defaultModule'];
359         $managerName    = $this->conf['site']['defaultManager'];
360         $defaultParams  = $this->conf['site']['defaultParams'];
361         $aDefaultParams = !empty($defaultParams)
362             ? explode('/', $defaultParams)
363             : array();
364
365         $aParams = array(
366             'moduleName'    => $moduleName,
367             'managerName'   => $managerName,
368             );
369
370         //  convert string into hash and merge with $aParams
371         $aRet = array();
372         if ($numElems = count($aDefaultParams)) {
373             $aTmp = array();
374             for ($x = 0; $x < $numElems; $x++) {
375                 if ($x % 2) { // if index is odd
376                     $aTmp['varValue'] = urldecode($aDefaultParams[$x]);
377                 } else {
378                     // parsing the parameters
379                     $aTmp['varName'] = urldecode($aDefaultParams[$x]);
380                 }
381                 //  if a name/value pair exists, add it to request
382                 if (count($aTmp) == 2) {
383                     $aRet[$aTmp['varName']] = $aTmp['varValue'];
384                     $aTmp = array();
385                 }
386             }
387         }
388         $aMergedParams = array_merge($aParams, $aRet);
389         return $aMergedParams;
390     }
391
392     function handleError($oError, $output)
393     {
394         $output->template = 'error.html';
395         $output->masterTemplate = 'masterNoCols.html';
396         $output->aError = array(
397             'message'   => $oError->getMessage(),
398             'debugInfo' => $oError->getDebugInfo(),
399             'level'     => $oError->getCode(),
400             'errorType' => SGL_Error::constantToString($oError->getCode())
401         );
402     }
403 }
404 ?>
Note: See TracBrowser for help on using the browser.