Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/Rest/Server.php
Go to the documentation of this file.
00001 <?php
00026 require_once 'Zend/Server/Interface.php';
00027 
00031 require_once 'Zend/Server/Reflection.php';
00032 
00036 require_once 'Zend/Server/Abstract.php';
00037 
00045 class Zend_Rest_Server implements Zend_Server_Interface
00046 {
00051     protected $_args = array();
00052 
00056     protected $_encoding = 'UTF-8';
00057 
00061     protected $_functions = array();
00062 
00066     protected $_headers = array();
00067 
00071     protected static $magicMethods = array(
00072         '__construct',
00073         '__destruct',
00074         '__get',
00075         '__set',
00076         '__call',
00077         '__sleep',
00078         '__wakeup',
00079         '__isset',
00080         '__unset',
00081         '__tostring',
00082         '__clone',
00083         '__set_state',
00084     );
00085 
00089     protected $_method;
00090 
00094     protected $_reflection = null;
00095 
00100     protected $_returnResponse = false;
00101 
00105     public function __construct()
00106     {
00107         set_exception_handler(array($this, "fault"));
00108         $this->_reflection = new Zend_Server_Reflection();
00109     }
00110 
00117     public function setEncoding($encoding)
00118     {
00119         $this->_encoding = (string) $encoding;
00120         return $this;
00121     }
00122 
00128     public function getEncoding()
00129     {
00130         return $this->_encoding;
00131     }
00132 
00142     public static function lowerCase(&$value, &$key)
00143     {
00144         return $value = strtolower($value);
00145     }
00146 
00159     public function returnResponse($flag = null)
00160     {
00161         if (null === $flag) {
00162             return $this->_returnResponse;
00163         }
00164 
00165         $this->_returnResponse = ($flag) ? true : false;
00166         return $this;
00167     }
00168 
00176     public function handle($request = false)
00177     {
00178         $this->_headers = array('Content-Type: text/xml');
00179         if (!$request) {
00180             $request = $_REQUEST;
00181         }
00182         if (isset($request['method'])) {
00183             $this->_method = $request['method'];
00184             if (isset($this->_functions[$this->_method])) {
00185                 if ($this->_functions[$this->_method] instanceof Zend_Server_Reflection_Function || $this->_functions[$this->_method] instanceof Zend_Server_Reflection_Method && $this->_functions[$this->_method]->isPublic()) {
00186                     $request_keys = array_keys($request);
00187                     array_walk($request_keys, array(__CLASS__, "lowerCase"));
00188                     $request = array_combine($request_keys, $request);
00189 
00190                     $func_args = $this->_functions[$this->_method]->getParameters();
00191 
00192                     $calling_args = array();
00193                     $missing_args = array();
00194                     foreach ($func_args as $arg) {
00195                         if (isset($request[strtolower($arg->getName())])) {
00196                             $calling_args[] = $request[strtolower($arg->getName())];
00197                         } elseif ($arg->isOptional()) {
00198                             $calling_args[] = $arg->getDefaultValue();
00199                         } else {
00200                             $missing_args[] = $arg->getName();
00201                         }
00202                     }
00203 
00204                     foreach ($request as $key => $value) {
00205                         if (substr($key, 0, 3) == 'arg') {
00206                             $key = str_replace('arg', '', $key);
00207                             $calling_args[$key] = $value;
00208                             if (($index = array_search($key, $missing_args)) !== false) {
00209                                 unset($missing_args[$index]);
00210                             }
00211                         }
00212                     }
00213 
00214                     // Sort arguments by key -- @see ZF-2279
00215                     ksort($calling_args);
00216 
00217                     $result = false;
00218                     if (count($calling_args) < count($func_args)) {
00219                         require_once 'Zend/Rest/Server/Exception.php';
00220                         $result = $this->fault(new Zend_Rest_Server_Exception('Invalid Method Call to ' . $this->_method . '. Missing argument(s): ' . implode(', ', $missing_args) . '.'), 400);
00221                     }
00222 
00223                     if (!$result && $this->_functions[$this->_method] instanceof Zend_Server_Reflection_Method) {
00224                         // Get class
00225                         $class = $this->_functions[$this->_method]->getDeclaringClass()->getName();
00226 
00227                         if ($this->_functions[$this->_method]->isStatic()) {
00228                             // for some reason, invokeArgs() does not work the same as
00229                             // invoke(), and expects the first argument to be an object.
00230                             // So, using a callback if the method is static.
00231                             $result = $this->_callStaticMethod($class, $calling_args);
00232                         } else {
00233                             // Object method
00234                             $result = $this->_callObjectMethod($class, $calling_args);
00235                         }
00236                     } elseif (!$result) {
00237                         try {
00238                             $result = call_user_func_array($this->_functions[$this->_method]->getName(), $calling_args); //$this->_functions[$this->_method]->invokeArgs($calling_args);
00239                         } catch (Exception $e) {
00240                             $result = $this->fault($e);
00241                         }
00242                     }
00243                 } else {
00244                     require_once "Zend/Rest/Server/Exception.php";
00245                     $result = $this->fault(
00246                         new Zend_Rest_Server_Exception("Unknown Method '$this->_method'."),
00247                         404
00248                     );
00249                 }
00250             } else {
00251                 require_once "Zend/Rest/Server/Exception.php";
00252                 $result = $this->fault(
00253                     new Zend_Rest_Server_Exception("Unknown Method '$this->_method'."),
00254                     404
00255                 );
00256             }
00257         } else {
00258             require_once "Zend/Rest/Server/Exception.php";
00259             $result = $this->fault(
00260                 new Zend_Rest_Server_Exception("No Method Specified."),
00261                 404
00262             );
00263         }
00264 
00265         if ($result instanceof SimpleXMLElement) {
00266             $response = $result->asXML();
00267         } elseif ($result instanceof DOMDocument) {
00268             $response = $result->saveXML();
00269         } elseif ($result instanceof DOMNode) {
00270             $response = $result->ownerDocument->saveXML($result);
00271         } elseif (is_array($result) || is_object($result)) {
00272             $response = $this->_handleStruct($result);
00273         } else {
00274             $response = $this->_handleScalar($result);
00275         }
00276 
00277         if (!$this->returnResponse()) {
00278             if (!headers_sent()) {
00279                 foreach ($this->_headers as $header) {
00280                     header($header);
00281                 }
00282             }
00283 
00284             echo $response;
00285             return;
00286         }
00287 
00288         return $response;
00289      }
00290 
00298     public function setClass($classname, $namespace = '', $argv = array())
00299     {
00300         $this->_args = $argv;
00301         foreach ($this->_reflection->reflectClass($classname, $argv)->getMethods() as $method) {
00302             $this->_functions[$method->getName()] = $method;
00303         }
00304     }
00305 
00312     protected function _handleStruct($struct)
00313     {
00314         $function = $this->_functions[$this->_method];
00315         if ($function instanceof Zend_Server_Reflection_Method) {
00316             $class = $function->getDeclaringClass()->getName();
00317         } else {
00318             $class = false;
00319         }
00320 
00321         $method = $function->getName();
00322 
00323         $dom    = new DOMDocument('1.0', $this->getEncoding());
00324         if ($class) {
00325             $root   = $dom->createElement($class);
00326             $method = $dom->createElement($method);
00327             $root->appendChild($method);
00328         } else {
00329             $root   = $dom->createElement($method);
00330             $method = $root;
00331         }
00332         $root->setAttribute('generator', 'zend');
00333         $root->setAttribute('version', '1.0');
00334         $dom->appendChild($root);
00335 
00336         $this->_structValue($struct, $dom, $method);
00337 
00338         $struct = (array) $struct;
00339         if (!isset($struct['status'])) {
00340             $status = $dom->createElement('status', 'success');
00341             $method->appendChild($status);
00342         }
00343 
00344         return $dom->saveXML();
00345     }
00346 
00358     protected function _structValue($struct, DOMDocument $dom, DOMElement $parent)
00359     {
00360         $struct = (array) $struct;
00361 
00362         foreach ($struct as $key => $value) {
00363             if ($value === false) {
00364                 $value = 0;
00365             } elseif ($value === true) {
00366                 $value = 1;
00367             }
00368 
00369             if (ctype_digit((string) $key)) {
00370                 $key = 'key_' . $key;
00371             }
00372 
00373             if (is_array($value) || is_object($value)) {
00374                 $element = $dom->createElement($key);
00375                 $this->_structValue($value, $dom, $element);
00376             } else {
00377                 $element = $dom->createElement($key);
00378                 $element->appendChild($dom->createTextNode($value));
00379             }
00380 
00381             $parent->appendChild($element);
00382         }
00383     }
00384 
00391     protected function _handleScalar($value)
00392     {
00393         $function = $this->_functions[$this->_method];
00394         if ($function instanceof Zend_Server_Reflection_Method) {
00395             $class = $function->getDeclaringClass()->getName();
00396         } else {
00397             $class = false;
00398         }
00399 
00400         $method = $function->getName();
00401 
00402         $dom = new DOMDocument('1.0', $this->getEncoding());
00403         if ($class) {
00404             $xml = $dom->createElement($class);
00405             $methodNode = $dom->createElement($method);
00406             $xml->appendChild($methodNode);
00407         } else {
00408             $xml = $dom->createElement($method);
00409             $methodNode = $xml;
00410         }
00411         $xml->setAttribute('generator', 'zend');
00412         $xml->setAttribute('version', '1.0');
00413         $dom->appendChild($xml);
00414 
00415         if ($value === false) {
00416             $value = 0;
00417         } elseif ($value === true) {
00418             $value = 1;
00419         }
00420 
00421         if (isset($value)) {
00422             $element = $dom->createElement('response');
00423             $element->appendChild($dom->createTextNode($value));
00424             $methodNode->appendChild($element);
00425         } else {
00426             $methodNode->appendChild($dom->createElement('response'));
00427         }
00428 
00429         $methodNode->appendChild($dom->createElement('status', 'success'));
00430 
00431         return $dom->saveXML();
00432     }
00433 
00443     public function fault($exception = null, $code = null)
00444     {
00445         if (isset($this->_functions[$this->_method])) {
00446             $function = $this->_functions[$this->_method];
00447         } elseif (isset($this->_method)) {
00448             $function = $this->_method;
00449         } else {
00450             $function = 'rest';
00451         }
00452 
00453         if ($function instanceof Zend_Server_Reflection_Method) {
00454             $class = $function->getDeclaringClass()->getName();
00455         } else {
00456             $class = false;
00457         }
00458 
00459         if ($function instanceof Zend_Server_Reflection_Function_Abstract) {
00460             $method = $function->getName();
00461         } else {
00462             $method = $function;
00463         }
00464 
00465         $dom = new DOMDocument('1.0', $this->getEncoding());
00466         if ($class) {
00467             $xml       = $dom->createElement($class);
00468             $xmlMethod = $dom->createElement($method);
00469             $xml->appendChild($xmlMethod);
00470         } else {
00471             $xml       = $dom->createElement($method);
00472             $xmlMethod = $xml;
00473         }
00474         $xml->setAttribute('generator', 'zend');
00475         $xml->setAttribute('version', '1.0');
00476         $dom->appendChild($xml);
00477 
00478         $xmlResponse = $dom->createElement('response');
00479         $xmlMethod->appendChild($xmlResponse);
00480 
00481         if ($exception instanceof Exception) {
00482             $element = $dom->createElement('message');
00483             $element->appendChild($dom->createTextNode($exception->getMessage()));
00484             $xmlResponse->appendChild($element);
00485             $code = $exception->getCode();
00486         } elseif (($exception !== null) || 'rest' == $function) {
00487             $xmlResponse->appendChild($dom->createElement('message', 'An unknown error occured. Please try again.'));
00488         } else {
00489             $xmlResponse->appendChild($dom->createElement('message', 'Call to ' . $method . ' failed.'));
00490         }
00491 
00492         $xmlMethod->appendChild($xmlResponse);
00493         $xmlMethod->appendChild($dom->createElement('status', 'failed'));
00494 
00495         // Headers to send
00496         if ($code === null || (404 != $code)) {
00497             $this->_headers[] = 'HTTP/1.0 400 Bad Request';
00498         } else {
00499             $this->_headers[] = 'HTTP/1.0 404 File Not Found';
00500         }
00501 
00502         return $dom;
00503     }
00504 
00510     public function getHeaders()
00511     {
00512         return $this->_headers;
00513     }
00514 
00521     public function addFunction($function, $namespace = '')
00522     {
00523         if (!is_array($function)) {
00524             $function = (array) $function;
00525         }
00526 
00527         foreach ($function as $func) {
00528             if (is_callable($func) && !in_array($func, self::$magicMethods)) {
00529                 $this->_functions[$func] = $this->_reflection->reflectFunction($func);
00530             } else {
00531                 require_once 'Zend/Rest/Server/Exception.php';
00532                 throw new Zend_Rest_Server_Exception("Invalid Method Added to Service.");
00533             }
00534         }
00535     }
00536 
00542     public function getFunctions()
00543     {
00544         return $this->_functions;
00545     }
00546 
00553     public function loadFunctions($functions)
00554     {
00555     }
00556 
00563     public function setPersistence($mode)
00564     {
00565     }
00566 
00574     protected function _callStaticMethod($class, array $args)
00575     {
00576         try {
00577             $result = call_user_func_array(array($class, $this->_functions[$this->_method]->getName()), $args);
00578         } catch (Exception $e) {
00579             $result = $this->fault($e);
00580         }
00581         return $result;
00582     }
00583 
00592     protected function _callObjectMethod($class, array $args)
00593     {
00594         try {
00595             if ($this->_functions[$this->_method]->getDeclaringClass()->getConstructor()) {
00596                 $object = $this->_functions[$this->_method]->getDeclaringClass()->newInstanceArgs($this->_args);
00597             } else {
00598                 $object = $this->_functions[$this->_method]->getDeclaringClass()->newInstance();
00599             }
00600         } catch (Exception $e) {
00601             require_once 'Zend/Rest/Server/Exception.php';
00602             throw new Zend_Rest_Server_Exception('Error instantiating class ' . $class .
00603                                                  ' to invoke method ' . $this->_functions[$this->_method]->getName() .
00604                                                  ' (' . $e->getMessage() . ') ',
00605                                                  500, $e);
00606         }
00607 
00608         try {
00609             $result = $this->_functions[$this->_method]->invokeArgs($object, $args);
00610         } catch (Exception $e) {
00611             $result = $this->fault($e);
00612         }
00613 
00614         return $result;
00615     }
00616 }
 All Data Structures Namespaces Files Functions Variables Enumerations