throws exception if mandatory user object is missing
[tine20] / tine20 / Tinebase / Controller / Abstract.php
1 <?php
2 /**
3  * Tine 2.0
4  *
5  * @package     Tinebase
6  * @subpackage  Controller
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @author      Philipp Schuele <p.schuele@metaways.de>
9  * @copyright   Copyright (c) 2007-2011 Metaways Infosystems GmbH (http://www.metaways.de)
10  * 
11  */
12
13 /**
14  * controller abstract for applications
15  *
16  * @package     Tinebase
17  * @subpackage  Controller
18  */
19 abstract class Tinebase_Controller_Abstract implements Tinebase_Controller_Interface
20 {
21     /**
22      * default settings
23      * 
24      * @var array
25      */
26     protected $_defaultsSettings = array();
27     
28     
29     /**
30      * holds the default Model of this application
31      * @var string
32      */
33     protected static $_defaultModel = NULL;
34     
35     /**
36      * application name (is needed in checkRight())
37      *
38      * @var string
39      */
40     protected $_applicationName = '';
41     
42     /**
43      * disable events on demand
44      * 
45      * @var mixed   false => no events filtered, true => all events filtered, array => disable only specific events
46      */
47     protected $_disabledEvents = false;
48     
49     /**
50      * generic check admin rights function
51      * rules: 
52      * - ADMIN right includes all other rights
53      * - MANAGE_* right includes VIEW_* right 
54      * - results are cached if caching is active (with cache tag 'rights')
55      * 
56      * @param   string  $_right to check
57      * @param   boolean $_throwException [optional]
58      * @param   boolean $_includeTinebaseAdmin [optional]
59      * @return  boolean
60      * @throws  Tinebase_Exception_UnexpectedValue
61      * @throws  Tinebase_Exception_AccessDenied
62      * @throws  Tinebase_Exception
63      * 
64      * @todo move that to *_Acl_Rights
65      * @todo include Tinebase admin? atm only the application admin right is checked
66      * @todo think about moving the caching to Tinebase_Acl_Roles and use only a class cache as it is difficult (and slow?) to invalidate
67      */
68     public function checkRight($_right, $_throwException = TRUE, $_includeTinebaseAdmin = TRUE) 
69     {
70         if (empty($this->_applicationName)) {
71             throw new Tinebase_Exception_UnexpectedValue('No application name defined!');
72         }
73         if (! is_object(Tinebase_Core::getUser())) {
74             throw new Tinebase_Exception('No user found for right check!');
75         }
76         
77         $right = strtoupper($_right);
78         
79         $cache = Tinebase_Core::getCache();
80         $cacheId = convertCacheId('checkRight' . Tinebase_Core::getUser()->getId() . $right . $this->_applicationName);
81         $result = $cache->load($cacheId);
82         
83         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $cacheId);
84         
85         if (!$result) {
86             $applicationRightsClass = $this->_applicationName . '_Acl_Rights';
87             
88             // array with the rights that should be checked, ADMIN is in it per default
89             $rightsToCheck = ($_includeTinebaseAdmin) ? array(Tinebase_Acl_Rights::ADMIN) : array();
90             
91             if (preg_match("/VIEW_([A-Z_]*)/", $right, $matches)) {
92                 // manage right includes view right
93                 $rightsToCheck[] = constant($applicationRightsClass. '::MANAGE_' . $matches[1]);
94             } 
95             
96             $rightsToCheck[] = constant($applicationRightsClass. '::' . $right);
97             
98             $result = FALSE;
99             
100             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
101                 . ' Checking rights: ' . print_r($rightsToCheck, TRUE));
102             
103             foreach ($rightsToCheck as $rightToCheck) {
104                 if (Tinebase_Acl_Roles::getInstance()->hasRight($this->_applicationName, Tinebase_Core::getUser()->getId(), $rightToCheck)) {
105                     $result = TRUE;
106                     break;
107                 }
108             }
109             
110             $cache->save($result, $cacheId, array('rights'), 120);
111         }
112         
113         if (!$result && $_throwException) {
114             throw new Tinebase_Exception_AccessDenied("You are not allowed to $right in application $this->_applicationName !");
115         }
116         
117         return $result;
118     }
119     
120     /**
121      * Returns default settings for app
122      *
123      * @param boolean $_resolve if some values should be resolved
124      * @return  array settings data
125      */
126     public function getConfigSettings($_resolve = FALSE)
127     {
128         $appConfig = Tinebase_Config::getAppConfig($this->_applicationName);
129         if ($appConfig != NULL) {
130             $settings = $appConfig::getInstance()->get(
131                 Tinebase_Config::APPDEFAULTS, 
132                 new Tinebase_Config_Struct($this->_defaultsSettings)
133             )->toArray();
134         } else { 
135             $settings = $this->_defaultsSettings;
136         }
137         return ($_resolve) ? $this->_resolveConfigSettings($settings) : $settings;
138     }
139     
140     /**
141      * resolve some settings
142      * 
143      * @param array $_settings
144      */
145     protected function _resolveConfigSettings($_settings)
146     {
147         return $_settings;
148     }
149     
150     /**
151      * save settings
152      * 
153      * @param array $_settings
154      * @return void
155      */
156     public function saveConfigSettings($_settings)
157     {
158         // only admins are allowed to do this
159         $this->checkRight(Tinebase_Acl_Rights::ADMIN);
160         
161         $appConfig = Tinebase_Config::getAppConfig($this->_applicationName);
162         
163         if ($appConfig !== NULL) {
164             $appConfig::getInstance()->set(Tinebase_Config::APPDEFAULTS, $_settings);
165         }
166     }
167     
168     /**
169      * returns the default model of this application
170      * @return string
171      */
172     public static function getDefaultModel()
173     {
174         return static::$_defaultModel;
175     }
176     
177     /**
178      * returns controller instance for given $_controllerName
179      * 
180      * @param string $_controllerName
181      * @return Tinebase_Controller
182      */
183     public static function getController($_controllerName)
184     {
185         if (! class_exists($_controllerName)) {
186             throw new Exception("Controller" . $_controllerName . "not found.");
187         }
188         
189         if (!in_array('Tinebase_Controller_Interface', class_implements($_controllerName))) {
190             throw new Exception("Controller $_controllerName does not implement Tinebase_Controller_Interface.");
191         }
192         
193         return call_user_func(array($_controllerName, 'getInstance'));
194     }
195 }