web/lib/Zend/Rest/Server.php
changeset 1230 68c69c656a2c
parent 807 877f952ae2bd
equal deleted inserted replaced
1229:5a6b6e770365 1230:68c69c656a2c
    13  * to license@zend.com so we can send you a copy immediately.
    13  * to license@zend.com so we can send you a copy immediately.
    14  *
    14  *
    15  * @category   Zend
    15  * @category   Zend
    16  * @package    Zend_Rest
    16  * @package    Zend_Rest
    17  * @subpackage Server
    17  * @subpackage Server
    18  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    18  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    20  * @version    $Id: Server.php 24593 2012-01-05 20:35:02Z matthew $
    20  * @version    $Id$
    21  */
    21  */
    22 
    22 
    23 /**
    23 /**
    24  * @see Zend_Server_Interface
    24  * @see Zend_Server_Interface
    25  */
    25  */
    37 
    37 
    38 /**
    38 /**
    39  * @category   Zend
    39  * @category   Zend
    40  * @package    Zend_Rest
    40  * @package    Zend_Rest
    41  * @subpackage Server
    41  * @subpackage Server
    42  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    42  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
    43  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    43  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    44  */
    44  */
    45 class Zend_Rest_Server implements Zend_Server_Interface
    45 class Zend_Rest_Server implements Zend_Server_Interface
    46 {
    46 {
    47     /**
    47     /**
   180             $request = $_REQUEST;
   180             $request = $_REQUEST;
   181         }
   181         }
   182         if (isset($request['method'])) {
   182         if (isset($request['method'])) {
   183             $this->_method = $request['method'];
   183             $this->_method = $request['method'];
   184             if (isset($this->_functions[$this->_method])) {
   184             if (isset($this->_functions[$this->_method])) {
   185                 if ($this->_functions[$this->_method] instanceof Zend_Server_Reflection_Function || $this->_functions[$this->_method] instanceof Zend_Server_Reflection_Method && $this->_functions[$this->_method]->isPublic()) {
   185                 if ($this->_functions[$this->_method] instanceof
   186                     $request_keys = array_keys($request);
   186                     Zend_Server_Reflection_Function
   187                     array_walk($request_keys, array(__CLASS__, "lowerCase"));
   187                     || $this->_functions[$this->_method] instanceof
   188                     $request = array_combine($request_keys, $request);
   188                        Zend_Server_Reflection_Method
   189 
   189                        && $this->_functions[$this->_method]->isPublic()
   190                     $func_args = $this->_functions[$this->_method]->getParameters();
   190                 ) {
   191 
   191                     $requestKeys = array_keys($request);
   192                     $calling_args = array();
   192                     array_walk($requestKeys, array(__CLASS__, "lowerCase"));
   193                     $missing_args = array();
   193                     $request = array_combine($requestKeys, $request);
   194                     foreach ($func_args as $arg) {
   194 
       
   195                     $funcArgs = $this->_functions[$this->_method]->getParameters();
       
   196 
       
   197                     // calling_args will be a zero-based array of the parameters
       
   198                     $callingArgs = array();
       
   199                     $missingArgs = array();
       
   200                     foreach ($funcArgs as $i => $arg) {
   195                         if (isset($request[strtolower($arg->getName())])) {
   201                         if (isset($request[strtolower($arg->getName())])) {
   196                             $calling_args[] = $request[strtolower($arg->getName())];
   202                             $callingArgs[$i] = $request[strtolower($arg->getName())];
   197                         } elseif ($arg->isOptional()) {
   203                         } elseif ($arg->isOptional()) {
   198                             $calling_args[] = $arg->getDefaultValue();
   204                             $callingArgs[$i] = $arg->getDefaultValue();
   199                         } else {
   205                         } else {
   200                             $missing_args[] = $arg->getName();
   206                             $missingArgs[] = $arg->getName();
   201                         }
   207                         }
   202                     }
   208                     }
   203 
   209 
       
   210                     $anonymousArgs = array();
   204                     foreach ($request as $key => $value) {
   211                     foreach ($request as $key => $value) {
   205                         if (substr($key, 0, 3) == 'arg') {
   212                         if (substr($key, 0, 3) == 'arg') {
   206                             $key = str_replace('arg', '', $key);
   213                             $key = str_replace('arg', '', $key);
   207                             $calling_args[$key] = $value;
   214                             $anonymousArgs[$key] = $value;
   208                             if (($index = array_search($key, $missing_args)) !== false) {
   215                             if (($index = array_search($key, $missingArgs)) !== false) {
   209                                 unset($missing_args[$index]);
   216                                 unset($missingArgs[$index]);
   210                             }
   217                             }
   211                         }
   218                         }
   212                     }
   219                     }
   213 
   220 
       
   221                     // re-key the $anonymousArgs to be zero-based, and add in
       
   222                     // any values already set in calling_args (optional defaults)
       
   223                     ksort($anonymousArgs);
       
   224                     $callingArgs = array_values($anonymousArgs) + $callingArgs;
       
   225 
   214                     // Sort arguments by key -- @see ZF-2279
   226                     // Sort arguments by key -- @see ZF-2279
   215                     ksort($calling_args);
   227                     ksort($callingArgs);
   216 
   228 
   217                     $result = false;
   229                     $result = false;
   218                     if (count($calling_args) < count($func_args)) {
   230                     if (count($callingArgs) < count($funcArgs)) {
   219                         require_once 'Zend/Rest/Server/Exception.php';
   231                         require_once 'Zend/Rest/Server/Exception.php';
   220                         $result = $this->fault(new Zend_Rest_Server_Exception('Invalid Method Call to ' . $this->_method . '. Missing argument(s): ' . implode(', ', $missing_args) . '.'), 400);
   232                         $result = $this->fault(
       
   233                             new Zend_Rest_Server_Exception(
       
   234                                 'Invalid Method Call to ' . $this->_method
       
   235                                 . '. Missing argument(s): ' . implode(
       
   236                                     ', ', $missingArgs
       
   237                                 ) . '.'
       
   238                             ), 400
       
   239                         );
   221                     }
   240                     }
   222 
   241 
   223                     if (!$result && $this->_functions[$this->_method] instanceof Zend_Server_Reflection_Method) {
   242                     if (!$result && $this->_functions[$this->_method] instanceof
       
   243                                     Zend_Server_Reflection_Method
       
   244                     ) {
   224                         // Get class
   245                         // Get class
   225                         $class = $this->_functions[$this->_method]->getDeclaringClass()->getName();
   246                         $class = $this->_functions[$this->_method]->getDeclaringClass()->getName();
   226 
   247 
   227                         if ($this->_functions[$this->_method]->isStatic()) {
   248                         if ($this->_functions[$this->_method]->isStatic()) {
   228                             // for some reason, invokeArgs() does not work the same as
   249                             // for some reason, invokeArgs() does not work the same as
   229                             // invoke(), and expects the first argument to be an object.
   250                             // invoke(), and expects the first argument to be an object.
   230                             // So, using a callback if the method is static.
   251                             // So, using a callback if the method is static.
   231                             $result = $this->_callStaticMethod($class, $calling_args);
   252                             $result = $this->_callStaticMethod(
       
   253                                 $class,
       
   254                                 $callingArgs
       
   255                             );
   232                         } else {
   256                         } else {
   233                             // Object method
   257                             // Object method
   234                             $result = $this->_callObjectMethod($class, $calling_args);
   258                             $result = $this->_callObjectMethod(
       
   259                                 $class,
       
   260                                 $callingArgs
       
   261                             );
   235                         }
   262                         }
   236                     } elseif (!$result) {
   263                     } elseif (!$result) {
   237                         try {
   264                         try {
   238                             $result = call_user_func_array($this->_functions[$this->_method]->getName(), $calling_args); //$this->_functions[$this->_method]->invokeArgs($calling_args);
   265                             $result = call_user_func_array(
       
   266                                 $this->_functions[$this->_method]->getName(),
       
   267                                 $callingArgs
       
   268                             );
   239                         } catch (Exception $e) {
   269                         } catch (Exception $e) {
   240                             $result = $this->fault($e);
   270                             $result = $this->fault($e);
   241                         }
   271                         }
   242                     }
   272                     }
   243                 } else {
   273                 } else {
   244                     require_once "Zend/Rest/Server/Exception.php";
   274                     require_once "Zend/Rest/Server/Exception.php";
   245                     $result = $this->fault(
   275                     $result = $this->fault(
   246                         new Zend_Rest_Server_Exception("Unknown Method '$this->_method'."),
   276                         new Zend_Rest_Server_Exception(
       
   277                             "Unknown Method '$this->_method'."
       
   278                         ),
   247                         404
   279                         404
   248                     );
   280                     );
   249                 }
   281                 }
   250             } else {
   282             } else {
   251                 require_once "Zend/Rest/Server/Exception.php";
   283                 require_once "Zend/Rest/Server/Exception.php";
   252                 $result = $this->fault(
   284                 $result = $this->fault(
   253                     new Zend_Rest_Server_Exception("Unknown Method '$this->_method'."),
   285                     new Zend_Rest_Server_Exception(
       
   286                         "Unknown Method '$this->_method'."
       
   287                     ),
   254                     404
   288                     404
   255                 );
   289                 );
   256             }
   290             }
   257         } else {
   291         } else {
   258             require_once "Zend/Rest/Server/Exception.php";
   292             require_once "Zend/Rest/Server/Exception.php";
   353      * @param mixed $struct
   387      * @param mixed $struct
   354      * @param DOMDocument $dom
   388      * @param DOMDocument $dom
   355      * @param DOMElement $parent
   389      * @param DOMElement $parent
   356      * @return void
   390      * @return void
   357      */
   391      */
   358     protected function _structValue($struct, DOMDocument $dom, DOMElement $parent)
   392     protected function _structValue(
   359     {
   393         $struct, DOMDocument $dom, DOMElement $parent
   360         $struct = (array) $struct;
   394     )
       
   395     {
       
   396         $struct = (array)$struct;
   361 
   397 
   362         foreach ($struct as $key => $value) {
   398         foreach ($struct as $key => $value) {
   363             if ($value === false) {
   399             if ($value === false) {
   364                 $value = 0;
   400                 $value = 0;
   365             } elseif ($value === true) {
   401             } elseif ($value === true) {
   366                 $value = 1;
   402                 $value = 1;
   367             }
   403             }
   368 
   404 
   369             if (ctype_digit((string) $key)) {
   405             if (ctype_digit((string)$key)) {
   370                 $key = 'key_' . $key;
   406                 $key = 'key_' . $key;
   371             }
   407             }
   372 
   408 
   373             if (is_array($value) || is_object($value)) {
   409             if (is_array($value) || is_object($value)) {
   374                 $element = $dom->createElement($key);
   410                 $element = $dom->createElement($key);
   478         $xmlResponse = $dom->createElement('response');
   514         $xmlResponse = $dom->createElement('response');
   479         $xmlMethod->appendChild($xmlResponse);
   515         $xmlMethod->appendChild($xmlResponse);
   480 
   516 
   481         if ($exception instanceof Exception) {
   517         if ($exception instanceof Exception) {
   482             $element = $dom->createElement('message');
   518             $element = $dom->createElement('message');
   483             $element->appendChild($dom->createTextNode($exception->getMessage()));
   519             $element->appendChild(
       
   520                 $dom->createTextNode($exception->getMessage())
       
   521             );
   484             $xmlResponse->appendChild($element);
   522             $xmlResponse->appendChild($element);
   485             $code = $exception->getCode();
   523             $code = $exception->getCode();
   486         } elseif (($exception !== null) || 'rest' == $function) {
   524         } elseif (($exception !== null) || 'rest' == $function) {
   487             $xmlResponse->appendChild($dom->createElement('message', 'An unknown error occured. Please try again.'));
   525             $xmlResponse->appendChild(
   488         } else {
   526                 $dom->createElement(
   489             $xmlResponse->appendChild($dom->createElement('message', 'Call to ' . $method . ' failed.'));
   527                     'message', 'An unknown error occured. Please try again.'
       
   528                 )
       
   529             );
       
   530         } else {
       
   531             $xmlResponse->appendChild(
       
   532                 $dom->createElement(
       
   533                     'message', 'Call to ' . $method . ' failed.'
       
   534                 )
       
   535             );
   490         }
   536         }
   491 
   537 
   492         $xmlMethod->appendChild($xmlResponse);
   538         $xmlMethod->appendChild($xmlResponse);
   493         $xmlMethod->appendChild($dom->createElement('status', 'failed'));
   539         $xmlMethod->appendChild($dom->createElement('status', 'failed'));
   494 
   540 
   527         foreach ($function as $func) {
   573         foreach ($function as $func) {
   528             if (is_callable($func) && !in_array($func, self::$magicMethods)) {
   574             if (is_callable($func) && !in_array($func, self::$magicMethods)) {
   529                 $this->_functions[$func] = $this->_reflection->reflectFunction($func);
   575                 $this->_functions[$func] = $this->_reflection->reflectFunction($func);
   530             } else {
   576             } else {
   531                 require_once 'Zend/Rest/Server/Exception.php';
   577                 require_once 'Zend/Rest/Server/Exception.php';
   532                 throw new Zend_Rest_Server_Exception("Invalid Method Added to Service.");
   578                 throw new Zend_Rest_Server_Exception(
       
   579                     "Invalid Method Added to Service."
       
   580                 );
   533             }
   581             }
   534         }
   582         }
   535     }
   583     }
   536 
   584 
   537     /**
   585     /**
   572      * @return mixed
   620      * @return mixed
   573      */
   621      */
   574     protected function _callStaticMethod($class, array $args)
   622     protected function _callStaticMethod($class, array $args)
   575     {
   623     {
   576         try {
   624         try {
   577             $result = call_user_func_array(array($class, $this->_functions[$this->_method]->getName()), $args);
   625             $result = call_user_func_array(
       
   626                 array(
       
   627                     $class,
       
   628                     $this->_functions[$this->_method]->getName()
       
   629                 ),
       
   630                 $args
       
   631             );
   578         } catch (Exception $e) {
   632         } catch (Exception $e) {
   579             $result = $this->fault($e);
   633             $result = $this->fault($e);
   580         }
   634         }
   581         return $result;
   635         return $result;
   582     }
   636     }
   597             } else {
   651             } else {
   598                 $object = $this->_functions[$this->_method]->getDeclaringClass()->newInstance();
   652                 $object = $this->_functions[$this->_method]->getDeclaringClass()->newInstance();
   599             }
   653             }
   600         } catch (Exception $e) {
   654         } catch (Exception $e) {
   601             require_once 'Zend/Rest/Server/Exception.php';
   655             require_once 'Zend/Rest/Server/Exception.php';
   602             throw new Zend_Rest_Server_Exception('Error instantiating class ' . $class .
   656             throw new Zend_Rest_Server_Exception(
   603                                                  ' to invoke method ' . $this->_functions[$this->_method]->getName() .
   657                 'Error instantiating class ' . $class .
   604                                                  ' (' . $e->getMessage() . ') ',
   658                 ' to invoke method '
   605                                                  500, $e);
   659                 . $this->_functions[$this->_method]->getName() .
       
   660                 ' (' . $e->getMessage() . ') ',
       
   661                 500,
       
   662                 $e
       
   663             );
   606         }
   664         }
   607 
   665 
   608         try {
   666         try {
   609             $result = $this->_functions[$this->_method]->invokeArgs($object, $args);
   667             $result = $this->_functions[$this->_method]->invokeArgs(
       
   668                 $object,
       
   669                 $args
       
   670             );
   610         } catch (Exception $e) {
   671         } catch (Exception $e) {
   611             $result = $this->fault($e);
   672             $result = $this->fault($e);
   612         }
   673         }
   613 
   674 
   614         return $result;
   675         return $result;