[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/Amf/ -> Server.php (source)

   1  <?php
   2  /**
   3   * Zend Framework
   4   *
   5   * LICENSE
   6   *
   7   * This source file is subject to the new BSD license that is bundled
   8   * with this package in the file LICENSE.txt.
   9   * It is also available through the world-wide-web at this URL:
  10   * http://framework.zend.com/license/new-bsd
  11   * If you did not receive a copy of the license and are unable to
  12   * obtain it through the world-wide-web, please send an email
  13   * to [email protected] so we can send you a copy immediately.
  14   *
  15   * @category   Zend
  16   * @package    Zend_Amf
  17   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  19   * @version    $Id$
  20   */
  21  
  22  /** @see Zend_Server_Interface */
  23  require_once 'Zend/Server/Interface.php';
  24  
  25  /** @see Zend_Server_Reflection */
  26  require_once 'Zend/Server/Reflection.php';
  27  
  28  /** @see Zend_Amf_Constants */
  29  require_once 'Zend/Amf/Constants.php';
  30  
  31  /** @see Zend_Amf_Value_MessageBody */
  32  require_once 'Zend/Amf/Value/MessageBody.php';
  33  
  34  /** @see Zend_Amf_Value_MessageHeader */
  35  require_once 'Zend/Amf/Value/MessageHeader.php';
  36  
  37  /** @see Zend_Amf_Value_Messaging_CommandMessage */
  38  require_once 'Zend/Amf/Value/Messaging/CommandMessage.php';
  39  
  40  /** @see Zend_Loader_PluginLoader */
  41  require_once 'Zend/Loader/PluginLoader.php';
  42  
  43  /** @see Zend_Amf_Parse_TypeLoader */
  44  require_once 'Zend/Amf/Parse/TypeLoader.php';
  45  
  46  /** @see Zend_Auth */
  47  require_once 'Zend/Auth.php';
  48  /**
  49   * An AMF gateway server implementation to allow the connection of the Adobe Flash Player to
  50   * Zend Framework
  51   *
  52   * @todo       Make the reflection methods cache and autoload.
  53   * @package    Zend_Amf
  54   * @subpackage Server
  55   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  56   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  57   */
  58  class Zend_Amf_Server implements Zend_Server_Interface
  59  {
  60      /**
  61       * Array of dispatchables
  62       * @var array
  63       */
  64      protected $_methods = array();
  65  
  66      /**
  67       * Array of classes that can be called without being explicitly loaded
  68       *
  69       * Keys are class names.
  70       *
  71       * @var array
  72       */
  73      protected $_classAllowed = array();
  74  
  75      /**
  76       * Loader for classes in added directories
  77       * @var Zend_Loader_PluginLoader
  78       */
  79      protected $_loader;
  80  
  81      /**
  82       * @var bool Production flag; whether or not to return exception messages
  83       */
  84      protected $_production = true;
  85  
  86      /**
  87       * Request processed
  88       * @var null|Zend_Amf_Request
  89       */
  90      protected $_request = null;
  91  
  92      /**
  93       * Class to use for responses
  94       * @var null|Zend_Amf_Response
  95       */
  96      protected $_response;
  97  
  98      /**
  99       * Dispatch table of name => method pairs
 100       * @var array
 101       */
 102      protected $_table = array();
 103  
 104      /**
 105       *
 106       * @var bool session flag; whether or not to add a session to each response.
 107       */
 108      protected $_session = false;
 109  
 110      /**
 111       * Namespace allows all AMF calls to not clobber other php session variables
 112       * @var Zend_Session_NameSpace default session namespace zend_amf
 113       */
 114      protected $_sesionNamespace = 'zend_amf';
 115  
 116      /**
 117       * Set the default session.name if php_
 118       * @var string
 119       */
 120      protected $_sessionName = 'PHPSESSID';
 121  
 122      /**
 123       * Authentication handler object
 124       *
 125       * @var Zend_Amf_Auth_Abstract
 126       */
 127      protected $_auth;
 128      /**
 129       * ACL handler object
 130       *
 131       * @var Zend_Acl
 132       */
 133      protected $_acl;
 134      /**
 135       * The server constructor
 136       */
 137      public function __construct()
 138      {
 139          Zend_Amf_Parse_TypeLoader::setResourceLoader(new Zend_Loader_PluginLoader(array("Zend_Amf_Parse_Resource" => "Zend/Amf/Parse/Resource")));
 140      }
 141  
 142      /**
 143       * Set authentication adapter
 144       *
 145       * @param  Zend_Amf_Auth_Abstract $auth
 146       * @return Zend_Amf_Server
 147       */
 148      public function setAuth(Zend_Amf_Auth_Abstract $auth)
 149      {
 150          $this->_auth = $auth;
 151          return $this;
 152      }
 153     /**
 154       * Get authentication adapter
 155       *
 156       * @return Zend_Amf_Auth_Abstract
 157       */
 158      public function getAuth()
 159      {
 160          return $this->_auth;
 161      }
 162  
 163      /**
 164       * Set ACL adapter
 165       *
 166       * @param  Zend_Acl $acl
 167       * @return Zend_Amf_Server
 168       */
 169      public function setAcl(Zend_Acl $acl)
 170      {
 171          $this->_acl = $acl;
 172          return $this;
 173      }
 174     /**
 175       * Get ACL adapter
 176       *
 177       * @return Zend_Acl
 178       */
 179      public function getAcl()
 180      {
 181          return $this->_acl;
 182      }
 183  
 184      /**
 185       * Set production flag
 186       *
 187       * @param  bool $flag
 188       * @return Zend_Amf_Server
 189       */
 190      public function setProduction($flag)
 191      {
 192          $this->_production = (bool) $flag;
 193          return $this;
 194      }
 195  
 196      /**
 197       * Whether or not the server is in production
 198       *
 199       * @return bool
 200       */
 201      public function isProduction()
 202      {
 203          return $this->_production;
 204      }
 205  
 206      /**
 207       * @param namespace of all incoming sessions defaults to Zend_Amf
 208       * @return Zend_Amf_Server
 209       */
 210      public function setSession($namespace = 'Zend_Amf')
 211      {
 212          require_once 'Zend/Session.php';
 213          $this->_session = true;
 214          $this->_sesionNamespace = new Zend_Session_Namespace($namespace);
 215          return $this;
 216      }
 217  
 218      /**
 219       * Whether of not the server is using sessions
 220       * @return bool
 221       */
 222      public function isSession()
 223      {
 224          return $this->_session;
 225      }
 226  
 227      /**
 228       * Check if the ACL allows accessing the function or method
 229       *
 230       * @param string|object $object Object or class being accessed
 231       * @param string $function Function or method being accessed
 232       * @return unknown_type
 233       */
 234      protected function _checkAcl($object, $function)
 235      {
 236          if(!$this->_acl) {
 237              return true;
 238          }
 239          if($object) {
 240              $class = is_object($object)?get_class($object):$object;
 241              if(!$this->_acl->has($class)) {
 242                  require_once 'Zend/Acl/Resource.php';
 243                  $this->_acl->add(new Zend_Acl_Resource($class));
 244              }
 245              $call = array($object, "initAcl");
 246              if(is_callable($call) && !call_user_func($call, $this->_acl)) {
 247                  // if initAcl returns false, no ACL check
 248                  return true;
 249              }
 250          } else {
 251              $class = null;
 252          }
 253  
 254          $auth = Zend_Auth::getInstance();
 255          if($auth->hasIdentity()) {
 256              $role = $auth->getIdentity()->role;
 257          } else {
 258              if($this->_acl->hasRole(Zend_Amf_Constants::GUEST_ROLE)) {
 259                  $role = Zend_Amf_Constants::GUEST_ROLE;
 260              } else {
 261                  require_once 'Zend/Amf/Server/Exception.php';
 262                  throw new Zend_Amf_Server_Exception("Unauthenticated access not allowed");
 263              }
 264          }
 265          if($this->_acl->isAllowed($role, $class, $function)) {
 266              return true;
 267          } else {
 268              require_once 'Zend/Amf/Server/Exception.php';
 269              throw new Zend_Amf_Server_Exception("Access not allowed");
 270          }
 271      }
 272  
 273      /**
 274       * Get PluginLoader for the Server
 275       *
 276       * @return Zend_Loader_PluginLoader
 277       */
 278      protected function getLoader()
 279      {
 280          if(empty($this->_loader)) {
 281              require_once 'Zend/Loader/PluginLoader.php';
 282              $this->_loader = new Zend_Loader_PluginLoader();
 283          }
 284          return $this->_loader;
 285      }
 286  
 287      /**
 288       * Loads a remote class or method and executes the function and returns
 289       * the result
 290       *
 291       * @param  string $method Is the method to execute
 292       * @param  mixed $param values for the method
 293       * @return mixed $response the result of executing the method
 294       * @throws Zend_Amf_Server_Exception
 295       */
 296      protected function _dispatch($method, $params = null, $source = null)
 297      {
 298          if($source) {
 299              if(($mapped = Zend_Amf_Parse_TypeLoader::getMappedClassName($source)) !== false) {
 300                  $source = $mapped;
 301              }
 302          }
 303          $qualifiedName = empty($source) ? $method : $source.".".$method;
 304  
 305          if (!isset($this->_table[$qualifiedName])) {
 306              // if source is null a method that was not defined was called.
 307              if ($source) {
 308                  $className = str_replace(".", "_", $source);
 309                  if(class_exists($className, false) && !isset($this->_classAllowed[$className])) {
 310                      require_once 'Zend/Amf/Server/Exception.php';
 311                      throw new Zend_Amf_Server_Exception('Can not call "' . $className . '" - use setClass()');
 312                  }
 313                  try {
 314                      $this->getLoader()->load($className);
 315                  } catch (Exception $e) {
 316                      require_once 'Zend/Amf/Server/Exception.php';
 317                      throw new Zend_Amf_Server_Exception('Class "' . $className . '" does not exist: '.$e->getMessage(), 0, $e);
 318                  }
 319                  // Add the new loaded class to the server.
 320                  $this->setClass($className, $source);
 321              } else {
 322                  require_once 'Zend/Amf/Server/Exception.php';
 323                  throw new Zend_Amf_Server_Exception('Method "' . $method . '" does not exist');
 324              }
 325          }
 326  
 327          $info = $this->_table[$qualifiedName];
 328          $argv = $info->getInvokeArguments();
 329  
 330          if (0 < count($argv)) {
 331              $params = array_merge($params, $argv);
 332          }
 333  
 334          if ($info instanceof Zend_Server_Reflection_Function) {
 335              $func = $info->getName();
 336              $this->_checkAcl(null, $func);
 337              $return = call_user_func_array($func, $params);
 338          } elseif ($info instanceof Zend_Server_Reflection_Method) {
 339              // Get class
 340              $class = $info->getDeclaringClass()->getName();
 341              if ('static' == $info->isStatic()) {
 342                  // for some reason, invokeArgs() does not work the same as
 343                  // invoke(), and expects the first argument to be an object.
 344                  // So, using a callback if the method is static.
 345                  $this->_checkAcl($class, $info->getName());
 346                  $return = call_user_func_array(array($class, $info->getName()), $params);
 347              } else {
 348                  // Object methods
 349                  try {
 350                      $object = $info->getDeclaringClass()->newInstance();
 351                  } catch (Exception $e) {
 352                      require_once 'Zend/Amf/Server/Exception.php';
 353                      throw new Zend_Amf_Server_Exception('Error instantiating class ' . $class . ' to invoke method ' . $info->getName() . ': '.$e->getMessage(), 621, $e);
 354                  }
 355                  $this->_checkAcl($object, $info->getName());
 356                  $return = $info->invokeArgs($object, $params);
 357              }
 358          } else {
 359              require_once 'Zend/Amf/Server/Exception.php';
 360              throw new Zend_Amf_Server_Exception('Method missing implementation ' . get_class($info));
 361          }
 362  
 363          return $return;
 364      }
 365  
 366      /**
 367       * Handles each of the 11 different command message types.
 368       *
 369       * A command message is a flex.messaging.messages.CommandMessage
 370       *
 371       * @see    Zend_Amf_Value_Messaging_CommandMessage
 372       * @param  Zend_Amf_Value_Messaging_CommandMessage $message
 373       * @return Zend_Amf_Value_Messaging_AcknowledgeMessage
 374       */
 375      protected function _loadCommandMessage(Zend_Amf_Value_Messaging_CommandMessage $message)
 376      {
 377          require_once 'Zend/Amf/Value/Messaging/AcknowledgeMessage.php';
 378          switch($message->operation) {
 379              case Zend_Amf_Value_Messaging_CommandMessage::DISCONNECT_OPERATION :
 380              case Zend_Amf_Value_Messaging_CommandMessage::CLIENT_PING_OPERATION :
 381                  $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message);
 382                  break;
 383              case Zend_Amf_Value_Messaging_CommandMessage::LOGIN_OPERATION :
 384                  $data = explode(':', base64_decode($message->body));
 385                  $userid = $data[0];
 386                  $password = isset($data[1])?$data[1]:"";
 387                  if(empty($userid)) {
 388                      require_once 'Zend/Amf/Server/Exception.php';
 389                      throw new Zend_Amf_Server_Exception('Login failed: username not supplied');
 390                  }
 391                  if(!$this->_handleAuth($userid, $password)) {
 392                      require_once 'Zend/Amf/Server/Exception.php';
 393                      throw new Zend_Amf_Server_Exception('Authentication failed');
 394                  }
 395                  $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message);
 396                  break;
 397             case Zend_Amf_Value_Messaging_CommandMessage::LOGOUT_OPERATION :
 398                  if($this->_auth) {
 399                      Zend_Auth::getInstance()->clearIdentity();
 400                  }
 401                  $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message);
 402                  break;
 403              default :
 404                  require_once 'Zend/Amf/Server/Exception.php';
 405                  throw new Zend_Amf_Server_Exception('CommandMessage::' . $message->operation . ' not implemented');
 406                  break;
 407          }
 408          return $return;
 409      }
 410  
 411      /**
 412       * Create appropriate error message
 413       *
 414       * @param int $objectEncoding Current AMF encoding
 415       * @param string $message Message that was being processed when error happened
 416       * @param string $description Error description
 417       * @param mixed $detail Detailed data about the error
 418       * @param int $code Error code
 419       * @param int $line Error line
 420       * @return Zend_Amf_Value_Messaging_ErrorMessage|array
 421       */
 422      protected function _errorMessage($objectEncoding, $message, $description, $detail, $code, $line)
 423      {
 424          $return = null;
 425          switch ($objectEncoding) {
 426              case Zend_Amf_Constants::AMF0_OBJECT_ENCODING :
 427                  return array (
 428                          'description' => ($this->isProduction ()) ? '' : $description,
 429                          'detail' => ($this->isProduction ()) ? '' : $detail,
 430                          'line' => ($this->isProduction ()) ? 0 : $line,
 431                          'code' => $code
 432                  );
 433              case Zend_Amf_Constants::AMF3_OBJECT_ENCODING :
 434                  require_once 'Zend/Amf/Value/Messaging/ErrorMessage.php';
 435                  $return = new Zend_Amf_Value_Messaging_ErrorMessage ( $message );
 436                  $return->faultString = $this->isProduction () ? '' : $description;
 437                  $return->faultCode = $code;
 438                  $return->faultDetail = $this->isProduction () ? '' : $detail;
 439                  break;
 440          }
 441          return $return;
 442      }
 443  
 444      /**
 445       * Handle AMF authentication
 446       *
 447       * @param string $userid
 448       * @param string $password
 449       * @return boolean
 450       */
 451      protected function _handleAuth( $userid,  $password)
 452      {
 453          if (!$this->_auth) {
 454              return true;
 455          }
 456          $this->_auth->setCredentials($userid, $password);
 457          $auth = Zend_Auth::getInstance();
 458          $result = $auth->authenticate($this->_auth);
 459          if ($result->isValid()) {
 460              if (!$this->isSession()) {
 461                  $this->setSession();
 462              }
 463              return true;
 464          } else {
 465              // authentication failed, good bye
 466              require_once 'Zend/Amf/Server/Exception.php';
 467              throw new Zend_Amf_Server_Exception(
 468                  "Authentication failed: " . join("\n",
 469                      $result->getMessages()), $result->getCode());
 470          }
 471  
 472      }
 473  
 474      /**
 475       * Takes the deserialized AMF request and performs any operations.
 476       *
 477       * @todo   should implement and SPL observer pattern for custom AMF headers
 478       * @todo   DescribeService support
 479       * @param  Zend_Amf_Request $request
 480       * @return Zend_Amf_Response
 481       * @throws Zend_Amf_server_Exception|Exception
 482       */
 483      protected function _handle(Zend_Amf_Request $request)
 484      {
 485          // Get the object encoding of the request.
 486          $objectEncoding = $request->getObjectEncoding();
 487  
 488          // create a response object to place the output from the services.
 489          $response = $this->getResponse();
 490  
 491          // set response encoding
 492          $response->setObjectEncoding($objectEncoding);
 493  
 494          $responseBody = $request->getAmfBodies();
 495  
 496          $handleAuth = false;
 497          if ($this->_auth) {
 498              $headers = $request->getAmfHeaders();
 499              if (isset($headers[Zend_Amf_Constants::CREDENTIALS_HEADER]) &&
 500                  isset($headers[Zend_Amf_Constants::CREDENTIALS_HEADER]->userid)) {
 501                  $handleAuth = true;
 502              }
 503          }
 504  
 505          // Iterate through each of the service calls in the AMF request
 506          foreach($responseBody as $body)
 507          {
 508              try {
 509                  if ($handleAuth) {
 510                      if ($this->_handleAuth(
 511                          $headers[Zend_Amf_Constants::CREDENTIALS_HEADER]->userid,
 512                          $headers[Zend_Amf_Constants::CREDENTIALS_HEADER]->password)) {
 513                          // use RequestPersistentHeader to clear credentials
 514                          $response->addAmfHeader(
 515                              new Zend_Amf_Value_MessageHeader(
 516                                  Zend_Amf_Constants::PERSISTENT_HEADER,
 517                                  false,
 518                                  new Zend_Amf_Value_MessageHeader(
 519                                      Zend_Amf_Constants::CREDENTIALS_HEADER,
 520                                      false, null)));
 521                          $handleAuth = false;
 522                      }
 523                  }
 524  
 525                  if ($objectEncoding == Zend_Amf_Constants::AMF0_OBJECT_ENCODING) {
 526                      // AMF0 Object Encoding
 527                      $targetURI = $body->getTargetURI();
 528                      $message = '';
 529  
 530                      // Split the target string into its values.
 531                      $source = substr($targetURI, 0, strrpos($targetURI, '.'));
 532  
 533                      if ($source) {
 534                          // Break off method name from namespace into source
 535                          $method = substr(strrchr($targetURI, '.'), 1);
 536                          $return = $this->_dispatch($method, $body->getData(), $source);
 537                      } else {
 538                          // Just have a method name.
 539                          $return = $this->_dispatch($targetURI, $body->getData());
 540                      }
 541                  } else {
 542                      // AMF3 read message type
 543                      $message = $body->getData();
 544                      if ($message instanceof Zend_Amf_Value_Messaging_CommandMessage) {
 545                          // async call with command message
 546                          $return = $this->_loadCommandMessage($message);
 547                      } elseif ($message instanceof Zend_Amf_Value_Messaging_RemotingMessage) {
 548                          require_once 'Zend/Amf/Value/Messaging/AcknowledgeMessage.php';
 549                          $return = new Zend_Amf_Value_Messaging_AcknowledgeMessage($message);
 550                          $return->body = $this->_dispatch($message->operation, $message->body, $message->source);
 551                      } else {
 552                          // Amf3 message sent with netConnection
 553                          $targetURI = $body->getTargetURI();
 554  
 555                          // Split the target string into its values.
 556                          $source = substr($targetURI, 0, strrpos($targetURI, '.'));
 557  
 558                          if ($source) {
 559                              // Break off method name from namespace into source
 560                              $method = substr(strrchr($targetURI, '.'), 1);
 561                              $return = $this->_dispatch($method, $body->getData(), $source);
 562                          } else {
 563                              // Just have a method name.
 564                              $return = $this->_dispatch($targetURI, $body->getData());
 565                          }
 566                      }
 567                  }
 568                  $responseType = Zend_AMF_Constants::RESULT_METHOD;
 569              } catch (Exception $e) {
 570                  $return = $this->_errorMessage($objectEncoding, $message,
 571                      $e->getMessage(), $e->getTraceAsString(),$e->getCode(),  $e->getLine());
 572                  $responseType = Zend_AMF_Constants::STATUS_METHOD;
 573              }
 574  
 575              $responseURI = $body->getResponseURI() . $responseType;
 576              $newBody     = new Zend_Amf_Value_MessageBody($responseURI, null, $return);
 577              $response->addAmfBody($newBody);
 578          }
 579          // Add a session header to the body if session is requested.
 580          if($this->isSession()) {
 581             $currentID = session_id();
 582             $joint = "?";
 583             if(isset($_SERVER['QUERY_STRING'])) {
 584                 if(!strpos($_SERVER['QUERY_STRING'], $currentID) !== FALSE) {
 585                     if(strrpos($_SERVER['QUERY_STRING'], "?") !== FALSE) {
 586                         $joint = "&";
 587                     }
 588                 }
 589             }
 590  
 591              // create a new AMF message header with the session id as a variable.
 592              $sessionValue = $joint . $this->_sessionName . "=" . $currentID;
 593              $sessionHeader = new Zend_Amf_Value_MessageHeader(Zend_Amf_Constants::URL_APPEND_HEADER, false, $sessionValue);
 594              $response->addAmfHeader($sessionHeader);
 595          }
 596  
 597          // serialize the response and return serialized body.
 598          $response->finalize();
 599      }
 600  
 601      /**
 602       * Handle an AMF call from the gateway.
 603       *
 604       * @param  null|Zend_Amf_Request $request Optional
 605       * @return Zend_Amf_Response
 606       */
 607      public function handle($request = null)
 608      {
 609          // Check if request was passed otherwise get it from the server
 610          if (is_null($request) || !$request instanceof Zend_Amf_Request) {
 611              $request = $this->getRequest();
 612          } else {
 613              $this->setRequest($request);
 614          }
 615          if ($this->isSession()) {
 616               // Check if a session is being sent from the amf call
 617               if (isset($_COOKIE[$this->_sessionName])) {
 618                   session_id($_COOKIE[$this->_sessionName]);
 619               }
 620          }
 621  
 622          // Check for errors that may have happend in deserialization of Request.
 623          try {
 624              // Take converted PHP objects and handle service call.
 625              // Serialize to Zend_Amf_response for output stream
 626              $this->_handle($request);
 627              $response = $this->getResponse();
 628          } catch (Exception $e) {
 629              // Handle any errors in the serialization and service  calls.
 630              require_once 'Zend/Amf/Server/Exception.php';
 631              throw new Zend_Amf_Server_Exception('Handle error: ' . $e->getMessage() . ' ' . $e->getLine(), 0, $e);
 632          }
 633  
 634          // Return the Amf serialized output string
 635          return $response;
 636      }
 637  
 638      /**
 639       * Set request object
 640       *
 641       * @param  string|Zend_Amf_Request $request
 642       * @return Zend_Amf_Server
 643       */
 644      public function setRequest($request)
 645      {
 646          if (is_string($request) && class_exists($request)) {
 647              $request = new $request();
 648              if (!$request instanceof Zend_Amf_Request) {
 649                  require_once 'Zend/Amf/Server/Exception.php';
 650                  throw new Zend_Amf_Server_Exception('Invalid request class');
 651              }
 652          } elseif (!$request instanceof Zend_Amf_Request) {
 653              require_once 'Zend/Amf/Server/Exception.php';
 654              throw new Zend_Amf_Server_Exception('Invalid request object');
 655          }
 656          $this->_request = $request;
 657          return $this;
 658      }
 659  
 660      /**
 661       * Return currently registered request object
 662       *
 663       * @return null|Zend_Amf_Request
 664       */
 665      public function getRequest()
 666      {
 667          if (null === $this->_request) {
 668              require_once 'Zend/Amf/Request/Http.php';
 669              $this->setRequest(new Zend_Amf_Request_Http());
 670          }
 671  
 672          return $this->_request;
 673      }
 674  
 675      /**
 676       * Public access method to private Zend_Amf_Server_Response reference
 677       *
 678       * @param  string|Zend_Amf_Server_Response $response
 679       * @return Zend_Amf_Server
 680       */
 681      public function setResponse($response)
 682      {
 683          if (is_string($response) && class_exists($response)) {
 684              $response = new $response();
 685              if (!$response instanceof Zend_Amf_Response) {
 686                  require_once 'Zend/Amf/Server/Exception.php';
 687                  throw new Zend_Amf_Server_Exception('Invalid response class');
 688              }
 689          } elseif (!$response instanceof Zend_Amf_Response) {
 690              require_once 'Zend/Amf/Server/Exception.php';
 691              throw new Zend_Amf_Server_Exception('Invalid response object');
 692          }
 693          $this->_response = $response;
 694          return $this;
 695      }
 696  
 697      /**
 698       * get a reference to the Zend_Amf_response instance
 699       *
 700       * @return Zend_Amf_Server_Response
 701       */
 702      public function getResponse()
 703      {
 704          if (null === ($response = $this->_response)) {
 705              require_once 'Zend/Amf/Response/Http.php';
 706              $this->setResponse(new Zend_Amf_Response_Http());
 707          }
 708          return $this->_response;
 709      }
 710  
 711      /**
 712       * Attach a class or object to the server
 713       *
 714       * Class may be either a class name or an instantiated object. Reflection
 715       * is done on the class or object to determine the available public
 716       * methods, and each is attached to the server as and available method. If
 717       * a $namespace has been provided, that namespace is used to prefix
 718       * AMF service call.
 719       *
 720       * @param  string|object $class
 721       * @param  string $namespace Optional
 722       * @param  mixed $arg Optional arguments to pass to a method
 723       * @return Zend_Amf_Server
 724       * @throws Zend_Amf_Server_Exception on invalid input
 725       */
 726      public function setClass($class, $namespace = '', $argv = null)
 727      {
 728          if (is_string($class) && !class_exists($class)){
 729              require_once 'Zend/Amf/Server/Exception.php';
 730              throw new Zend_Amf_Server_Exception('Invalid method or class');
 731          } elseif (!is_string($class) && !is_object($class)) {
 732              require_once 'Zend/Amf/Server/Exception.php';
 733              throw new Zend_Amf_Server_Exception('Invalid method or class; must be a classname or object');
 734          }
 735  
 736          $argv = null;
 737          if (2 < func_num_args()) {
 738              $argv = array_slice(func_get_args(), 2);
 739          }
 740  
 741          // Use the class name as the name space by default.
 742  
 743          if ($namespace == '') {
 744              $namespace = is_object($class) ? get_class($class) : $class;
 745          }
 746  
 747          $this->_classAllowed[is_object($class) ? get_class($class) : $class] = true;
 748  
 749          $this->_methods[] = Zend_Server_Reflection::reflectClass($class, $argv, $namespace);
 750          $this->_buildDispatchTable();
 751  
 752          return $this;
 753      }
 754  
 755      /**
 756       * Attach a function to the server
 757       *
 758       * Additional arguments to pass to the function at dispatch may be passed;
 759       * any arguments following the namespace will be aggregated and passed at
 760       * dispatch time.
 761       *
 762       * @param  string|array $function Valid callback
 763       * @param  string $namespace Optional namespace prefix
 764       * @return Zend_Amf_Server
 765       * @throws Zend_Amf_Server_Exception
 766       */
 767      public function addFunction($function, $namespace = '')
 768      {
 769          if (!is_string($function) && !is_array($function)) {
 770              require_once 'Zend/Amf/Server/Exception.php';
 771              throw new Zend_Amf_Server_Exception('Unable to attach function');
 772          }
 773  
 774          $argv = null;
 775          if (2 < func_num_args()) {
 776              $argv = array_slice(func_get_args(), 2);
 777          }
 778  
 779          $function = (array) $function;
 780          foreach ($function as $func) {
 781              if (!is_string($func) || !function_exists($func)) {
 782                  require_once 'Zend/Amf/Server/Exception.php';
 783                  throw new Zend_Amf_Server_Exception('Unable to attach function');
 784              }
 785              $this->_methods[] = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace);
 786          }
 787  
 788          $this->_buildDispatchTable();
 789          return $this;
 790      }
 791  
 792  
 793      /**
 794       * Creates an array of directories in which services can reside.
 795       * TODO: add support for prefixes?
 796       *
 797       * @param string $dir
 798       */
 799      public function addDirectory($dir)
 800      {
 801          $this->getLoader()->addPrefixPath("", $dir);
 802      }
 803  
 804      /**
 805       * Returns an array of directories that can hold services.
 806       *
 807       * @return array
 808       */
 809      public function getDirectory()
 810      {
 811          return $this->getLoader()->getPaths("");
 812      }
 813  
 814      /**
 815       * (Re)Build the dispatch table
 816       *
 817       * The dispatch table consists of a an array of method name =>
 818       * Zend_Server_Reflection_Function_Abstract pairs
 819       *
 820       * @return void
 821       */
 822      protected function _buildDispatchTable()
 823      {
 824          $table = array();
 825          foreach ($this->_methods as $key => $dispatchable) {
 826              if ($dispatchable instanceof Zend_Server_Reflection_Function_Abstract) {
 827                  $ns   = $dispatchable->getNamespace();
 828                  $name = $dispatchable->getName();
 829                  $name = empty($ns) ? $name : $ns . '.' . $name;
 830  
 831                  if (isset($table[$name])) {
 832                      require_once 'Zend/Amf/Server/Exception.php';
 833                      throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name);
 834                  }
 835                  $table[$name] = $dispatchable;
 836                  continue;
 837              }
 838  
 839              if ($dispatchable instanceof Zend_Server_Reflection_Class) {
 840                  foreach ($dispatchable->getMethods() as $method) {
 841                      $ns   = $method->getNamespace();
 842                      $name = $method->getName();
 843                      $name = empty($ns) ? $name : $ns . '.' . $name;
 844  
 845                      if (isset($table[$name])) {
 846                          require_once 'Zend/Amf/Server/Exception.php';
 847                          throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name);
 848                      }
 849                      $table[$name] = $method;
 850                      continue;
 851                  }
 852              }
 853          }
 854          $this->_table = $table;
 855      }
 856  
 857  
 858  
 859      /**
 860       * Raise a server fault
 861       *
 862       * Unimplemented
 863       *
 864       * @param  string|Exception $fault
 865       * @return void
 866       */
 867      public function fault($fault = null, $code = 404)
 868      {
 869      }
 870  
 871      /**
 872       * Returns a list of registered methods
 873       *
 874       * Returns an array of dispatchables (Zend_Server_Reflection_Function,
 875       * _Method, and _Class items).
 876       *
 877       * @return array
 878       */
 879      public function getFunctions()
 880      {
 881          return $this->_table;
 882      }
 883  
 884      /**
 885       * Set server persistence
 886       *
 887       * Unimplemented
 888       *
 889       * @param  mixed $mode
 890       * @return void
 891       */
 892      public function setPersistence($mode)
 893      {
 894      }
 895  
 896      /**
 897       * Load server definition
 898       *
 899       * Unimplemented
 900       *
 901       * @param  array $definition
 902       * @return void
 903       */
 904      public function loadFunctions($definition)
 905      {
 906      }
 907  
 908      /**
 909       * Map ActionScript classes to PHP classes
 910       *
 911       * @param  string $asClass
 912       * @param  string $phpClass
 913       * @return Zend_Amf_Server
 914       */
 915      public function setClassMap($asClass, $phpClass)
 916      {
 917          require_once 'Zend/Amf/Parse/TypeLoader.php';
 918          Zend_Amf_Parse_TypeLoader::setMapping($asClass, $phpClass);
 919          return $this;
 920      }
 921  
 922      /**
 923       * List all available methods
 924       *
 925       * Returns an array of method names.
 926       *
 927       * @return array
 928       */
 929      public function listMethods()
 930      {
 931          return array_keys($this->_table);
 932      }
 933  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1