Example #1
0
 private function routeRequest(Request $request, Service $service)
 {
     $desired_method = String::underscoreToCamelCase($request->getMethod());
     $requested_method = $request->getRequestMethod() . $desired_method;
     $method = $requested_method;
     $arguments = $request->getArguments();
     if (!method_exists($service, $method)) {
         $method = $request->getRequestMethod() . 'Router';
         if (!method_exists($service, $method)) {
             throw new MethodNotSupported($request->getService(), $requested_method);
         }
         array_splice($arguments, 0, 0, array($request->getMethod()));
     }
     $output = call_user_func_array(array($service, $method), $arguments);
     $this->response->setResponse($output);
 }
Example #2
0
 public function handleRequest()
 {
     $request = new Request($_SERVER);
     // OPTIONS is used by cors for the preflight, so it must be accepted
     if ($request->getMethod() != 'OPTIONS') {
         // See if service is specified
         if ($request->getService()) {
             $service = $this->findService($request);
             if ($service !== NULL) {
                 $method = $this->findMethod($service, $request);
                 if ($method !== NULL) {
                     // Check for use of annotation @Authenticated
                     if (!$method->requiresAuthentication() || $method->requiresAuthentication() && $this->isAuthenticated()) {
                         // Check for use of annotation @AccessLevel
                         if ($this->getAccessLevel() >= $method->requiredAccessLevel()) {
                             $result = NULL;
                             // Analyze the service method and invoke it "the best way"(tm)
                             $parameters = $method->getParameters();
                             if (count($parameters) > 0) {
                                 $data = $request->getData();
                                 $paramClass = $parameters[0]->getClass();
                                 /* If the method takes a special object, we try to create an
                                  * object of this kind and fill it with data from the request
                                  *
                                  * We don't try to fit anonymous arguments to service
                                  * methods that uses classes
                                  */
                                 if ($paramClass !== NULL) {
                                     $paramClassName = $paramClass->name;
                                     $requestObj = new $paramClassName();
                                     $classVars = get_class_vars($paramClassName);
                                     // Request ex: {"user":{"name":"a","pass":"b"}}
                                     $arrayValues = array_values($data);
                                     if (count($data) === 1 && is_array($arrayValues[0])) {
                                         $data = array_pop($data);
                                     }
                                     if (is_array($data)) {
                                         $data = array_change_key_case($data);
                                         foreach ($classVars as $attr => $defaultVal) {
                                             if (isset($data[strtolower($attr)])) {
                                                 $requestObj->{$attr} = $data[strtolower($attr)];
                                             }
                                         }
                                     }
                                     // Combine object and anonymous data (for subroutes)
                                     $input = array_merge(array($requestObj), $request->getAnonymousData());
                                     try {
                                         $result = $method->invokeArgs($service, $input);
                                     } catch (Exception $e) {
                                         $result = $e;
                                     }
                                     /* If no object, we try to rearrange the request data to
                                      * match paramter names in the method
                                      */
                                 } else {
                                     // Try to make each param come in right order
                                     $input = array();
                                     foreach ($parameters as $param) {
                                         if (isset($data[strtolower($param->name)])) {
                                             $input[] = $data[strtolower($param->name)];
                                         } else {
                                             /* Where we don't have arguments available, we put
                                              * NULLs so that we can find these holes later and
                                              * use anonymous arguments to fill them
                                              */
                                             $input[] = NULL;
                                         }
                                     }
                                     // Try to fill in the blanks with unnamed request data
                                     $data = $request->getAnonymousData();
                                     foreach ($input as $key => &$inputData) {
                                         if ($inputData === NULL) {
                                             $anonymous = array_shift($data);
                                             if ($anonymous !== NULL) {
                                                 $inputData = $anonymous;
                                             } else {
                                                 /* We are out of anonymous data to use, but perhaps
                                                  * the parameter is optional with a default value
                                                  * and we don't have to send in NULL
                                                  */
                                                 if ($parameters[$key]->isOptional()) {
                                                     $inputData = $parameters[$key]->getDefaultValue();
                                                 }
                                             }
                                         }
                                     }
                                     try {
                                         $result = $method->invokeArgs($service, $input);
                                     } catch (Exception $e) {
                                         $result = $e;
                                     }
                                 }
                             } else {
                                 try {
                                     $result = $method->invoke($service);
                                 } catch (Exception $e) {
                                     $result = $e;
                                 }
                             }
                             if ($result instanceof Exception) {
                                 if ($result instanceof ServiceException) {
                                     $this->response->setHttpStatus($result->getCode());
                                     $this->response->setContent($result->getMessage());
                                 } else {
                                     $this->response->setHttpStatus(HttpStatus::INTERNAL_SERVER_ERROR);
                                     $this->response->setContent($result->getMessage());
                                 }
                             } else {
                                 $this->response->setContentType($method->getContentType());
                                 if ($result !== NULL) {
                                     $this->response->setContent($result);
                                 }
                             }
                         } else {
                             $this->response->setHttpStatus(HttpStatus::METHOD_NOT_ALLOWED);
                         }
                     } else {
                         $this->response->setHttpStatus(HttpStatus::UNAUTHORIZED);
                     }
                 } else {
                     $this->response->setHttpStatus(HttpStatus::NOT_IMPLEMENTED);
                 }
             } else {
                 $this->response->setHttpStatus(HttpStatus::NOT_FOUND);
             }
         } else {
             $this->response->setContentType('text/html');
             $this->response->setContent($this->createIndex());
         }
     }
     $this->sendResponse();
 }