[ Index ]

PHP Cross Reference of JPSpan 0.4 (beta)

title

Body

[close]

/JPSpan/Server/ -> PostOffice.php (source)

   1  <?php
   2  /**
   3  * @package JPSpan
   4  * @subpackage Server
   5  * @version $Id: PostOffice.php,v 1.11 2004/11/23 13:49:56 harryf Exp $
   6  */
   7  //--------------------------------------------------------------------------------
   8  /**
   9  * Define
  10  */
  11  if ( !defined('JPSPAN') ) {
  12      define ('JPSPAN',dirname(__FILE__).'/../');
  13  }
  14  /**
  15  * Include
  16  */
  17  require_once JPSPAN . 'Server.php';
  18  //--------------------------------------------------------------------------------
  19  
  20  /**
  21  * Class and method name passed in the URL with params passed
  22  * as url-encoded POST data. Urls like
  23  * http://localhost/server.php/Class/Method
  24  * @package JPSpan
  25  * @subpackage Server
  26  * @public
  27  */
  28  class JPSpan_Server_PostOffice extends JPSpan_Server {
  29  
  30      /**
  31      * Name of user defined handler that was called
  32      * @param string
  33      * @access private
  34      */
  35      var $calledClass = NULL;
  36      
  37      /**
  38      * Name of method in handler
  39      * @param string
  40      * @access private
  41      */
  42      var $calledMethod = NULL;
  43      
  44      /**
  45      * Request encoding to use (e.g. xml or php)
  46      * @var string
  47      * @access public
  48      */
  49      var $RequestEncoding = 'xml';
  50  
  51      /**
  52      * @access public
  53      */
  54      function JPSpan_Server_PostOffice() {
  55          parent::JPSpan_Server();
  56      }
  57      
  58      /**
  59      * Serve a request
  60      * @param boolean send headers
  61      * @return boolean FALSE if failed (invalid request - see errors)
  62      * @access public
  63      */
  64      function serve($sendHeaders = TRUE) {
  65          require_once JPSPAN . 'Monitor.php';
  66          $M = & JPSpan_Monitor::instance();
  67          
  68          $this->calledClass = NULL;
  69          $this->calledMethod = NULL;
  70          
  71          if ( $this->resolveCall() ) {
  72          
  73              $M->setRequestInfo('class',$this->calledClass);
  74              $M->setRequestInfo('method',$this->calledMethod);
  75              
  76              if ( FALSE !== ($Handler = & $this->getHandler($this->calledClass) ) ) {
  77              
  78                  $args = array();
  79                  $M->setRequestInfo('args',$args);
  80                  
  81                  if ( $this->getArgs($args) ) {
  82                  
  83                      $M->setRequestInfo('args',$args);
  84                      
  85                      $response = call_user_func_array(
  86                          array(
  87                              & $Handler,
  88                              $this->calledMethod
  89                          ),
  90                          $args
  91                      );
  92                      
  93                  } else {
  94                  
  95                      $response = call_user_func(
  96                          array(
  97                              & $Handler,
  98                              $this->calledMethod
  99                          )
 100                      );
 101                      
 102                  }
 103                  
 104                  require_once JPSPAN . 'Serializer.php';
 105  
 106                  $M->setResponseInfo('payload',$response);
 107                  $M->announceSuccess();
 108                  
 109                  $response = JPSpan_Serializer::serialize($response);
 110                  
 111                  if ( $sendHeaders ) {
 112                      header('Content-Length: '.strlen($response));
 113                      header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); 
 114                      header('Last-Modified: ' . gmdate( "D, d M Y H:i:s" ) . 'GMT'); 
 115                      header('Cache-Control: no-cache, must-revalidate'); 
 116                      header('Pragma: no-cache');
 117                  }
 118                  echo $response;
 119  
 120                  return TRUE;
 121                  
 122              } else {
 123              
 124                  trigger_error('Invalid handle for: '.$this->calledClass,E_USER_ERROR);
 125                  return FALSE;
 126                  
 127              }
 128              
 129          }
 130          return FALSE;
 131      }
 132  
 133      /**
 134      * Resolve the call - identify the handler class and method and store
 135      * locally
 136      * @return boolean FALSE if failed (invalid request - see errors)
 137      * @access private
 138      */
 139      function resolveCall() {
 140          $uriPath = explode('/',JPSpan_Server::getUriPath());
 141          
 142          if ( count($uriPath) != 2 ) {
 143              trigger_error('Invalid call syntax',E_USER_ERROR);
 144              return FALSE;
 145          }
 146          
 147          if ( preg_match('/^[a-z]+[0-9a-z_]*$/',$uriPath[0]) != 1 ) {
 148              trigger_error('Invalid handler name: '.$uriPath[0],E_USER_ERROR);
 149              return FALSE;
 150          }
 151          
 152          if ( preg_match('/^[a-z]+[0-9a-z_]*$/',$uriPath[1]) != 1 ) {
 153              trigger_error('Invalid handler method: '.$uriPath[1],E_USER_ERROR);
 154              return FALSE;
 155          }
 156          
 157          if ( !array_key_exists($uriPath[0],$this->descriptions) ) {
 158              trigger_error('Unknown handler: '.$uriPath[0],E_USER_ERROR);
 159              return FALSE;
 160          }
 161          
 162          if ( !in_array($uriPath[1],$this->descriptions[$uriPath[0]]->methods) ) {
 163              trigger_error('Unknown handler method: '.$uriPath[1],E_USER_ERROR);
 164              return FALSE;
 165          }
 166          
 167          $this->calledClass = $uriPath[0];
 168          $this->calledMethod = $uriPath[1];
 169          
 170          return TRUE;
 171          
 172      }
 173      
 174      /**
 175      * Populate the args array if there are any
 176      * @param array args (reference)
 177      * @return boolean TRUE if request had args
 178      * @access private
 179      */
 180      function getArgs(& $args) {
 181          require_once JPSPAN . 'RequestData.php';
 182          
 183          if ( $this->RequestEncoding == 'php' ) {
 184              $args = JPSpan_RequestData_Post::fetch($this->RequestEncoding);
 185          } else {
 186              $args = JPSpan_RequestData_RawPost::fetch($this->RequestEncoding);
 187          }
 188          
 189          if ( is_array($args) ) {
 190              return TRUE;
 191          }
 192          
 193          return FALSE;
 194      }
 195      
 196      /**
 197      * Get the Javascript client generator
 198      * @return JPSpan_Generator
 199      * @access public
 200      */
 201      function & getGenerator() {
 202          require_once JPSPAN . 'Generator.php';
 203          $G = & new JPSpan_Generator();
 204          $G->init(
 205              new JPSpan_PostOffice_Generator(),
 206              $this->descriptions,
 207              $this->serverUrl,
 208              $this->RequestEncoding
 209              );
 210          return $G;
 211      }
 212  }
 213  
 214  //--------------------------------------------------------------------------------
 215  /**
 216  * Generator for the JPSpan_Server_PostOffice
 217  * @todo Much refactoring need to make code generation "pluggable"
 218  * @see JPSpan_Server_PostOffice
 219  * @package JPSpan
 220  * @subpackage Server
 221  * @access public
 222  */
 223  class JPSpan_PostOffice_Generator {
 224  
 225      /**
 226      * @var array list of JPSpan_HandleDescription objects
 227      * @access public
 228      */
 229      var $descriptions;
 230      
 231      /**
 232      * @var string URL or server
 233      * @access public
 234      */
 235      var $serverUrl;
 236      
 237      /**
 238      * How requests should be encoded
 239      * @var string request encoding
 240      * @access public
 241      */
 242      var $RequestEncoding;
 243      
 244      /**
 245      * Invokes code generator
 246      * @param JPSpan_CodeWriter
 247      * @return void
 248      * @access public
 249      */
 250      function generate(& $Code) {
 251  
 252          $this->generateScriptHeader($Code);
 253          foreach ( array_keys($this->descriptions) as $key ) {
 254              $this->generateHandleClient($Code, $this->descriptions[$key]);
 255          }
 256      }
 257      
 258      /**
 259      * Generate the starting includes section of the script
 260      * @param JPSpan_CodeWriter
 261      * @return void
 262      * @access private
 263      */
 264      function generateScriptHeader(& $Code) {
 265          ob_start();
 266  ?>
 267  /**@
 268  * include 'remoteobject.js';
 269  <?php
 270  if ( $this->RequestEncoding == 'xml' ) {
 271  ?>
 272  * include 'request/rawpost.js';
 273  * include 'encode/xml.js';
 274  <?php
 275  } else {
 276  ?>
 277  * include 'request/post.js';
 278  * include 'encode/php.js';
 279  <?php
 280  }
 281  ?>
 282  */
 283  <?php
 284          $Code->append(ob_get_contents());
 285          ob_end_clean();
 286      }
 287      
 288      /**
 289      * Generate code for a single description (a single PHP class)
 290      * @param JPSpan_CodeWriter
 291      * @param JPSpan_HandleDescription
 292      * @return void
 293      * @access private
 294      */
 295      function generateHandleClient(& $Code, & $Description) {
 296          ob_start();
 297  ?>
 298  
 299  function <?php echo $Description->Class; ?>() {
 300      
 301      var oParent = new JPSpan_RemoteObject();
 302      
 303      if ( arguments[0] ) {
 304          oParent.Async(arguments[0]);
 305      }
 306      
 307      oParent.__serverurl = '<?php 
 308          echo $this->serverUrl . '/' . $Description->Class; ?>';
 309      
 310      oParent.__remoteClass = '<?php echo $Description->Class; ?>';
 311      
 312  <?php
 313  if ( $this->RequestEncoding == 'xml' ) {
 314  ?>
 315      oParent.__request = new JPSpan_Request_RawPost(new JPSpan_Encode_Xml());
 316  <?php
 317  } else {
 318  ?>
 319      oParent.__request = new JPSpan_Request_Post(new JPSpan_Encode_PHP());
 320  <?php
 321  }
 322  
 323  foreach ( $Description->methods as $method ) {
 324  ?>
 325      
 326      // @access public
 327      oParent.<?php echo $method; ?> = function() {
 328          var url = this.__serverurl+'/<?php echo $method; ?>/';
 329          return this.__call(url,arguments,'<?php echo $method; ?>');
 330      };
 331  <?php
 332  }
 333  ?>
 334      
 335      return oParent;
 336  }
 337  
 338  <?php
 339          $Code->append(ob_get_contents());
 340          ob_end_clean();
 341      }
 342  }
 343  
 344  


Generated: Fri Nov 26 11:42:46 2004 Cross-referenced by PHPXref 0.6