/** * Detect an instance of a representation class using a matched route, or default representation classes * @param RouteMetaData $route * @param Mapping\RouteMetaData $route * @throws UnableToMatchRepresentationException * @throws RepresentationException - if unable to instantiate a representation object from config settings * @return AbstractRepresentation $representation */ protected function getDeterminedRepresentation(Mapping\RouteMetaData &$route = null) { $representations = !is_null($route) ? $route->getClassMetaData()->getRepresentations() : $this->config->getDefaultRepresentations(); if (empty($representations)) { throw RepresentationException::noRepresentationsSetForRoute($route->getName(), $route->getClassMetaData()->getClassName()); } $representationObjects = array(); foreach ($representations as $representation) { if (!is_object($representation)) { // Check if the class is namespaced, if so instantiate from root $className = strstr($representation, '\\') !== false ? '\\' . ltrim($representation, '\\') : $representation; $className = !class_exists($className) ? '\\DrestCommon\\Representation\\' . ltrim($className, '\\') : $className; if (!class_exists($className)) { throw RepresentationException::unknownRepresentationClass($representation); } $representationObjects[] = $representation = new $className(); } if (!$representation instanceof AbstractRepresentation) { throw RepresentationException::representationMustBeInstanceOfDrestRepresentation(); } switch ($this->request->getHttpMethod()) { // Match on content option case Request::METHOD_GET: // This representation matches the required media type requested by the client if ($representation->isExpectedContent($this->config->getDetectContentOptions(), $this->request)) { return $representation; } break; // Match on content-type // Match on content-type case Request::METHOD_POST: case Request::METHOD_PUT: case Request::METHOD_PATCH: if ($representation->getContentType() === $this->request->getHeaders('Content-Type')) { return $representation; } break; } } // For get requests with "415 for no media match" set on, throw an exception if ($this->request->getHttpMethod() == Request::METHOD_GET && $this->config->get415ForNoMediaMatchSetting()) { throw UnableToMatchRepresentationException::noMatch(); } // Return the first instantiated representation instance if (isset($representationObjects[0])) { return $representationObjects[0]; } // We have no representation instances from either annotations or config object throw UnableToMatchRepresentationException::noMatch(); }
/** * Does this request match the route pattern * @param Request $request * @param boolean $matchVerb - Whether you want to match the route using the request HTTP verb * - useful for OPTIONS requests to provide route info * @param string $basePath - add a base path to the route pattern * @return boolean $result */ public function matches(Request $request, $matchVerb = true, $basePath = null) { // If we're matching the verb and we've defined them, ensure the method used is in our list of registered verbs if ($matchVerb && $this->routeMetaData->usesHttpVerbs() && !$this->methodIsInOurListOfAllowedVerbs($request->getHttpMethod())) { return false; } $patternAsRegex = $this->getMatchRegexPattern($basePath); //Cache URL params' names and values if this route matches the current HTTP request if (!preg_match('#^' . $patternAsRegex . '$#', $request->getPath(), $paramValues)) { return false; } // Process the param names and save them on the route params $this->processRouteParams($paramValues); // Check the route conditions if (!$this->routeConditionsAreValid()) { return false; } return true; }
/** * Determine the representation by inspecting the HTTP method * @param AbstractRepresentation $representation * @param array $detectContentOptions - Eg array(self::DETECT_CONTENT_HEADER => 'Accept') * @return AbstractRepresentation|null */ protected function determineRepresentationByHttpMethod(AbstractRepresentation $representation, array $detectContentOptions = []) { switch ($this->request->getHttpMethod()) { // Match on content option case Request::METHOD_GET: // This representation matches the required media type requested by the client if ($representation->isExpectedContent($detectContentOptions, $this->request)) { return $representation; } break; // Match on content-type // Match on content-type case Request::METHOD_POST: case Request::METHOD_PUT: case Request::METHOD_PATCH: if ($representation->getContentType() === $this->request->getHeaders('Content-Type')) { return $representation; } break; } return null; }
/** * Does this request matches the route pattern * @param Request $request * @param boolean $matchVerb - Whether you want to match the route using the request HTTP verb * - useful for OPTIONS requests * @param string $basePath - add a base path to the route pattern * @return boolean $result */ public function matches(Request $request, $matchVerb = true, $basePath = null) { if ($matchVerb && $this->usesHttpVerbs()) { try { $method = $request->getHttpMethod(); if (!in_array($method, $this->verbs)) { return false; } } catch (DrestException $e) { return false; } } //Convert URL params into regex patterns, construct a regex for this route, init params $routePattern = is_null($basePath) ? (string) $this->route_pattern : '/' . $basePath . '/' . ltrim((string) $this->route_pattern, '/'); $patternAsRegex = preg_replace_callback('#:([\\w]+)\\+?#', array($this, 'matchesCallback'), str_replace(')', ')?', $routePattern)); if (substr($this->route_pattern, -1) === '/') { $patternAsRegex .= '?'; } //Cache URL params' names and values if this route matches the current HTTP request if (!preg_match('#^' . $patternAsRegex . '$#', $request->getPath(), $paramValues)) { return false; } foreach ($this->param_names as $name) { if (isset($paramValues[$name])) { if (isset($this->param_names_path[$name])) { $parts = explode('/', urldecode($paramValues[$name])); $this->route_params[$name] = array_shift($parts); $this->unmapped_route_params = $parts; } else { $this->route_params[$name] = urldecode($paramValues[$name]); } } } // Check the route conditions foreach ($this->route_conditions as $key => $condition) { if (!preg_match('/^' . $condition . '$/', $this->route_params[$key])) { $this->param_names_path = $this->route_params = $this->unmapped_route_params = array(); return false; } } return true; }