* @copyright 2012-2013 Jurian Sluiman. * @license http://www.opensource.org/licenses/bsd-license.php BSD License * @link http://juriansluiman.nl */ namespace SlmLocale\Locale; use Laminas\EventManager\EventManagerAwareInterface; use Laminas\EventManager\EventManagerInterface; use Laminas\Stdlib\RequestInterface; use Laminas\Stdlib\ResponseInterface; use Laminas\Uri\Uri; use SlmLocale\LocaleEvent; use SlmLocale\Strategy\StrategyInterface; class Detector implements EventManagerAwareInterface { /** * Event manager holding the different strategies * * @var EventManagerInterface */ protected $events; /** * Default locale * * @var string */ protected $default; /** * Optional list of supported locales * * @var array */ protected $supported; /** * Optional list of locale mappings * * @var array */ protected $mappings; public function getEventManager() { return $this->events; } public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers([ __CLASS__, get_called_class(), ]); $this->events = $events; return $this; } public function addStrategy(StrategyInterface $strategy, $priority = 1) { $strategy->attach($this->getEventManager(), $priority); } public function getDefault() { return $this->default; } public function setDefault($default) { $this->default = $default; return $this; } public function getSupported() { return $this->supported; } public function setSupported(array $supported) { $this->supported = $supported; return $this; } public function hasSupported() { return is_array($this->supported) && count($this->supported); } public function getMappings() { return $this->mappings; } public function setMappings(array $mappings) { $this->mappings = $mappings; return $this; } public function hasMappings() { return is_array($this->mappings) && count($this->mappings); } public function detect(RequestInterface $request, ResponseInterface $response = null) { $event = new LocaleEvent(LocaleEvent::EVENT_DETECT, $this); $event->setRequest($request); $event->setResponse($response); if ($this->hasSupported()) { $event->setSupported($this->getSupported()); } $events = $this->getEventManager(); $results = $events->triggerEventUntil(function ($r) { return is_string($r); }, $event); if ($results->stopped()) { $locale = $results->last(); } else { $locale = $this->getDefault(); } if ($this->hasSupported() && ! in_array($locale, $this->getSupported())) { $locale = $this->getDefault(); } if ($this->hasMappings() && array_key_exists($locale, $this->getMappings())) { $mappings = $this->getMappings(); $locale = $mappings[$locale]; } // Trigger FOUND event only when a response is given if ($response instanceof ResponseInterface) { $event->setName(LocaleEvent::EVENT_FOUND); $event->setLocale($locale); $return = false; /** * The response will be returned instead of the found locale * only in case a strategy returned the response. This is an * indication the strategy has updated the response (e.g. with * a Location header) and as such, the response must be returned * instead of the locale. */ $events->triggerEventUntil(function ($r) use (&$return) { if ($r instanceof ResponseInterface) { $return = true; } }, $event); if ($return) { return $response; } } return $locale; } public function assemble($locale, $uri, RequestInterface $request) { $event = new LocaleEvent(LocaleEvent::EVENT_ASSEMBLE, $this); $event->setLocale($locale); $event->setRequest($request); if ($this->hasSupported()) { $event->setSupported($this->getSupported()); } if (! $uri instanceof Uri) { $uri = new Uri($uri); } $event->setUri($uri); $events = $this->getEventManager(); $results = $events->triggerEvent($event); if (! $results->stopped()) { return $uri; } return $results->last(); } }