Completed
Pull Request — master (#81)
by
unknown
03:04
created

View::addJS()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 0
cts 6
cp 0
rs 9.4285
cc 2
eloc 5
nc 2
nop 2
crap 6
1
<?php
2
namespace Zewa;
3
4
/**
5
 * View management
6
 *
7
 * @author Zechariah Walden<zech @ zewadesign.com>
8
 */
9
class View
10
{
11
    /**
12
     * Active layout for view
13
     *
14
     * @var string|bool
15
     */
16
    protected $layout;
17
18
    /**
19
     * Active module for view
20
     *
21
     * @var string|bool
22
     */
23
    protected $module = false;
24
25
    /**
26
     * Rendered view content
27
     *
28
     * @var string
29
     */
30
    protected $view = false;
31
32
    /**
33
     * Data object for view
34
     *
35
     * @var object
36
     */
37
    protected $properties;
38
39
    /**
40
     * \Zewa\Config reference
41
     *
42
     * @var Config
43
     */
44
    protected $configuration;
45
46
    /**
47
     * \Zewa\Router reference
48
     *
49
     * @var Router
50
     */
51
    protected $router;
52
53
    /**
54
     * \Zewa\Router reference
55
     *
56
     * @var Router
57
     */
58
    protected $request;
59
60
    /**
61
     * @var array
62
     */
63
    private $queuedJS = [];
64
65
    /**
66
     * @var array
67
     */
68
    private $queuedCSS = [];
69
70
    /**
71
     * Load up some basic configuration settings.
72
     */
73
    public function __construct(Config $config, Router $router, Request $request)
74
    {
75
        $this->configuration = $config;
76
        $this->router = $router;
77
        $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...
78
    }
79
80
    /**
81
     * Returns base URL for app
82
     * @return string
83
     */
84
    private function baseURL($path = '')
85
    {
86
        return $this->router->baseURL($path);
87
    }
88
89
    /**
90
     * Returns the current request URL
91
     * @return string
92
     */
93
    private function currentURL($params = false)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
94
    {
95
        return $this->router->currentURL($params);
96
    }
97
98
    /**
99
     * Returns uri string
100
     * @return string
101
     */
102
    private function currentURI()
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
103
    {
104
        return $this->router->uri;
105
    }
106
107
    /*
108
     * @todo create method for returning
109
     * a valid json string with header..
110
     * view shouldn't set header logic,
111
     * and the framework doesn't care what returns the string
112
     * ..but view should handle the json_encode...
113
     * seems overkill to call header() with returning a $view->json;
114
     * thoughts?*/
115
116
    /**
117
     * Loads a view
118
     *
119
     * @access public
120
     * @param string|bool $view view to load
121
     * @param string|bool $layout
122
     * @return string
123
     */
124
    public function render($view = false, $layout = false)
125
    {
126
        if ($layout !== false) {
127
            $this->setLayout($layout);
128
        }
129
130
        if ($view !== false) {
131
            $view = $this->prepareView($view);
132
133
            $this->view = $return = $this->process($view);
134
135
            if (! is_null($this->layout)) {
136
                $return = $this->process($this->layout);
137
            }
138
139
            return $return;
140
        } else {
141
            if ($this->view !== false) {
142
                $this->view = $this->process($this->view);
143
            }
144
145
            if (! is_null($this->layout)) {
146
                return $this->process($this->layout);
147
            } else {
148
                return $this->view;
149
            }
150
        }
151
    }
152
153
    /**
154
     * formats and prepares view for inclusion
155
     * @param $viewName
156
     * @return string
157
     * @throws Exception\LookupException
158
     */
159
    private function prepareView($viewName)
160
    {
161
        if ($this->module === false) {
162
            $this->setModule();
163
        }
164
165
        $view = APP_PATH
166
            . DIRECTORY_SEPARATOR
167
            . 'Modules'
168
            . DIRECTORY_SEPARATOR
169
            . $this->module
170
            . DIRECTORY_SEPARATOR
171
            . 'Views'
172
            . DIRECTORY_SEPARATOR
173
            . strtolower($viewName)
174
            . '.php';
175
176
        if (!file_exists($view)) {
177
            throw new Exception\LookupException('View: "' . $view . '" could not be found.');
178
        }
179
180
        return $view;
181
    }
182
183
    public function setView($viewName, $layout = false)
184
    {
185
        if ($layout !== false) {
186
            $this->setLayout($layout);
187
        }
188
        $this->view = $this->prepareView($viewName);
189
    }
190
191
    public function setProperty($property, $value = false)
192
    {
193
        if ($value !== false) {
194
            $this->properties[$property] = $value;
195
        } elseif (!empty($property)) {
196
            $this->properties = $property;
197
        }
198
        return false;
199
    }
200
201
    public function setLayout($layout)
202
    {
203
        if ($layout === false) {
204
            $this->layout = null;
205
        } else {
206
            $layout = APP_PATH . DIRECTORY_SEPARATOR . 'Layouts' . DIRECTORY_SEPARATOR . strtolower($layout) . '.php';
207
208
            if (!file_exists($layout)) {
209
                throw new Exception\LookupException('Layout: "' . $layout . '" could not be found.');
210
            }
211
212
            $this->layout = $layout;
213
214
            return true;
215
        }
216
    }
217
218
    /**
219
     * Set the module for view look
220
     *
221
     * @access public
222
     * @param string|bool $module module to override
223
     */
224
    public function setModule($module = false)
225
    {
226
        if ($module === false) {
227
            $routerConfig = $this->router->getConfig()->get('Routing');
228
            $this->module = $routerConfig->module;
229
        } else {
230
            $this->module = ucfirst($module);
231
        }
232
    }
233
234
    /**
235
     * Processes view/layouts and exposes variables to the view/layout
236
     *
237
     * @access private
238
     * @param string $file file being rendered
239
     * @return string processed content
240
     */
241
    //@TODO: come back and clean up this and the way the view receives stuff
242
    private function process($file)
243
    {
244
        ob_start();
245
246
        if (is_array($this->properties)) {
247
            extract($this->properties); // yuck. could produce undeclared errors. hmm..
248
        }
249
        //should i set $this->data in abstract controller, and provide all access vars ? seems bad practice..
250
251
        include $file;
252
253
        $return = ob_get_contents();
254
255
        ob_end_clean();
256
257
        return $return;
258
    }
259
260
    /**
261
     * Helper method for grabbing aggregated css files
262
     *
263
     * @access protected
264
     * @return string css includes
265
     */
266
    protected function fetchCSS()
267
    {
268
        $string = "";
269
270
        if (empty($this->queuedCSS)) {
271
            return $string;
272
        }
273
274
        foreach ($this->queuedCSS as $sheet) {
275
            $string .= '<link rel="stylesheet" href="' . $sheet .'">' . "\r\n";
276
        }
277
278
        return $string;
279
    }
280
281
    /**
282
     * Helper method for grabbing aggregated JS files
283
     *
284
     * @access protected
285
     * @return string JS includes
286
     */
287
    protected function fetchJS()
288
    {
289
        $string = "<script>baseURL = '" . $this->baseURL() . "/'</script>\r\n";
290
291
        if (empty($this->queuedJS)) {
292
            return $string;
293
        }
294
295
        foreach ($this->queuedJS as $script) {
296
            $string .= '<script src="' . $script . '"></script>' . "\r\n";
297
        }
298
299
        return $string;
300
    }
301
302
    /**
303
     * Helper method for adding css files for aggregation/render
304
     *
305
     * @access public
306
     * @param $files array
307
     * @param $place string
308
     * @return string css includes
309
     * @throws Exception\LookupException
310
     */
311
    public function addCSS($files = [], $place = 'append')
312
    {
313
        if ($place === 'append') {
314
            $this->queuedCSS = array_merge($files, $this->queuedCSS);
315
        } else {
316
            $this->queuedCSS = array_merge($this->queuedCSS, $files);
317
        }
318
    }
319
320
    public function addJS($files = [], $place = 'append')
321
    {
322
        if ($place === 'append') {
323
            $this->queuedJS = array_merge($files, $this->queuedJS);
324
        } else {
325
            $this->queuedJS = array_merge($this->queuedJS, $files);
326
        }
327
    }
328
329
    /**
330
     * Set 404 header, and return 404 view contents
331
     *
332
     * @access public
333
     * @param  $data array
334
     * @return string
335
     */
336
    public function render404($data = [])
337
    {
338
        header('HTTP/1.1 404 Not Found');
339
        $this->setProperty($data);
340
        $this->setLayout('404');
341
        return $this->render();
342
    }
343
}
344