1 | <?php |
||
34 | class ViewBuilder |
||
35 | { |
||
36 | |||
37 | use ConfigTrait; |
||
38 | |||
39 | const ENGINE_FINDER_KEY = 'EngineFinder'; |
||
40 | const VIEW_FINDER_KEY = 'ViewFinder'; |
||
41 | |||
42 | /** |
||
43 | * ViewFinder instance. |
||
44 | * |
||
45 | * @since 0.1.0 |
||
46 | * |
||
47 | * @var ViewFinderInterface |
||
48 | */ |
||
49 | protected $viewFinder; |
||
50 | |||
51 | /** |
||
52 | * EngineFinder instance. |
||
53 | * |
||
54 | * @since 0.1.0 |
||
55 | * |
||
56 | * @var EngineFinderInterface |
||
57 | */ |
||
58 | protected $engineFinder; |
||
59 | |||
60 | /** |
||
61 | * Locations to scan for views. |
||
62 | * |
||
63 | * @since 0.1.0 |
||
64 | * |
||
65 | * @var LocationCollection |
||
66 | */ |
||
67 | protected $locations; |
||
68 | |||
69 | /** |
||
70 | * Instantiate a ViewBuilder object. |
||
71 | * |
||
72 | * @since 0.1.0 |
||
73 | * |
||
74 | * @param ConfigInterface $config Configuration settings. |
||
75 | * @param ViewFinderInterface|null $viewFinder ViewFinder instance. |
||
76 | * @param EngineFinderInterface|null $engineFinder EngineFinder instance. |
||
77 | * |
||
78 | * @throws FailedToProcessConfigException If the config could not be processed. |
||
79 | */ |
||
80 | 8 | public function __construct( |
|
81 | ConfigInterface $config, |
||
82 | ViewFinderInterface $viewFinder = null, |
||
83 | EngineFinderInterface $engineFinder = null |
||
84 | ) { |
||
85 | 8 | $this->processConfig($config); |
|
86 | 8 | $this->viewFinder = $viewFinder; |
|
87 | 8 | $this->engineFinder = $engineFinder; |
|
88 | 8 | $this->locations = new LocationCollection(); |
|
89 | 8 | } |
|
90 | |||
91 | /** |
||
92 | * Create a new view for a given URI. |
||
93 | * |
||
94 | * @since 0.1.0 |
||
95 | * |
||
96 | * @param string $view View identifier to create a view for. |
||
97 | * @param mixed $type Type of view to create. |
||
98 | * |
||
99 | * @return ViewInterface Instance of the requested view. |
||
100 | */ |
||
101 | 18 | public function create($view, $type = null) |
|
102 | { |
||
103 | 18 | $uri = $this->scanLocations([$view]); |
|
104 | 18 | $engine = $this->getEngine($uri); |
|
105 | |||
106 | 18 | return $uri |
|
107 | 17 | ? $this->getView($uri, $engine, $type) |
|
108 | 18 | : $this->getViewFinder()->getNullObject(); |
|
109 | } |
||
110 | |||
111 | /** |
||
112 | * Get an Engine that can deal with the given URI. |
||
113 | * |
||
114 | * @since 0.1.0 |
||
115 | * |
||
116 | * @param string|false $uri URI to get an engine for. |
||
117 | * |
||
118 | * @return EngineInterface Instance of an engine that can deal with the given URI. |
||
119 | */ |
||
120 | 18 | public function getEngine($uri) |
|
121 | { |
||
122 | 18 | return $this->getEngineFinder()->find([$uri]); |
|
123 | } |
||
124 | |||
125 | /** |
||
126 | * Get a view for a given URI, engine and type. |
||
127 | * |
||
128 | * @since 0.1.0 |
||
129 | * |
||
130 | * @param string $uri URI to get a view for. |
||
131 | * @param EngineInterface $engine Engine to use for the view. |
||
132 | * @param mixed $type Type of view to get. |
||
133 | * |
||
134 | * @return ViewInterface View that matches the given requirements. |
||
135 | */ |
||
136 | 17 | public function getView($uri, EngineInterface $engine, $type = null) |
|
137 | { |
||
138 | 17 | if (null === $type) { |
|
139 | 17 | return $this->getViewFinder()->find([$uri], $engine); |
|
140 | } |
||
141 | |||
142 | return $this->resolveType($type, $uri, $engine); |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * Get the ViewFinder instance. |
||
147 | * |
||
148 | * @since 0.1.0 |
||
149 | * |
||
150 | * @return ViewFinderInterface Instance of a ViewFinder. |
||
151 | */ |
||
152 | 18 | public function getViewFinder() |
|
153 | { |
||
154 | 18 | return $this->getFinder($this->viewFinder, static::VIEW_FINDER_KEY); |
|
155 | } |
||
156 | |||
157 | /** |
||
158 | * Get the EngineFinder instance. |
||
159 | * |
||
160 | * @since 0.1.0 |
||
161 | * |
||
162 | * @return EngineFinderInterface Instance of a EngineFinder. |
||
163 | */ |
||
164 | 18 | public function getEngineFinder() |
|
165 | { |
||
166 | 18 | return $this->getFinder($this->engineFinder, static::ENGINE_FINDER_KEY); |
|
167 | } |
||
168 | |||
169 | /** |
||
170 | * Add a location to scan with the ViewFinder. |
||
171 | * |
||
172 | * @since 0.1.0 |
||
173 | * |
||
174 | * @param LocationInterface $location Location to scan with the ViewFinder. |
||
175 | */ |
||
176 | 18 | public function addLocation(LocationInterface $location) |
|
177 | { |
||
178 | 18 | $this->locations->add($location); |
|
179 | 18 | } |
|
180 | |||
181 | /** |
||
182 | * Scan Locations for an URI that matches the specified criteria. |
||
183 | * |
||
184 | * @since 0.1.0 |
||
185 | * |
||
186 | * @param array $criteria Criteria to match. |
||
187 | * |
||
188 | * @return string|false URI of the requested view, or false if not found. |
||
189 | */ |
||
190 | 18 | public function scanLocations(array $criteria) |
|
191 | { |
||
192 | return $this->locations->map(function ($location) use ($criteria) { |
||
193 | /** @var LocationInterface $location */ |
||
194 | 18 | return $location->getURI($criteria); |
|
195 | 18 | })->filter(function ($uri) { |
|
196 | 18 | return false !== $uri; |
|
197 | 18 | })->first() ?: false; |
|
198 | } |
||
199 | |||
200 | /** |
||
201 | * Get a finder instance. |
||
202 | * |
||
203 | * @since 0.1.1 |
||
204 | * |
||
205 | * @param mixed $property Property to use. |
||
206 | * @param string $key Configuration key to use. |
||
207 | * |
||
208 | * @return FinderInterface The requested finder instance. |
||
209 | */ |
||
210 | 18 | protected function getFinder(&$property, $key) |
|
219 | |||
220 | /** |
||
221 | * Resolve the view type. |
||
222 | * |
||
223 | * @since 0.1.0 |
||
224 | * |
||
225 | * @param mixed $type Type of view that was requested. |
||
226 | * @param string $uri URI to get a view for. |
||
227 | * @param EngineInterface|null $engine Engine to use for the view. |
||
228 | * |
||
229 | * @return ViewInterface Resolved View object. |
||
230 | * @throws FailedToInstantiateViewException If the view type could not be resolved. |
||
231 | */ |
||
232 | protected function resolveType($type, $uri, EngineInterface $engine = null) |
||
260 | } |
||
261 |