home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / XML / RPC2 / CachedServer.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  12.6 KB  |  395 lines

  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.  
  7. /**
  8. * +-----------------------------------------------------------------------------+
  9. * | Copyright (c) 2004 S├⌐rgio Gon├ºalves Carvalho                                |
  10. * +-----------------------------------------------------------------------------+
  11. * | This file is part of XML_RPC2.                                              |
  12. * |                                                                             |
  13. * | XML_RPC2 is free software; you can redistribute it and/or modify            |
  14. * | it under the terms of the GNU Lesser General Public License as published by |
  15. * | the Free Software Foundation; either version 2.1 of the License, or         |
  16. * | (at your option) any later version.                                         |
  17. * |                                                                             |
  18. * | XML_RPC2 is distributed in the hope that it will be useful,                 |
  19. * | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
  20. * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
  21. * | GNU Lesser General Public License for more details.                         |
  22. * |                                                                             |
  23. * | You should have received a copy of the GNU Lesser General Public License    |
  24. * | along with XML_RPC2; if not, write to the Free Software                     |
  25. * | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
  26. * | 02111-1307 USA                                                              |
  27. * +-----------------------------------------------------------------------------+
  28. * | Author: S├⌐rgio Carvalho <sergio.carvalho@portugalmail.com>                  |
  29. * +-----------------------------------------------------------------------------+
  30. *
  31. * @category   XML
  32. * @package    XML_RPC2
  33. * @author     Fabien MARTY <fab@php.net>  
  34. * @copyright  2005-2006 Fabien MARTY
  35. * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  36. * @version    CVS: $Id: CachedServer.php,v 1.5 2006/01/23 22:30:48 fab Exp $
  37. * @link       http://pear.php.net/package/XML_RPC2
  38. */
  39.  
  40. // }}}
  41.  
  42. // dependencies {{{
  43. require_once('Cache/Lite.php');
  44. // }}}
  45.  
  46. /**
  47.  * XML_RPC "cached server" class.
  48.  *
  49.  * @category   XML
  50.  * @package    XML_RPC2
  51.  * @author     Fabien MARTY <fab@php.net> 
  52.  * @copyright  2005-2006 Fabien MARTY
  53.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  54.  * @link       http://pear.php.net/package/XML_RPC2 
  55.  */
  56. class XML_RPC2_CachedServer {
  57.  
  58.     // {{{ properties
  59.       
  60.     /**
  61.      * cache by default 
  62.      *
  63.      * @var boolean
  64.      */
  65.     private $_cacheByDefault = true;
  66.     
  67.     /**
  68.      * Cache_Lite object
  69.      *
  70.      * @var object 
  71.      */
  72.     private $_cacheObject = null;
  73.     
  74.     /**
  75.      * XML_RPC2_Server object (if needed, dynamically built)
  76.      *
  77.      * @var object
  78.      */
  79.     private $_serverObject = null;
  80.     
  81.     /**
  82.      * Default cache group for XML_RPC server caching
  83.      *
  84.      * @var string
  85.      */
  86.     private $_defaultCacheGroup = 'xml_rpc2_server';
  87.     
  88.     /**
  89.      * callHandler field
  90.      *
  91.      * The call handler is responsible for executing the server exported methods
  92.      *
  93.      * @var mixed
  94.      */
  95.     private $_callHandler = null;
  96.     
  97.     /**
  98.      * either a class name or an object instance
  99.      *
  100.      * @var mixed
  101.      */
  102.     private $_callTarget = '';
  103.     
  104.     /**
  105.      * methods prefix
  106.      *
  107.      * @var string
  108.      */
  109.     private $_prefix = '';
  110.     
  111.     /**
  112.      * XML_RPC2_Server options
  113.      *
  114.      * @var array
  115.      */
  116.     private $_options = array();
  117.     
  118.     /**
  119.      * "cache debug" flag (for debugging the caching process)
  120.      * 
  121.      * @var boolean
  122.      */
  123.     private $_cacheDebug = false;
  124.         
  125.     /**
  126.      * encoding
  127.      * 
  128.      * @var string
  129.      */
  130.     private $_encoding = 'iso-8859-1';
  131.        
  132.     // }}}
  133.     // {{{ setCacheOptions()
  134.     
  135.     /**
  136.      * Set options for the caching process
  137.      *
  138.      * See Cache_Lite constructor for options
  139.      * Specific options are 'cachedMethods', 'notCachedMethods', 'cacheByDefault', 'defaultCacheGroup'
  140.      * See corresponding properties for more informations
  141.      *
  142.      * @param array $array
  143.      */
  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.     
  165.     /**
  166.      * Constructor
  167.      *
  168.      * @param object $callHandler the call handler will receive a method call for each remote call received. 
  169.      */
  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.     
  194.     /**
  195.      * "Emulated Factory" method to get the same API than XML_RPC2_Server class
  196.      *
  197.      * Here, simply returns a new instance of XML_RPC2_CachedServer class
  198.      *
  199.      * @param mixed $callTarget either a class name or an object instance. 
  200.      * @param array $options associative array of options
  201.      * @return object a server class instance
  202.      */
  203.     public static function create($callTarget, $options = array()) 
  204.     {
  205.         return new XML_RPC2_CachedServer($callTarget, $options);
  206.     }
  207.          
  208.     // }}}
  209.     // {{{ handleCall()
  210.     
  211.     /** 
  212.      * handle XML_RPC calls
  213.      *
  214.      */
  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: '.strlen($response));
  224.         print $response;
  225.     }
  226.     
  227.     /**
  228.      * get the XML response of the XMLRPC server
  229.      *
  230.      * @return string the XML response
  231.      */
  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.     
  292.     /**
  293.      * Work on reflection API to search for @xmlrpc.caching tags into PHPDOC comments
  294.      *
  295.      * @param string $methodName method name
  296.      * @return array array((boolean) weCache, (int) lifetime) => parameters to use for caching
  297.      */
  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.     
  334.     /**
  335.      * Parse the method name from the raw XMLRPC client request
  336.      *
  337.      * NB : the prefix is removed from the method name
  338.      *
  339.      * @param string $request raw XMLRPC client request
  340.      * @return string method name
  341.      */
  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.     
  355.     /**
  356.      * Do the real stuff if no cache available
  357.      * 
  358.      * @return string the response of the real XML/RPC2 server
  359.      */
  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.     
  370.     /** 
  371.      * make a cache id depending on the raw xmlrpc client request but depending on "environnement" setting too
  372.      *
  373.      * @param string $raw_request
  374.      * @return string cache id
  375.      */
  376.     private function _makeCacheId($raw_request) 
  377.     {
  378.         return md5($raw_request . serialize($this->_options));
  379.     }
  380.        
  381.     // }}}
  382.     // {{{ clean()
  383.     
  384.     /** 
  385.      * Clean all the cache
  386.      */
  387.     public function clean() 
  388.     {
  389.         $this->_cacheObject->clean($this->_defaultCacheGroup, 'ingroup');
  390.     }
  391.  
  392. }
  393.  
  394. ?>
  395.