adds in memory caching for model config methods
[tine20] / tine20 / Tinebase / Server / Abstract.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @subpackage  Server
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @copyright   Copyright (c) 2013-2014 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Philipp Schüle <p.schuele@metaways.de>
10  * 
11  */
12
13 /**
14  * Server Abstract with handle function
15  * 
16  * @package     Tinebase
17  * @subpackage  Server
18  */
19 abstract class Tinebase_Server_Abstract implements Tinebase_Server_Interface
20 {
21     /**
22      * the request
23      *
24      * @var \Zend\Http\PhpEnvironment\Request
25      */
26     protected $_request = NULL;
27     
28     /**
29      * the request body
30      * 
31      * @var stream|string
32      */
33     protected $_body;
34     
35     /**
36      * set to true if server supports sessions
37      * 
38      * @var boolean
39      */
40     protected $_supportsSessions = false;
41
42     /**
43      * cache for modelconfig methods by frontend
44      *
45      * @var array
46      */
47     protected static $_modelConfigMethods = array();
48
49     /**
50      * 
51      */
52     public function __construct()
53     {
54         if ($this->_supportsSessions) {
55             Tinebase_Session_Abstract::setSessionEnabled('TINE20SESSID');
56         }
57     }
58     
59     /**
60      * read auth data from all available sources
61      * 
62      * @param \Zend\Http\PhpEnvironment\Request $request
63      * @throws Tinebase_Exception_NotFound
64      * @return array
65      */
66     protected function _getAuthData(\Zend\Http\PhpEnvironment\Request $request)
67     {
68         if ($authData = $this->_getPHPAuthData($request)) {
69             return $authData;
70         }
71         
72         if ($authData = $this->_getBasicAuthData($request)) {
73             return $authData;
74         }
75         
76         throw new Tinebase_Exception_NotFound('No auth data found');
77     }
78     
79     /**
80      * fetch auch from PHP_AUTH*
81      * 
82      * @param  \Zend\Http\PhpEnvironment\Request  $request
83      * @return array
84      */
85     protected function _getPHPAuthData(\Zend\Http\PhpEnvironment\Request $request)
86     {
87         if ($request->getServer('PHP_AUTH_USER')) {
88             return array(
89                 $request->getServer('PHP_AUTH_USER'),
90                 $request->getServer('PHP_AUTH_PW')
91             );
92         }
93     }
94     
95     /**
96      * fetch basic auth credentials
97      * 
98      * @param  \Zend\Http\PhpEnvironment\Request  $request
99      * @return array
100      */
101     protected function _getBasicAuthData(\Zend\Http\PhpEnvironment\Request $request)
102     {
103         if ($header = $request->getHeaders('Authorization')) {
104             return explode(
105                 ":",
106                 base64_decode(substr($header->getFieldValue(), 6)),  // "Basic didhfiefdhfu4fjfjdsa34drsdfterrde..."
107                 2
108             );
109             
110         } elseif ($header = $request->getServer('HTTP_AUTHORIZATION')) {
111             return explode(
112                 ":",
113                 base64_decode(substr($header, 6)),  // "Basic didhfiefdhfu4fjfjdsa34drsdfterrde..."
114                 2
115             );
116             
117         } else {
118             // check if (REDIRECT_)*REMOTE_USER is found in SERVER vars
119             $name = 'REMOTE_USER';
120             
121             for ($i=0; $i<5; $i++) {
122                 if ($header = $request->getServer($name)) {
123                     return explode(
124                         ":",
125                         base64_decode(substr($header, 6)),  // "Basic didhfiefdhfu4fjfjdsa34drsdfterrde..."
126                         2
127                     );
128                 }
129                 
130                 $name = 'REDIRECT_' . $name;
131             }
132         }
133     }
134
135     /**
136      * get default modelconfig methods
137      *
138      * @param string $frontend
139      * @return array of Zend_Server_Method_Definition
140      */
141     protected static function _getModelConfigMethods($frontend)
142     {
143         if (array_key_exists($frontend, Tinebase_Server_Abstract::$_modelConfigMethods)) {
144             return Tinebase_Server_Abstract::$_modelConfigMethods[$frontend];
145         }
146
147         // get all apps user has RUN right for
148         try {
149             $userApplications = Tinebase_Core::getUser() ? Tinebase_Core::getUser()->getApplications() : array();
150         } catch (Tinebase_Exception_NotFound $tenf) {
151             // session might be invalid, destroy it
152             Tinebase_Session::destroyAndRemoveCookie();
153             $userApplications = array();
154         }
155
156         $definitions = array();
157         foreach ($userApplications as $application) {
158             try {
159                 $controller = Tinebase_Core::getApplicationInstance($application->name);
160                 $models = $controller->getModels();
161                 if (!$models) {
162                     continue;
163                 }
164             } catch (Exception $e) {
165                 Tinebase_Exception::log($e);
166                 continue;
167             }
168
169             foreach ($models as $model) {
170                 $config = $model::getConfiguration();
171                 if ($frontend::exposeApi($config)) {
172                     $simpleModelName = Tinebase_Record_Abstract::getSimpleModelName($application, $model);
173                     $commonApiMethods = $frontend::_getCommonApiMethods($application, $simpleModelName);
174
175                     foreach ($commonApiMethods as $name => $method) {
176                         $key = $application->name . '.' . $name . $simpleModelName . ($method['plural'] ? 's' : '');
177                         $object = $frontend::_getFrontend($application);
178
179                         $definitions[$key] = new Zend_Server_Method_Definition(array(
180                             'name'            => $key,
181                             'prototypes'      => array(array(
182                                 'returnType' => 'array',
183                                 'parameters' => $method['params']
184                             )),
185                             'methodHelp'      => $method['help'],
186                             'invokeArguments' => array(),
187                             'object'          => $object,
188                             'callback'        => array(
189                                 'type'   => 'instance',
190                                 'class'  => get_class($object),
191                                 'method' => $name . $simpleModelName . ($method['plural'] ? 's' : '')
192                             ),
193                         ));
194                     }
195                 }
196             }
197         }
198
199         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
200             . ' Got MC definitions: ' . print_r(array_keys($definitions), true));
201
202         Tinebase_Server_Abstract::$_modelConfigMethods[$frontend] = $definitions;
203
204         return $definitions;
205     }
206 }