ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
CachedServer.php
Go to the documentation of this file.
1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
4
5// LICENSE AGREEMENT. If folded, press za here to unfold and read license {{{
6
40// }}}
41
42// dependencies {{{
43require_once('Cache/Lite.php');
44// }}}
45
57
58 // {{{ properties
59
65 private $_cacheByDefault = true;
66
72 private $_cacheObject = null;
73
79 private $_serverObject = null;
80
86 private $_defaultCacheGroup = 'xml_rpc2_server';
87
95 private $_callHandler = null;
96
102 private $_callTarget = '';
103
109 private $_prefix = '';
110
116 private $_options = array();
117
123 private $_cacheDebug = false;
124
130 private $_encoding = 'iso-8859-1';
131
132 // }}}
133 // {{{ setCacheOptions()
134
144 private function _setCacheOptions($array)
145 {
146 if (isset($array['defaultCacheGroup'])) {
147 $this->_defaultCacheGroup = $array['defaultCacheGroup'];
148 unset($array['defaultCacheGroup']); // this is a "non standard" option for Cache_Lite
149 }
150 if (isset($array['cacheByDefault'])) {
151 $this->_cacheByDefault = $array['cacheByDefault'];
152 unset($array['CacheByDefault']); // this is a "non standard" option for Cache_Lite
153 }
154 $array['automaticSerialization'] = false; // datas are already serialized in this class
155 if (!isset($array['lifetime'])) {
156 $array['lifetime'] = 3600; // we need a default lifetime
157 }
158 $this->_cacheOptions = $array;
159 $this->_cacheObject = new Cache_Lite($this->_cacheOptions);
160 }
161
162 // }}}
163 // {{{ constructor
164
170 protected function __construct($callTarget, $options = array())
171 {
172 if (isset($options['cacheOptions'])) {
173 $cacheOptions = $options['cacheOptions'];
174 $this->_setCacheOptions($cacheOptions);
175 unset($options['cacheOptions']);
176 }
177 if (isset($options['cacheDebug'])) {
178 $this->_cacheDebug = $options['cacheDebug'];
179 unset($options['cacheDebug']); // 'cacheDebug' is not a standard option for XML/RPC2/Server
180 }
181 $this->_options = $options;
182 $this->_callTarget = $callTarget;
183 if (isset($this->_options['encoding'])) {
184 $this->_encoding = $this->_options['encoding'];
185 }
186 if (isset($this->_options['prefix'])) {
187 $this->_prefix = $this->_options['prefix'];
188 }
189 }
190
191 // }}}
192 // {{{ create()
193
203 public static function create($callTarget, $options = array())
204 {
205 return new XML_RPC2_CachedServer($callTarget, $options);
206 }
207
208 // }}}
209 // {{{ handleCall()
210
215 public function handleCall()
216 {
217 $response = $this->getResponse();
218 $encoding = 'iso-8859-1';
219 if (isset($this->_options['encoding'])) {
220 $encoding = $this->_options['encoding'];
221 }
222 header('Content-type: text/xml; charset=' . $encoding);
223 header('Content-length: ' . $this->getContentLength($response));
224 print $response;
225 }
226
232 public function getResponse()
233 {
234 if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
235 $methodName = $this->_parseMethodName($GLOBALS['HTTP_RAW_POST_DATA']);
236 } else {
237 $methodName = null;
238 }
239 $weCache = $this->_cacheByDefault;
240 $lifetime = $this->_cacheOptions['lifetime'];
241 if ($this->_cacheDebug) {
242 if ($weCache) {
243 print "CACHE DEBUG : default values => weCache=true, lifetime=$lifetime\n";
244 } else {
245 print "CACHE DEBUG : default values => weCache=false, lifetime=$lifetime\n";
246 }
247 }
248 if ($methodName) {
249 // work on reflection API to search for @xmlrpc.caching tags into PHPDOC comments
250 list($weCache, $lifetime) = $this->_reflectionWork($methodName);
251 if ($this->_cacheDebug) {
252 if ($weCache) {
253 print "CACHE DEBUG : phpdoc comments => weCache=true, lifetime=$lifetime\n";
254 } else {
255 print "CACHE DEBUG : phpdoc comments => weCache=false, lifetime=$lifetime\n";
256 }
257 }
258 }
259 if (($weCache) and ($lifetime!=-1)) {
260 if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
261 $cacheId = $this->_makeCacheId($GLOBALS['HTTP_RAW_POST_DATA']);
262 } else {
263 $cacheId = 'norawpostdata';
264 }
265 $this->_cacheObject = new Cache_Lite($this->_cacheOptions);
266 $this->_cacheObject->setLifetime($lifetime);
267 if ($data = $this->_cacheObject->get($cacheId, $this->_defaultCacheGroup)) {
268 // cache id hit
269 if ($this->_cacheDebug) {
270 print "CACHE DEBUG : cache is hit !\n";
271 }
272 } else {
273 // cache is not hit
274 if ($this->_cacheDebug) {
275 print "CACHE DEBUG : cache is not hit !\n";
276 }
277 $data = $this->_workWithoutCache();
278 $this->_cacheObject->save($data);
279 }
280 } else {
281 if ($this->_cacheDebug) {
282 print "CACHE DEBUG : we don't cache !\n";
283 }
284 $data = $this->_workWithoutCache();
285 }
286 return $data;
287 }
288
289 // }}}
290 // {{{ _reflectionWork()
291
298 private function _reflectionWork($methodName) {
299 $weCache = $this->_cacheByDefault;
300 $lifetime = $this->_cacheOptions['lifetime'];
301 if (is_string($this->_callTarget)) {
302 $className = strtolower($this->_callTarget);
303 } else {
304 $className = get_class($this->_callTarget);
305 }
306 $class = new ReflectionClass($className);
307 $method = $class->getMethod($methodName);
308 $docs = explode("\n", $method->getDocComment());
309 foreach ($docs as $i => $doc) {
310 $doc = trim($doc, " \r\t/*");
311 $res = ereg('@xmlrpc.caching ([+-]{0,1}[a-zA-Z0-9]*)', $doc, $results); // TODO : better/faster regexp ?
312 if ($res>0) {
313 $value = $results[1];
314 if (($value=='yes') or ($value=='true') or ($value=='on')) {
315 $weCache = true;
316 } else if (($value=='no') or ($value=='false') or ($value=='off')) {
317 $weCache = false;
318 } else {
319 $lifetime = (int) $value;
320 if ($lifetime==-1) {
321 $weCache = false;
322 } else {
323 $weCache = true;
324 }
325 }
326 }
327 }
328 return array($weCache, $lifetime);
329 }
330
331 // }}}
332 // {{{ _parseMethodName()
333
342 private function _parseMethodName($request)
343 {
344 // TODO : change for "simplexml"
345 $res = ereg('<methodName>' . $this->_prefix . '([a-zA-Z0-9\.,\/]*)</methodName>', $request, $results);
346 if ($res>0) {
347 return $results[1];
348 }
349 return false;
350 }
351
352 // }}}
353 // {{{ _workWithoutCache()
354
360 private function _workWithoutCache()
361 {
362 require_once('XML/RPC2/Server.php');
363 $this->_serverObject = XML_RPC2_Server::create($this->_callTarget, $this->_options);
364 return $this->_serverObject->getResponse();
365 }
366
367 // }}}
368 // {{{ _makeCacheId()
369
376 private function _makeCacheId($raw_request)
377 {
378 return md5($raw_request . serialize($this->_options));
379 }
380
381 // }}}
382 // {{{ clean()
383
387 public function clean()
388 {
389 $this->_cacheObject->clean($this->_defaultCacheGroup, 'ingroup');
390 }
391
392 // }}}
393 // {{{ getContentLength()
394
402 protected function getContentLength($content)
403 {
404 if (extension_loaded('mbstring') && (ini_get('mbstring.func_overload') & 2) == 2) {
405 $length = mb_strlen($content, '8bit');
406 } else {
407 $length = strlen((binary)$content);
408 }
409
410 return $length;
411 }
412
413 // }}}
414}
415
416?>
handleCall()
handle XML_RPC calls
clean()
Clean all the cache.
_reflectionWork($methodName)
Work on reflection API to search for @xmlrpc.caching tags into PHPDOC comments.
getContentLength($content)
Gets the content legth of a serialized XML-RPC message in bytes.
__construct($callTarget, $options=array())
Constructor.
_makeCacheId($raw_request)
make a cache id depending on the raw xmlrpc client request but depending on "environnement" setting t...
_workWithoutCache()
Do the real stuff if no cache available.
static create($callTarget, $options=array())
"Emulated Factory" method to get the same API than XML_RPC2_Server class
getResponse()
get the XML response of the XMLRPC server
_setCacheOptions($array)
Set options for the caching process.
_parseMethodName($request)
Parse the method name from the raw XMLRPC client request.
static create($callTarget, $options=array())
Factory method to select a backend and return a new XML_RPC2_Server based on the backend.
Definition: Server.php:190
$data
$GLOBALS['PHPCAS_CLIENT']
This global variable is used by the interface class phpCAS.
Definition: CAS.php:276
if(! $in) print
$results
if(!is_array($argv)) $options