Example #1
0
 /**
  * Construct a flat array of method arguments for the resource method.
  *
  * @param Route            $route  The route being processed.
  * @param ReflectionMethod $method The resource class method that arguments
  *                                 are needed for.
  *
  * @return array
  */
 protected function _getResourceMethodArguments(Route $route, ReflectionMethod $method)
 {
     $clsRenderable = 'Sonno\\Application\\Renderable';
     $pathParamValues = $this->_uriInfo->getPathParameters();
     $queryParamValues = $this->_uriInfo->getQueryParameters();
     $headerParamValues = $this->_request->getHeaders();
     $pathParams = $route->getPathParams() ?: array();
     $queryParams = $route->getQueryParams() ?: array();
     $headerParams = $route->getHeaderParams() ?: array();
     $formParams = $route->getFormParams() ?: array();
     $resourceMethodArgs = array();
     parse_str($this->_request->getRequestBody(), $formParamValues);
     foreach ($method->getParameters() as $idx => $reflParam) {
         $parameterName = $reflParam->getName();
         $parameterClass = $reflParam->getClass();
         // if the parameter is a type that implements Renderable, use the
         // implementation's unrender() function to generate an instance
         // of the class from the request body as the parameter value
         if (null !== $parameterClass && $parameterClass->implementsInterface($clsRenderable)) {
             $parameterClassName = $parameterClass->getName();
             $parameterValue = $parameterClassName::unrender($this->_request->getRequestBody(), new Variant(null, null, $this->_request->getContentType()));
             $resourceMethodArgs[$idx] = $parameterValue;
         }
         // search for an argument value in the Path parameter collection
         if (in_array($parameterName, $pathParams) && isset($pathParamValues[$parameterName])) {
             $resourceMethodArgs[$idx] = $pathParamValues[$parameterName];
         }
         // search for an argument value in the Query parameter collection
         if (in_array($parameterName, $queryParams) && isset($queryParamValues[$parameterName])) {
             $resourceMethodArgs[$idx] = $queryParamValues[$parameterName];
         }
         // search for an argument value in the Header parameter collection
         if (in_array($parameterName, $headerParams) && isset($headerParamValues[$parameterName])) {
             $resourceMethodArgs[$idx] = $headerParamValues[$parameterName];
         }
         // search for an argument value in the Form parameter collection
         if (in_array($parameterName, $formParams) && isset($formParamValues[$parameterName])) {
             $resourceMethodArgs[$idx] = $formParamValues[$parameterName];
         }
     }
     return $resourceMethodArgs;
 }
Example #2
0
 /**
  * Find candidate routes for an incoming request.
  *
  * @param RequestInterface $request        The incoming request
  * @param array            $pathParameters The set of Path parameters
  *                                         matched on the incoming Request
  *                                         path.
  *
  * @throws \Sonno\Http\Exception\MethodNotAllowedException
  * @throws \Sonno\Http\Exception\NotFoundException
  * @throws \InvalidArgumentException
  * @throws \Sonno\Http\Exception\NotAcceptableException
  *
  * @return array A collection of candidate Route objects.
  *
  * @todo   When filtering candidate routes by matching the incoming
  *         media type, Sonno is ignoring any Content-Type parameters
  *         including the charset. This should be resolved, otherwise there
  *         will be unintended consequences while dealing with charsets and
  *         other Content-Type parameters.
  */
 public function match(RequestInterface $request, &$pathParameters = array())
 {
     if (null == $request) {
         throw new InvalidArgumentException('Missing function argument: request');
     }
     $candidateRoutes = array();
     $allRoutes = $this->_config->getRoutes();
     $requestPath = $request->getRequestUri();
     $requestMethod = $request->getMethod();
     $requestContentType = $request->getContentType();
     // drop the base path from the beginning of the incoming path
     $basePath = $this->_config->getBasePath();
     if ($basePath && strstr($requestPath, $basePath) !== FALSE) {
         $requestPath = substr($requestPath, strlen($basePath));
     }
     // locate matching routes using the incoming request path
     /** @var $route \Sonno\Configuration\Route */
     foreach ($allRoutes as $route) {
         $params = $this->_matchPath($requestPath, $route->getPath());
         if (false !== $params) {
             $pathParameters = $params;
             $candidateRoutes[] = $route;
         }
     }
     if (empty($candidateRoutes)) {
         throw new NotFoundException();
     }
     // filter candidate routes further by matching the incoming request
     // method
     $allowedMethods = array();
     foreach ($candidateRoutes as $i => $route) {
         if ($route->getHttpMethod() != $requestMethod) {
             $allowedMethods[] = $route->getHttpMethod();
             unset($candidateRoutes[$i]);
         }
     }
     if (empty($candidateRoutes)) {
         throw new MethodNotAllowedException($allowedMethods);
     }
     // filter candidate routes further by matching the incoming media type
     if (!empty($requestContentType)) {
         foreach ($candidateRoutes as $i => $route) {
             if (($offset = strpos($requestContentType, ';')) !== false) {
                 $requestContentType = substr($requestContentType, 0, $offset);
             }
             if (!in_array($requestContentType, $route->getConsumes())) {
                 unset($candidateRoutes[$i]);
             }
         }
     }
     if (empty($candidateRoutes)) {
         throw new NotAcceptableException();
     }
     return $candidateRoutes;
 }