Esempio n. 1
0
 /**
  * Find the api method to execute for the requested Url
  */
 protected function route()
 {
     $this->dispatch('route');
     $params = $this->getRequestData();
     //backward compatibility for restler 2 and below
     if (!Defaults::$smartParameterParsing) {
         $params = $params + array(Defaults::$fullRequestDataName => $params);
     }
     $this->apiMethodInfo = $o = Routes::find($this->url, $this->requestMethod, $this->requestedApiVersion, $params);
     //set defaults based on api method comments
     if (isset($o->metadata)) {
         foreach (Defaults::$fromComments as $key => $defaultsKey) {
             if (array_key_exists($key, $o->metadata)) {
                 $value = $o->metadata[$key];
                 Defaults::setProperty($defaultsKey, $value);
             }
         }
     }
     if (!isset($o->className)) {
         throw new RestException(404);
     }
     if (isset($this->apiVersionMap[$o->className])) {
         Scope::$classAliases[Util::getShortName($o->className)] = $this->apiVersionMap[$o->className][$this->requestedApiVersion];
     }
     foreach ($this->authClasses as $auth) {
         if (isset($this->apiVersionMap[$auth])) {
             Scope::$classAliases[$auth] = $this->apiVersionMap[$auth][$this->requestedApiVersion];
         } elseif (isset($this->apiVersionMap[Scope::$classAliases[$auth]])) {
             Scope::$classAliases[$auth] = $this->apiVersionMap[Scope::$classAliases[$auth]][$this->requestedApiVersion];
         }
     }
 }
 /**
  * Main function for processing the api request
  * and return the response
  *
  * @throws Exception     when the api service class is missing
  * @throws RestException to send error response
  */
 public function handle()
 {
     try {
         $this->init();
         foreach ($this->filterClasses as $filterClass) {
             /**
              * @var iFilter
              */
             $filterObj = new $filterClass();
             $filterObj->restler = $this;
             if (!$filterObj instanceof iFilter) {
                 throw new RestException(500, 'Filter Class ' . 'should implement iFilter');
             } else {
                 $ok = $filterObj->__isAllowed();
                 if (is_null($ok) && $filterObj instanceof iUseAuthentication) {
                     //handle at authentication stage
                     $this->filterObjects[] = $filterObj;
                     continue;
                 }
                 throw new RestException(403);
                 //Forbidden
             }
         }
         Util::setProperties(get_class($this->requestFormat), null, $this->requestFormat);
         $this->requestData = $this->getRequestData();
         //parse defaults
         foreach ($_GET as $key => $value) {
             if (isset(Defaults::$aliases[$key])) {
                 $_GET[Defaults::$aliases[$key]] = $value;
                 unset($_GET[$key]);
                 $key = Defaults::$aliases[$key];
             }
             if (in_array($key, Defaults::$overridables)) {
                 Defaults::setProperty($key, $value);
             }
         }
         $this->apiMethodInfo = $o = $this->mapUrlToMethod();
         if (isset($o->metadata)) {
             foreach (Defaults::$fromComments as $key => $defaultsKey) {
                 if (array_key_exists($key, $o->metadata)) {
                     $value = $o->metadata[$key];
                     Defaults::setProperty($defaultsKey, $value);
                 }
             }
         }
         $result = null;
         if (!isset($o->className)) {
             $this->handleError(404);
         } else {
             try {
                 $accessLevel = max(Defaults::$apiAccessLevel, $o->accessLevel);
                 if ($accessLevel || count($this->filterObjects)) {
                     if (!count($this->authClasses)) {
                         throw new RestException(401);
                     }
                     foreach ($this->authClasses as $authClass) {
                         $authObj = Util::setProperties($authClass, $o->metadata);
                         if (!method_exists($authObj, Defaults::$authenticationMethod)) {
                             throw new RestException(500, 'Authentication Class ' . 'should implement iAuthenticate');
                         } elseif (!$authObj->{Defaults::$authenticationMethod}()) {
                             throw new RestException(401);
                         }
                     }
                     $this->authenticated = true;
                 }
             } catch (RestException $e) {
                 if ($accessLevel > 1) {
                     //when it is not a hybrid api
                     $this->handleError($e->getCode(), $e->getMessage());
                 } else {
                     $this->authenticated = false;
                 }
             }
             try {
                 foreach ($this->filterObjects as $filterObj) {
                     Util::setProperties(get_class($filterObj), $o->metadata, $filterObj);
                 }
                 $preProcess = '_' . $this->requestFormat->getExtension() . '_' . $o->methodName;
                 $this->apiMethod = $o->methodName;
                 $object = $this->apiClassInstance = null;
                 // TODO:check if the api version requested is allowed by class
                 if (Defaults::$autoValidationEnabled) {
                     foreach ($o->metadata['param'] as $index => $param) {
                         $info =& $param[CommentParser::$embeddedDataName];
                         if (!isset($info['validate']) || $info['validate'] != false) {
                             if (isset($info['method'])) {
                                 if (!isset($object)) {
                                     $object = $this->apiClassInstance = Util::setProperties($o->className);
                                 }
                                 $info['apiClassInstance'] = $object;
                             }
                             //convert to instance of ValidationInfo
                             $info = new ValidationInfo($param);
                             $valid = Validator::validate($o->arguments[$index], $info);
                             $o->arguments[$index] = $valid;
                         }
                     }
                 }
                 if (!isset($object)) {
                     $object = $this->apiClassInstance = Util::setProperties($o->className);
                 }
                 if (method_exists($o->className, $preProcess)) {
                     call_user_func_array(array($object, $preProcess), $o->arguments);
                 }
                 switch ($accessLevel) {
                     case 3:
                         //protected method
                         $reflectionMethod = new ReflectionMethod($object, $o->methodName);
                         $reflectionMethod->setAccessible(true);
                         $result = $reflectionMethod->invokeArgs($object, $o->arguments);
                         break;
                     default:
                         $result = call_user_func_array(array($object, $o->methodName), $o->arguments);
                 }
             } catch (RestException $e) {
                 $this->handleError($e->getCode(), $e->getMessage());
             }
         }
         $this->sendData($result);
     } catch (RestException $e) {
         $this->handleError($e->getCode(), $e->getMessage());
     } catch (\Exception $e) {
         $this->log[] = $e->getMessage();
         if ($this->productionMode) {
             $this->handleError(500);
         } else {
             $this->handleError(500, $e->getMessage());
         }
     }
 }
Esempio n. 3
0
 /**
  * Find the api method to execute for the requested Url
  */
 protected function route()
 {
     $this->dispatch('route');
     $params = $this->getRequestData();
     $currentUrl = 'v' . $this->requestedApiVersion;
     if (!empty($this->url)) {
         $currentUrl .= '/' . $this->url;
     }
     $this->apiMethodInfo = $o = Routes::find($currentUrl, $this->requestMethod, $params);
     //set defaults based on api method comments
     if (isset($o->metadata)) {
         foreach (Defaults::$fromComments as $key => $defaultsKey) {
             if (array_key_exists($key, $o->metadata)) {
                 $value = $o->metadata[$key];
                 Defaults::setProperty($defaultsKey, $value);
             }
         }
     }
     if (!isset($o->className)) {
         throw new RestException(404);
     }
 }