composer package updates
[openemr.git] / vendor / zendframework / zend-navigation / src / Service / AbstractNavigationFactory.php
blob2e8faaf207aa14197d389215533b87ff9cd50e8e
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Navigation\Service;
12 use Interop\Container\ContainerInterface;
13 use Traversable;
14 use Zend\Config;
15 use Zend\Http\Request;
16 use Zend\Mvc\Router as MvcRouter;
17 use Zend\Navigation\Exception;
18 use Zend\Navigation\Navigation;
19 use Zend\Router\RouteMatch;
20 use Zend\Router\RouteStackInterface as Router;
21 use Zend\ServiceManager\FactoryInterface;
22 use Zend\ServiceManager\ServiceLocatorInterface;
23 use Zend\Stdlib\ArrayUtils;
25 /**
26 * Abstract navigation factory
28 abstract class AbstractNavigationFactory implements FactoryInterface
30 /**
31 * @var array
33 protected $pages;
35 /**
36 * Create and return a new Navigation instance (v3).
38 * @param ContainerInterface $container
39 * @param string $requestedName
40 * @param null|array $options
41 * @return Navigation
43 public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
45 return new Navigation($this->getPages($container));
48 /**
49 * Create and return a new Navigation instance (v2).
51 * @param ServiceLocatorInterface $container
52 * @param null|string $name
53 * @param null|string $requestedName
54 * @return Navigation
56 public function createService(ServiceLocatorInterface $container)
58 return $this($container, Navigation::class);
61 /**
62 * @abstract
63 * @return string
65 abstract protected function getName();
67 /**
68 * @param ContainerInterface $container
69 * @return array
70 * @throws \Zend\Navigation\Exception\InvalidArgumentException
72 protected function getPages(ContainerInterface $container)
74 if (null === $this->pages) {
75 $configuration = $container->get('config');
77 if (! isset($configuration['navigation'])) {
78 throw new Exception\InvalidArgumentException('Could not find navigation configuration key');
80 if (! isset($configuration['navigation'][$this->getName()])) {
81 throw new Exception\InvalidArgumentException(sprintf(
82 'Failed to find a navigation container by the name "%s"',
83 $this->getName()
84 ));
87 $pages = $this->getPagesFromConfig($configuration['navigation'][$this->getName()]);
88 $this->pages = $this->preparePages($container, $pages);
90 return $this->pages;
93 /**
94 * @param ContainerInterface $container
95 * @param array|\Zend\Config\Config $pages
96 * @return null|array
97 * @throws \Zend\Navigation\Exception\InvalidArgumentException
99 protected function preparePages(ContainerInterface $container, $pages)
101 $application = $container->get('Application');
102 $routeMatch = $application->getMvcEvent()->getRouteMatch();
103 $router = $application->getMvcEvent()->getRouter();
104 $request = $application->getMvcEvent()->getRequest();
106 // HTTP request is the only one that may be injected
107 if (! $request instanceof Request) {
108 $request = null;
111 return $this->injectComponents($pages, $routeMatch, $router, $request);
115 * @param string|\Zend\Config\Config|array $config
116 * @return array|null|\Zend\Config\Config
117 * @throws \Zend\Navigation\Exception\InvalidArgumentException
119 protected function getPagesFromConfig($config = null)
121 if (is_string($config)) {
122 if (! file_exists($config)) {
123 throw new Exception\InvalidArgumentException(sprintf(
124 'Config was a string but file "%s" does not exist',
125 $config
128 $config = Config\Factory::fromFile($config);
129 } elseif ($config instanceof Traversable) {
130 $config = ArrayUtils::iteratorToArray($config);
131 } elseif (! is_array($config)) {
132 throw new Exception\InvalidArgumentException(
133 'Invalid input, expected array, filename, or Traversable object'
137 return $config;
141 * @param array $pages
142 * @param RouteMatch|MvcRouter\RouteMatch $routeMatch
143 * @param Router|MvcRouter\RouteStackInterface $router
144 * @param null|Request $request
145 * @return array
147 protected function injectComponents(
148 array $pages,
149 $routeMatch = null,
150 $router = null,
151 $request = null
153 $this->validateRouteMatch($routeMatch);
154 $this->validateRouter($router);
156 foreach ($pages as &$page) {
157 $hasUri = isset($page['uri']);
158 $hasMvc = isset($page['action']) || isset($page['controller']) || isset($page['route']);
159 if ($hasMvc) {
160 if (! isset($page['routeMatch']) && $routeMatch) {
161 $page['routeMatch'] = $routeMatch;
163 if (! isset($page['router'])) {
164 $page['router'] = $router;
166 } elseif ($hasUri) {
167 if (! isset($page['request'])) {
168 $page['request'] = $request;
172 if (isset($page['pages'])) {
173 $page['pages'] = $this->injectComponents($page['pages'], $routeMatch, $router, $request);
176 return $pages;
180 * Validate that a route match argument provided to injectComponents is valid.
182 * @param null|RouteMatch|MvcRouter\RouteMatch
183 * @return void
184 * @throws Exception\InvalidArgumentException
186 private function validateRouteMatch($routeMatch)
188 if (null === $routeMatch) {
189 return;
192 if (! $routeMatch instanceof RouteMatch
193 && ! $routeMatch instanceof MvcRouter\RouteMatch
195 throw new Exception\InvalidArgumentException(sprintf(
196 '%s or %s expected by %s::injectComponents; received %s',
197 RouteMatch::class,
198 MvcRouter\RouteMatch::class,
199 __CLASS__,
200 (is_object($routeMatch) ? get_class($routeMatch) : gettype($routeMatch))
206 * Validate that a router argument provided to injectComponents is valid.
208 * @param null|Router|MvcRouter\RouteStackInterface
209 * @return void
210 * @throws Exception\InvalidArgumentException
212 private function validateRouter($router)
214 if (null === $router) {
215 return;
218 if (! $router instanceof Router
219 && ! $router instanceof MvcRouter\RouteStackInterface
221 throw new Exception\InvalidArgumentException(sprintf(
222 '%s or %s expected by %s::injectComponents; received %s',
223 RouteMatch::class,
224 MvcRouter\RouteMatch::class,
225 __CLASS__,
226 (is_object($router) ? get_class($router) : gettype($router))