Source of file AcceptableViewModelSelector.php
Size: 8,491 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/Mvc/Controller/Plugin/AcceptableViewModelSelector.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 | <?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\Mvc\Controller\Plugin; use Zend\Http\Header\Accept\FieldValuePart\AbstractFieldValuePart; use Zend\Http\Request; use Zend\Mvc\InjectApplicationEventInterface; use Zend\Mvc\MvcEvent; use Zend\Mvc\Exception\DomainException; use Zend\Mvc\Exception\InvalidArgumentException; use Zend\View\Model\ModelInterface; /** * Controller Plugin to assist in selecting an appropriate View Model type based on the * User Agent's accept header. */ class AcceptableViewModelSelector extends AbstractPlugin { /** * * @var string the Key to inject the name of a viewmodel with in an Accept Header */ const INJECT_VIEWMODEL_NAME = '_internalViewModel'; /** * * @var \Zend\Mvc\MvcEvent */ protected $event; /** * * @var \Zend\Http\Request */ protected $request; /** * Default array to match against. * * @var Array */ protected $defaultMatchAgainst; /** * * @var string Default ViewModel */ protected $defaultViewModelName = 'Zend\View\Model\ViewModel'; /** * 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 __invoke( array $matchAgainst = null, $returnDefault = true, & $resultReference = null ) { return $this->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 null; } if (!$matchAgainst) { $matchAgainst = $this->defaultMatchAgainst; } $matchAgainstString = ''; foreach ($matchAgainst as $modelName => $modelStrings) { foreach ((array) $modelStrings as $modelString) { $matchAgainstString .= $this->injectViewModelName($modelString, $modelName); } } /** @var $accept \Zend\Http\Header\Accept */ $accept = $headers->get('Accept'); if (($res = $accept->match($matchAgainstString)) === false) { return null; } 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); 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; } } |