getViewModel($matchAgainst, $returnDefault, $resultReference); } /** * Detects an appropriate viewmodel for request. * * @param array $matchAgainst (optional) The Array to match against * @param bool $returnDefault (optional) If no match is available. Return default instead * @param AbstractFieldValuePart|null $resultReference (optional) The object that was matched * @throws InvalidArgumentException If the supplied and matched View Model could not be found * @return ModelInterface|null */ public function getViewModel( array $matchAgainst = null, $returnDefault = true, & $resultReference = null ) { $name = $this->getViewModelName($matchAgainst, $returnDefault, $resultReference); if (! $name) { return; } if (! class_exists($name)) { throw new InvalidArgumentException('The supplied View Model could not be found'); } return new $name(); } /** * Detects an appropriate viewmodel name for request. * * @param array $matchAgainst (optional) The Array to match against * @param bool $returnDefault (optional) If no match is available. Return default instead * @param AbstractFieldValuePart|null $resultReference (optional) The object that was matched. * @return ModelInterface|null Returns null if $returnDefault = false and no match could be made */ public function getViewModelName( array $matchAgainst = null, $returnDefault = true, & $resultReference = null ) { $res = $this->match($matchAgainst); if ($res) { $resultReference = $res; return $this->extractViewModelName($res); } if ($returnDefault) { return $this->defaultViewModelName; } } /** * Detects an appropriate viewmodel name for request. * * @param array $matchAgainst (optional) The Array to match against * @return AbstractFieldValuePart|null The object that was matched */ public function match(array $matchAgainst = null) { $request = $this->getRequest(); $headers = $request->getHeaders(); if ((! $matchAgainst && ! $this->defaultMatchAgainst) || ! $headers->has('accept')) { return; } if (! $matchAgainst) { $matchAgainst = $this->defaultMatchAgainst; } $matchAgainstString = ''; foreach ($matchAgainst as $modelName => $modelStrings) { foreach ((array) $modelStrings as $modelString) { $matchAgainstString .= $this->injectViewModelName($modelString, $modelName); } } /** @var $accept \Laminas\Http\Header\Accept */ $accept = $headers->get('Accept'); if (($res = $accept->match($matchAgainstString)) === false) { return; } return $res; } /** * Set the default View Model (name) to return if no match could be made * @param string $defaultViewModelName The default View Model name * @return AcceptableViewModelSelector provides fluent interface */ public function setDefaultViewModelName($defaultViewModelName) { $this->defaultViewModelName = (string) $defaultViewModelName; return $this; } /** * Set the default View Model (name) to return if no match could be made * @return string */ public function getDefaultViewModelName() { return $this->defaultViewModelName; } /** * Set the default Accept Types and View Model combinations to match against if none are specified. * * @param array $matchAgainst (optional) The Array to match against * @return AcceptableViewModelSelector provides fluent interface */ public function setDefaultMatchAgainst(array $matchAgainst = null) { $this->defaultMatchAgainst = $matchAgainst; return $this; } /** * Get the default Accept Types and View Model combinations to match against if none are specified. * * @return array|null */ public function getDefaultMatchAgainst() { return $this->defaultMatchAgainst; } /** * Inject the viewmodel name into the accept header string * * @param string $modelAcceptString * @param string $modelName * @return string */ protected function injectViewModelName($modelAcceptString, $modelName) { $modelName = str_replace('\\', '|', $modelName); $modelAcceptString = (is_array($modelAcceptString)) ? $modelAcceptString[key($modelAcceptString)] : $modelAcceptString; return $modelAcceptString . '; ' . self::INJECT_VIEWMODEL_NAME . '="' . $modelName . '", '; } /** * Extract the viewmodel name from a match * @param AbstractFieldValuePart $res * @return string */ protected function extractViewModelName(AbstractFieldValuePart $res) { $modelName = $res->getMatchedAgainst()->params[self::INJECT_VIEWMODEL_NAME]; return str_replace('|', '\\', $modelName); } /** * Get the request * * @return Request * @throws DomainException if unable to find request */ protected function getRequest() { if ($this->request) { return $this->request; } $event = $this->getEvent(); $request = $event->getRequest(); if (! $request instanceof Request) { throw new DomainException( 'The event used does not contain a valid Request, but must.' ); } $this->request = $request; return $request; } /** * Get the event * * @return MvcEvent * @throws DomainException if unable to find event */ protected function getEvent() { if ($this->event) { return $this->event; } $controller = $this->getController(); if (! $controller instanceof InjectApplicationEventInterface) { throw new DomainException( 'A controller that implements InjectApplicationEventInterface ' . 'is required to use ' . __CLASS__ ); } $event = $controller->getEvent(); if (! $event instanceof MvcEvent) { $params = $event->getParams(); $event = new MvcEvent(); $event->setParams($params); } $this->event = $event; return $this->event; } }