Driver_HTML::clear()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Provides view functionality for html output
5
 *
6
 * PHP Version 5
7
 *
8
 * @category  Core
9
 * @package   View
10
 * @author    Hans-Joachim Piepereit <[email protected]>
11
 * @copyright 2013 cSphere Team
12
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
13
 * @link      http://www.csphere.eu
14
 **/
15
16
namespace csphere\core\view;
17
18
/**
19
 * Provides view functionality for html output
20
 *
21
 * @category  Core
22
 * @package   View
23
 * @author    Hans-Joachim Piepereit <[email protected]>
24
 * @copyright 2013 cSphere Team
25
 * @license   http://opensource.org/licenses/bsd-license Simplified BSD License
26
 * @link      http://www.csphere.eu
27
 **/
28
29
class Driver_HTML extends Base
30
{
31
    /**
32
     * Content type header
33
     **/
34
    protected $type = 'text/html; charset=UTF-8';
35
36
    /**
37
     * Boxes with key and a value containing their data
38
     **/
39
    private $_boxes = [];
40
41
    /**
42
     * List of template files with their cache key attached
43
     **/
44
    private $_files = [];
45
46
    /**
47
     * Theme name
48
     **/
49
    private $_theme = '';
50
51
    /**
52
     * Hold cache object for checks
53
     **/
54
    private $_cache = null;
55
56
    /**
57
     * Language shorthandle for translation
58
     **/
59
    private $_language = '';
60
61
    /**
62
     * Creates the view handler object
63
     *
64
     * @param array $config Configuration details as an array
65
     *
66
     * @return \csphere\core\view\Driver_HTML
67
     **/
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
68
69
    public function __construct(array $config)
70
    {
71
        parent::__construct($config);
72
73
        // @TODO: Theme should be configurable
74
        if (empty($this->config['theme'])) {
75
76
            $this->config['theme'] = 'default';
77
        }
78
79
        $request=\csphere\core\router\Controller::parseRequestAction();
80
81
        $pluginMetadata=new \csphere\core\plugins\metadata();
82
        $result=$pluginMetadata->templateType(
83
            $request['plugin'], $request['action']
84
        );
85
86
        if ($result=="backend") {
87
88
            $this->config['theme'] = 'admin';
89
        }
90
91
        $this->_theme = $this->config['theme'];
92
93
        // Set cache object
94
        $this->_cache = $this->loader->load('cache');
95
96
        // Get language
97
        $this->_language = \csphere\core\translation\Fetch::lang();
98
    }
99
100
    /**
101
     * Get theme details from cache or file
102
     *
103
     * @param boolean $boxes Get only boxes of theme
104
     *
105
     * @return array
106
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
107
108
    private function _theme($boxes = false)
109
    {
110
        // Try to load theme details from cache
111
        $key_boxes = 'theme_boxes_' . $this->_theme . '_' . $this->_language;
112
        $key_parts = 'theme_parts_' . $this->_theme . '_' . $this->_language;
113
114
        if ($boxes == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
115
116
            $result = $this->_cache->load($key_boxes);
117
118
        } else {
119
120
            $result = $this->_cache->load($key_parts);
121
        }
122
123
        // If cache loading fails prepare theme file
124
        if ($result == false) {
125
126
            // Load theme file name and fetch file content
127
            $target = new \csphere\core\themes\Checks($this->_theme);
128
            $dir  = $target->dirname();
129
            $file = $target->result();
130
            $file = file_get_contents($file);
131
132
            // Split theme file and get boxes
133
            $parts = \csphere\core\template\Theme::prepare($file, $dir);
134
            $boxed = \csphere\core\template\Theme::boxes($parts);
135
136
            // Save result for later requests
137
            $this->_cache->save($key_boxes, $boxed);
138
            $this->_cache->save($key_parts, $parts);
139
140
            if ($boxes == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
141
142
                $result = $boxed;
143
144
            } else {
145
146
                $result = $parts;
147
            }
148
        }
149
150
        return $result;
151
    }
152
153
    /**
154
     * Prepare template files
155
     *
156
     * @param string $plugin   Name of the plugin
157
     * @param string $template Template file name without file ending
158
     *
159
     * @return string
160
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
161
162
    private function _load($plugin, $template)
163
    {
164
        // Try to load template details from cache
165
        $key = 'tpl_' . $plugin . '_' . $template . '_' . $this->_language;
166
167
        // Check if key is already loaded
168
        if (!isset($this->_files[$key])) {
169
170
            $tpl = $this->_cache->load($key);
171
172
            // If cache loading fails prepare template file
173
            if ($tpl == false) {
174
175
                $tpl = \csphere\core\template\Engine::source($plugin, $template);
176
177
                // Save result for later requests
178
                $this->_cache->save($key, $tpl);
179
            }
180
181
            $this->_files[$key] = $tpl;
182
        }
183
184
        return $key;
185
    }
186
187
    /**
188
     * Parses the template parts
189
     *
190
     * @param array $parts Array of data per template
191
     *
192
     * @return string
193
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
194
195
    private function _parse($parts)
196
    {
197
        // Get and parse parts
198
        $result = '';
199
200
        foreach ($parts AS $part) {
201
202
            if (isset($part['key'])) {
203
204
                $tpl = $this->_files[$part['key']];
205
206
                $add = \csphere\core\template\Engine::parse($tpl, $part['data']);
207
208
            } else {
209
210
                $add = (string)$part;
211
            }
212
213
            $result .= $add . "\n";
214
        }
215
216
        return $result;
217
    }
218
219
    /**
220
     * Format content parts on json requests
221
     *
222
     * @param boolean $box Special case for box mode
223
     *
224
     * @return array
225
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
226
227
    protected function format($box)
228
    {
229
        if ($box == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
230
231
            $response = $this->_parse($this->_boxes);
232
233
            $this->_boxes = [];
234
235
            $response = ['box' => $response];
236
237
            // Load debug toolbar only if debug option is true
238
            if ($this->config['debug'] == true) {
239
240
                $response['debug'] = \csphere\core\template\Hooks::debug();
241
            }
242
243
        } else {
244
245
            $result = $this->_parse($this->content);
246
247
            // Only use boxes from theme
248
            $boxes = $this->_theme(true);
249
250
            $response = \csphere\core\template\Engine::boxes($boxes, $result);
251
        }
252
253
        return $response;
0 ignored issues
show
Best Practice introduced by
The expression return $response; seems to be an array, but some of its elements' types (array) are incompatible with the return type of the parent method csphere\core\view\Base::format of type array<string,string>.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
254
    }
255
256
    /**
257
     * Combine content parts on usual requests
258
     *
259
     * @param boolean $box Special case for box mode
260
     *
261
     * @return string
262
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
263
264
    protected function combine($box)
265
    {
266
        if ($box == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
267
268
            $response = $this->_parse($this->_boxes);
269
270
            $this->_boxes = [];
271
272
        } else {
273
274
            $result = $this->_parse($this->content);
275
276
            // Use full theme file
277
            $theme = $this->_theme();
278
279
            $response = \csphere\core\template\Theme::parse($theme, $result);
280
        }
281
282
        return $response;
283
    }
284
285
    /**
286
     * Parse content of active box
287
     *
288
     * @return string
289
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
290
291
    public function box()
292
    {
293
        $result = $this->_parse($this->_boxes);
294
295
        $this->_boxes = [];
296
297
        return $result;
298
    }
299
300
    /**
301
     * Clear boxes for template box parser
302
     *
303
     * @return boolean
304
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
305
306
    public function clear()
307
    {
308
        $this->_boxes = [];
309
310
        return true;
311
    }
312
313
    /**
314
     * Adds a template file with data to output
315
     *
316
     * @param string  $plugin   Name of the plugin
317
     * @param string  $template Template file name without file ending
318
     * @param array   $data     Array with content to use in the template
319
     * @param boolean $box      Defaults to false which turns box mode off
320
     *
321
     * @return boolean
322
     **/
0 ignored issues
show
Coding Style introduced by
There must be no blank lines after the function comment
Loading history...
323
324
    public function template(
325
        $plugin, $template, array $data = [], $box = false
326
    ) {
327
        // Get template key and file content
328
        $key = $this->_load($plugin, $template);
329
330
        // Add key with data to content or boxes
331
        if ($box == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
332
333
            $this->_boxes[] = ['key' => $key, 'data' => $data];
334
335
        } else {
336
337
            $this->content[] = ['key' => $key, 'data' => $data];
338
        }
339
340
        return true;
341
    }
342
}
343