/** * 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(); }
/** * 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; }
/** * Uses configuration options to determine whether this writer instance is the media type expected by the client * @param array $configOptions - configuration options for content detection * @param Request $request - request object * @return boolean $result */ public final function isExpectedContent(array $configOptions, Request $request) { foreach ($configOptions as $detectContentOption => $detectContentValue) { switch ($detectContentOption) { case 1: // HTTP Header $headers = explode(',', $request->getHeaders($detectContentValue)); foreach ($headers as $headerEntry) { if (false !== ($pos = strpos($headerEntry, ';'))) { $headerEntry = substr($headerEntry, 0, $pos); } // See if the header matches for this writer if (in_array(trim($headerEntry), $this->getMatchableAcceptHeaders())) { return true; } } break; case 2: // Extension // See if an extension has been supplied $ext = $request->getExtension(); if (!empty($ext) && in_array($request->getExtension(), $this->getMatchableExtensions())) { return true; } break; case 3: // Parameter // Inspect the request object for a "format" parameter if (in_array($request->getQuery($detectContentValue), $this->getMatchableFormatParams())) { return true; } break; } } return false; }
/** * Configure the expose object to filter out fields that have been explicitly requested by the client. * This is only applicable for a HTTP pull (GET) call. For configuring * @param array $requestOptions * @param Request $request * @return ExposeFields $this object instance */ public function configurePullRequest(array $requestOptions, Request $request) { if (empty($this->route_expose)) { $exposeString = ''; foreach ($requestOptions as $requestOption => $requestValue) { switch ($requestOption) { case Configuration::EXPOSE_REQUEST_HEADER: $exposeString = $request->getHeaders($requestValue); break; case Configuration::EXPOSE_REQUEST_PARAM: $exposeString = $request->getParams($requestValue); break; case Configuration::EXPOSE_REQUEST_PARAM_GET: $exposeString = $request->getQuery($requestValue); break; case Configuration::EXPOSE_REQUEST_PARAM_POST: $exposeString = $request->getPost($requestValue); break; } } if (!empty($exposeString)) { $requestedExposure = $this->parseExposeString($exposeString); $this->filterRequestedExpose($requestedExposure, $this->fields); $this->fields = $requestedExposure; } } return $this; }