Completed
Pull Request — master (#81)
by
unknown
02:53
created

View   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 336
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 2 Features 0
Metric Value
wmc 36
c 3
b 2
f 0
lcom 3
cbo 2
dl 0
loc 336
ccs 0
cts 168
cp 0
rs 8.8

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A baseURL() 0 4 1
A currentURL() 0 4 1
A currentURI() 0 4 1
B render() 0 29 6
A prepareView() 0 23 3
A setView() 0 7 2
A setProperty() 0 9 3
A setLayout() 0 16 3
A setModule() 0 9 2
A process() 0 17 2
A fetchCSS() 0 14 3
A fetchJS() 0 14 3
A addCSS() 0 8 2
A addJS() 0 8 2
A render404() 0 7 1
1
<?php
2
namespace Zewa;
3
use Zewa\Interfaces\ContainerInterface;
4
5
/**
6
 * View management
7
 *
8
 * @author Zechariah Walden<zech @ zewadesign.com>
9
 */
10
class View
11
{
12
    /**
13
     * Active layout for view
14
     *
15
     * @var string|bool
16
     */
17
    protected $layout;
18
19
    /**
20
     * Active module for view
21
     *
22
     * @var string|bool
23
     */
24
    protected $module = false;
25
26
    /**
27
     * Rendered view content
28
     *
29
     * @var string
30
     */
31
    protected $view = false;
32
33
    /**
34
     * Data object for view
35
     *
36
     * @var object
37
     */
38
    protected $properties;
39
40
    /**
41
     * \Zewa\Config reference
42
     *
43
     * @var Config
44
     */
45
    protected $configuration;
46
47
    /**
48
     * \Zewa\Router reference
49
     *
50
     * @var Router
51
     */
52
    protected $router;
53
54
    /**
55
     * \Zewa\Router reference
56
     *
57
     * @var Router
58
     */
59
    protected $request;
60
61
    /**
62
     * @var array
63
     */
64
    private $queuedJS = [];
65
66
    /**
67
     * @var array
68
     */
69
    private $queuedCSS = [];
70
71
    /**
72
     * Load up some basic configuration settings.
73
     */
74
    public function __construct(Config $config, Router $router, Request $request)
75
    {
76
        $this->configuration = $config;
77
        $this->router = $router;
78
        $this->request = $request;
0 ignored issues
show
Documentation Bug introduced by
It seems like $request of type object<Zewa\Request> is incompatible with the declared type object<Zewa\Router> of property $request.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
79
    }
80
81
    /**
82
     * Returns base URL for app
83
     * @return string
84
     */
85
    private function baseURL($path = '')
86
    {
87
        return $this->router->baseURL($path);
88
    }
89
90
    /**
91
     * Returns the current request URL
92
     * @return string
93
     */
94
    private function currentURL($params = false)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
95
    {
96
        return $this->router->currentURL($params);
97
    }
98
99
    /**
100
     * Returns uri string
101
     * @return string
102
     */
103
    private function currentURI()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
104
    {
105
        return $this->router->uri;
106
    }
107
108
    /*
109
     * @todo create method for returning
110
     * a valid json string with header..
111
     * view shouldn't set header logic,
112
     * and the framework doesn't care what returns the string
113
     * ..but view should handle the json_encode...
114
     * seems overkill to call header() with returning a $view->json;
115
     * thoughts?*/
116
117
    /**
118
     * Loads a view
119
     *
120
     * @access public
121
     * @param string|bool $view view to load
122
     * @param string|bool $layout
123
     * @return string
124
     */
125
    public function render($view = false, $layout = false)
126
    {
127
        if ($layout !== false) {
128
            $this->setLayout($layout);
129
        }
130
131
        if ($view !== false) {
132
133
            $view = $this->prepareView($view);
134
135
            $this->view = $return = $this->process($view);
136
137
            if(! is_null($this->layout) ) {
138
                $return = $this->process($this->layout);
139
            }
140
141
            return $return;
142
        } else {
143
            if ($this->view !== false) {
144
                $this->view = $this->process($this->view);
145
            }
146
147
            if (! is_null($this->layout)) {
148
                return $this->process($this->layout);
149
            } else {
150
                return $this->view;
151
            }
152
        }
153
    }
154
155
    /**
156
     * formats and prepares view for inclusion
157
     * @param $viewName
158
     * @return string
159
     * @throws Exception\LookupException
160
     */
161
    private function prepareView($viewName)
162
    {
163
        if ($this->module === false) {
164
            $this->setModule();
165
        }
166
167
        $view = APP_PATH
168
            . DIRECTORY_SEPARATOR
169
            . 'Modules'
170
            . DIRECTORY_SEPARATOR
171
            . $this->module
172
            . DIRECTORY_SEPARATOR
173
            . 'Views'
174
            . DIRECTORY_SEPARATOR
175
            . strtolower($viewName)
176
            . '.php';
177
178
        if (!file_exists($view)) {
179
            throw new Exception\LookupException('View: "' . $view . '" could not be found.');
180
        }
181
182
        return $view;
183
    }
184
185
    public function setView($viewName, $layout = false)
186
    {
187
        if ($layout !== false) {
188
            $this->setLayout($layout);
189
        }
190
        $this->view = $this->prepareView($viewName);
191
    }
192
193
    public function setProperty($property, $value = false)
194
    {
195
        if ($value !== false) {
196
            $this->properties[$property] = $value;
197
        } elseif (!empty($property)) {
198
            $this->properties = $property;
199
        }
200
        return false;
201
    }
202
203
    public function setLayout($layout)
204
    {
205
        if ($layout === false) {
206
            $this->layout = null;
207
        } else {
208
            $layout = APP_PATH . DIRECTORY_SEPARATOR . 'Layouts' . DIRECTORY_SEPARATOR . strtolower($layout) . '.php';
209
210
            if (!file_exists($layout)) {
211
                throw new Exception\LookupException('Layout: "' . $layout . '" could not be found.');
212
            }
213
214
            $this->layout = $layout;
215
216
            return true;
217
        }
218
    }
219
220
    /**
221
     * Set the module for view look
222
     *
223
     * @access public
224
     * @param string|bool $module module to override
225
     */
226
    public function setModule($module = false)
227
    {
228
        if ($module === false) {
229
            $routerConfig = $this->configuration->get('Routing');
230
            $this->module = $routerConfig->module;
231
        } else {
232
            $this->module = ucfirst($module);
233
        }
234
    }
235
236
    /**
237
     * Processes view/layouts and exposes variables to the view/layout
238
     *
239
     * @access private
240
     * @param string $file file being rendered
241
     * @return string processed content
242
     */
243
    //@TODO: come back and clean up this and the way the view receives stuff
244
    private function process($file)
245
    {
246
        ob_start();
247
248
        if (is_array($this->properties)) {
249
            extract($this->properties); // yuck. could produce undeclared errors. hmm..
250
        }
251
        //should i set $this->data in abstract controller, and provide all access vars ? seems bad practice..
252
253
        include $file;
254
255
        $return = ob_get_contents();
256
257
        ob_end_clean();
258
259
        return $return;
260
    }
261
262
    /**
263
     * Helper method for grabbing aggregated css files
264
     *
265
     * @access protected
266
     * @return string css includes
267
     */
268
    protected function fetchCSS()
269
    {
270
        $string = "";
271
272
        if (empty($this->queuedCSS)) {
273
            return $string;
274
        }
275
276
        foreach ($this->queuedCSS as $sheet) {
277
            $string .= '<link rel="stylesheet" href="' . $sheet .'">' . "\r\n";
278
        }
279
280
        return $string;
281
    }
282
283
    /**
284
     * Helper method for grabbing aggregated JS files
285
     *
286
     * @access protected
287
     * @return string JS includes
288
     */
289
    protected function fetchJS()
290
    {
291
        $string = "<script>baseURL = '" . $this->baseURL() . "/'</script>\r\n";
292
293
        if (empty($this->queuedJS)) {
294
            return $string;
295
        }
296
297
        foreach ($this->queuedJS as $script) {
298
            $string .= '<script src="' . $script . '"></script>' . "\r\n";
299
        }
300
301
        return $string;
302
    }
303
304
    /**
305
     * Helper method for adding css files for aggregation/render
306
     *
307
     * @access public
308
     * @param $files array
309
     * @param $place string
310
     * @return string css includes
311
     * @throws Exception\LookupException
312
     */
313
    public function addCSS($files = [], $place = 'append')
314
    {
315
        if ($place === 'append') {
316
            $this->queuedCSS = array_merge($files, $this->queuedCSS);
317
        } else {
318
            $this->queuedCSS = array_merge($this->queuedCSS, $files);
319
        }
320
    }
321
322
    public function addJS($files = [], $place = 'append')
323
    {
324
        if ($place === 'append') {
325
            $this->queuedJS = array_merge($files, $this->queuedJS);
326
        } else {
327
            $this->queuedJS = array_merge($this->queuedJS, $files);
328
        }
329
    }
330
331
    /**
332
     * Set 404 header, and return 404 view contents
333
     *
334
     * @access public
335
     * @param  $data array
336
     * @return string
337
     */
338
    public function render404($data = [])
339
    {
340
        header('HTTP/1.1 404 Not Found');
341
        $this->setProperty($data);
342
        $this->setLayout('404');
343
        return $this->render();
344
    }
345
}
346