*prechod na novsiu verziu ZF
[sport-group.git] / library / Zend / Amf / Server.php
bloba280945b6c88c63c1e0d0a1eeb63fa7f31298292
1 <?php
2 /**
3 * Zend Framework
5 * LICENSE
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 license@zend.com so we can send you a copy immediately.
15 * @category Zend
16 * @package Zend_Amf
17 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
18 * @license http://framework.zend.com/license/new-bsd New BSD License
19 * @version $Id: Server.php 16971 2009-07-22 18:05:45Z mikaelkael $
22 /** Zend_Server_Interface */
23 require_once 'Zend/Server/Interface.php';
25 /** Zend_Server_Reflection */
26 require_once 'Zend/Server/Reflection.php';
28 /** Zend_Amf_Constants */
29 require_once 'Zend/Amf/Constants.php';
31 /** Zend_Amf_Value_MessageBody */
32 require_once 'Zend/Amf/Value/MessageBody.php';
34 /** Zend_Amf_Value_MessageHeader */
35 require_once 'Zend/Amf/Value/MessageHeader.php';
37 /** Zend_Amf_Value_Messaging_CommandMessage */
38 require_once 'Zend/Amf/Value/Messaging/CommandMessage.php';
40 /** Zend_Loader_PluginLoader */
41 require_once 'Zend/Loader/PluginLoader.php';
43 /** Zend_Amf_Parse_TypeLoader */
44 require_once 'Zend/Amf/Parse/TypeLoader.php';
46 /** 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
52 * @todo Make the relection methods cache and autoload.
53 * @package Zend_Amf
54 * @subpackage Server
55 * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
56 * @license http://framework.zend.com/license/new-bsd New BSD License
58 class Zend_Amf_Server implements Zend_Server_Interface
60 /**
61 * Array of dispatchables
62 * @var array
64 protected $_methods = array();
66 /**
67 * Array of classes that can be called without being explicitly loaded
69 * Keys are class names.
71 * @var array
73 protected $_classAllowed = array();
75 /**
76 * Loader for classes in added directories
77 * @var Zend_Loader_PluginLoader
79 protected $_loader;
81 /**
82 * @var bool Production flag; whether or not to return exception messages
84 protected $_production = true;
86 /**
87 * Request processed
88 * @var null|Zend_Amf_Request
90 protected $_request = null;
92 /**
93 * Class to use for responses
94 * @var null|Zend_Amf_Response
96 protected $_response;
98 /**
99 * Dispatch table of name => method pairs
100 * @var array
102 protected $_table = array();
106 * @var bool session flag; whether or not to add a session to each response.
108 protected $_session = false;
111 * Namespace allows all AMF calls to not clobber other php session variables
112 * @var Zend_Session_NameSpace default session namespace zend_amf
114 protected $_sesionNamespace = 'zend_amf';
117 * Set the default session.name if php_
118 * @var string
120 protected $_sessionName = 'PHPSESSID';
123 * Authentication handler object
125 * @var Zend_Amf_Auth_Abstract
127 protected $_auth;
129 * ACL handler object
131 * @var Zend_Acl
133 protected $_acl;
135 * The server constructor
137 public function __construct()
139 Zend_Amf_Parse_TypeLoader::setResourceLoader(new Zend_Loader_PluginLoader(array("Zend_Amf_Parse_Resource" => "Zend/Amf/Parse/Resource")));
143 * Set authentication adapter
145 * @param Zend_Amf_Auth_Abstract $auth
146 * @return Zend_Amf_Server
148 public function setAuth(Zend_Amf_Auth_Abstract $auth)
150 $this->_auth = $auth;
151 return $this;
154 * Get authentication adapter
156 * @return Zend_Amf_Auth_Abstract
158 public function getAuth()
160 return $this->_auth;
164 * Set ACL adapter
166 * @param Zend_Acl $acl
167 * @return Zend_Amf_Server
169 public function setAcl(Zend_Acl $acl)
171 $this->_acl = $acl;
172 return $this;
175 * Get ACL adapter
177 * @return Zend_Acl
179 public function getAcl()
181 return $this->_acl;
185 * Set production flag
187 * @param bool $flag
188 * @return Zend_Amf_Server
190 public function setProduction($flag)
192 $this->_production = (bool) $flag;
193 return $this;
197 * Whether or not the server is in production
199 * @return bool
201 public function isProduction()
203 return $this->_production;
207 * @param namespace of all incoming sessions defaults to Zend_Amf
208 * @return Zend_Amf_Server
210 public function setSession($namespace = 'Zend_Amf')
212 require_once 'Zend/Session.php';
213 $this->_session = true;
214 $this->_sesionNamespace = new Zend_Session_Namespace($namespace);
215 return $this;
219 * Whether of not the server is using sessions
220 * @return bool
222 public function isSession()
224 return $this->_session;
228 * Check if the ACL allows accessing the function or method
230 * @param string|object $object Object or class being accessed
231 * @param string $function Function or method being acessed
232 * @return unknown_type
234 protected function _checkAcl($object, $function)
236 if(!$this->_acl) {
237 return true;
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));
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;
250 } else {
251 $class = null;
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");
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");
274 * Get PluginLoader for the Server
276 * @return Zend_Loader_PluginLoader
278 protected function getLoader()
280 if(empty($this->_loader)) {
281 require_once 'Zend/Loader/PluginLoader.php';
282 $this->_loader = new Zend_Loader_PluginLoader();
284 return $this->_loader;
288 * Loads a remote class or method and executes the function and returns
289 * the result
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
296 protected function _dispatch($method, $params = null, $source = null)
298 if($source) {
299 if(($mapped = Zend_Amf_Parse_TypeLoader::getMappedClassName($source)) !== false) {
300 $source = $mapped;
303 $qualifiedName = empty($source) ? $method : $source.".".$method;
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()');
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());
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');
327 $info = $this->_table[$qualifiedName];
328 $argv = $info->getInvokeArguments();
330 if (0 < count($argv)) {
331 $params = array_merge($params, $argv);
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);
355 $this->_checkAcl($object, $info->getName());
356 $return = $info->invokeArgs($object, $params);
358 } else {
359 require_once 'Zend/Amf/Server/Exception.php';
360 throw new Zend_Amf_Server_Exception('Method missing implementation ' . get_class($info));
363 return $return;
367 * Handles each of the 11 different command message types.
369 * A command message is a flex.messaging.messages.CommandMessage
371 * @see Zend_Amf_Value_Messaging_CommandMessage
372 * @param Zend_Amf_Value_Messaging_CommandMessage $message
373 * @return Zend_Amf_Value_Messaging_AcknowledgeMessage
375 protected function _loadCommandMessage(Zend_Amf_Value_Messaging_CommandMessage $message)
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');
391 if(!$this->_handleAuth($userid, $password)) {
392 require_once 'Zend/Amf/Server/Exception.php';
393 throw new Zend_Amf_Server_Exception('Authentication failed');
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();
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;
408 return $return;
412 * Create appropriate error message
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
422 protected function _errorMessage($objectEncoding, $message, $description, $detail, $code, $line)
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
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;
441 return $return;
445 * Handle AMF authenticaton
447 * @param string $userid
448 * @param string $password
449 * @return boolean
451 protected function _handleAuth( $userid, $password)
453 if (!$this->_auth) {
454 return true;
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();
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());
475 * Takes the deserialized AMF request and performs any operations.
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
483 protected function _handle(Zend_Amf_Request $request)
485 // Get the object encoding of the request.
486 $objectEncoding = $request->getObjectEncoding();
488 // create a response object to place the output from the services.
489 $response = $this->getResponse();
491 // set reponse encoding
492 $response->setObjectEncoding($objectEncoding);
494 $responseBody = $request->getAmfBodies();
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;
505 // Iterate through each of the service calls in the AMF request
506 foreach($responseBody as $body)
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;
525 if ($objectEncoding == Zend_Amf_Constants::AMF0_OBJECT_ENCODING) {
526 // AMF0 Object Encoding
527 $targetURI = $body->getTargetURI();
528 $message = '';
530 // Split the target string into its values.
531 $source = substr($targetURI, 0, strrpos($targetURI, '.'));
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());
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();
555 // Split the target string into its values.
556 $source = substr($targetURI, 0, strrpos($targetURI, '.'));
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());
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;
575 $responseURI = $body->getResponseURI() . $responseType;
576 $newBody = new Zend_Amf_Value_MessageBody($responseURI, null, $return);
577 $response->addAmfBody($newBody);
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 = "&";
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);
597 // serialize the response and return serialized body.
598 $response->finalize();
602 * Handle an AMF call from the gateway.
604 * @param null|Zend_Amf_Request $request Optional
605 * @return Zend_Amf_Response
607 public function handle($request = null)
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);
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]);
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());
634 // Return the Amf serialized output string
635 return $response;
639 * Set request object
641 * @param string|Zend_Amf_Request $request
642 * @return Zend_Amf_Server
644 public function setRequest($request)
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');
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');
656 $this->_request = $request;
657 return $this;
661 * Return currently registered request object
663 * @return null|Zend_Amf_Request
665 public function getRequest()
667 if (null === $this->_request) {
668 require_once 'Zend/Amf/Request/Http.php';
669 $this->setRequest(new Zend_Amf_Request_Http());
672 return $this->_request;
676 * Public access method to private Zend_Amf_Server_Response refrence
678 * @param string|Zend_Amf_Server_Response $response
679 * @return Zend_Amf_Server
681 public function setResponse($response)
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');
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');
693 $this->_response = $response;
694 return $this;
698 * get a refrence to the Zend_Amf_response instance
700 * @return Zend_Amf_Server_Response
702 public function getResponse()
704 if (null === ($response = $this->_response)) {
705 require_once 'Zend/Amf/Response/Http.php';
706 $this->setResponse(new Zend_Amf_Response_Http());
708 return $this->_response;
712 * Attach a class or object to the server
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.
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
726 public function setClass($class, $namespace = '', $argv = null)
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');
736 $argv = null;
737 if (2 < func_num_args()) {
738 $argv = array_slice(func_get_args(), 2);
741 // Use the class name as the name space by default.
743 if ($namespace == '') {
744 $namespace = is_object($class) ? get_class($class) : $class;
747 $this->_classAllowed[is_object($class) ? get_class($class) : $class] = true;
749 $this->_methods[] = Zend_Server_Reflection::reflectClass($class, $argv, $namespace);
750 $this->_buildDispatchTable();
752 return $this;
756 * Attach a function to the server
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.
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
767 public function addFunction($function, $namespace = '')
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');
774 $argv = null;
775 if (2 < func_num_args()) {
776 $argv = array_slice(func_get_args(), 2);
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');
785 $this->_methods[] = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace);
788 $this->_buildDispatchTable();
789 return $this;
794 * Creates an array of directories in which services can reside.
795 * TODO: add support for prefixes?
797 * @param string $dir
799 public function addDirectory($dir)
801 $this->getLoader()->addPrefixPath("", $dir);
805 * Returns an array of directories that can hold services.
807 * @return array
809 public function getDirectory()
811 return $this->getLoader()->getPaths("");
815 * (Re)Build the dispatch table
817 * The dispatch table consists of a an array of method name =>
818 * Zend_Server_Reflection_Function_Abstract pairs
820 * @return void
822 protected function _buildDispatchTable()
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;
831 if (isset($table[$name])) {
832 require_once 'Zend/Amf/Server/Exception.php';
833 throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name);
835 $table[$name] = $dispatchable;
836 continue;
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;
845 if (isset($table[$name])) {
846 require_once 'Zend/Amf/Server/Exception.php';
847 throw new Zend_Amf_Server_Exception('Duplicate method registered: ' . $name);
849 $table[$name] = $method;
850 continue;
854 $this->_table = $table;
860 * Raise a server fault
862 * Unimplemented
864 * @param string|Exception $fault
865 * @return void
867 public function fault($fault = null, $code = 404)
872 * Returns a list of registered methods
874 * Returns an array of dispatchables (Zend_Server_Reflection_Function,
875 * _Method, and _Class items).
877 * @return array
879 public function getFunctions()
881 return $this->_table;
885 * Set server persistence
887 * Unimplemented
889 * @param mixed $mode
890 * @return void
892 public function setPersistence($mode)
897 * Load server definition
899 * Unimplemented
901 * @param array $definition
902 * @return void
904 public function loadFunctions($definition)
909 * Map ActionScript classes to PHP classes
911 * @param string $asClass
912 * @param string $phpClass
913 * @return Zend_Amf_Server
915 public function setClassMap($asClass, $phpClass)
917 require_once 'Zend/Amf/Parse/TypeLoader.php';
918 Zend_Amf_Parse_TypeLoader::setMapping($asClass, $phpClass);
919 return $this;
923 * List all available methods
925 * Returns an array of method names.
927 * @return array
929 public function listMethods()
931 return array_keys($this->_table);