Completed
Push — master ( a378d5...7b6893 )
by Flo
28s
created

ViewController::setParentTemplate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * Class ViewController | ViewController.php
4
 *
5
 * @package Faulancer\View
6
 * @author Florian Knapp <[email protected]>
7
 */
8
namespace Faulancer\View;
9
10
use Faulancer\Exception\ClassNotFoundException;
11
use Faulancer\Exception\ConstantMissingException;
12
use Faulancer\Exception\FileNotFoundException;
13
use Faulancer\Exception\ViewHelperIncompatibleException;
14
use Faulancer\Service\Config;
15
use Faulancer\ServiceLocator\ServiceLocator;
16
17
/**
18
 * Class ViewController
19
 */
20
class ViewController
21
{
22
23
    /**
24
     * Holds the view variables
25
     * @var array
26
     */
27
    private $variable = [];
28
29
    /**
30
     * Holds the view template
31
     * @var string
32
     */
33
    private $template = '';
34
35
    /**
36
     * Holds the parent template
37
     * @var ViewController
38
     */
39
    private $parentTemplate = null;
40
41
    /**
42
     * Holds the registered view helper
43
     * @var array
44
     */
45
    public $viewHelper = [];
46
47
    /**
48
     * Set template for this view
49
     * @param string $template
50
     * @return self
51
     * @throws ConstantMissingException
52
     * @throws FileNotFoundException
53
     */
54
    public function setTemplate(string $template = '') :self
55
    {
56
        /** @var Config $config */
57
        $config = ServiceLocator::instance()->get(Config::class);
58
59
        if (strpos($template, $config->get('viewsRoot')) === false) {
60
            $template = $config->get('viewsRoot') . $template;
61
        }
62
63
        if (empty($template) || !file_exists($template) || is_dir($template)) {
64
            throw new FileNotFoundException('Template "' . $template . '" not found');
65
        }
66
67
        $this->template = $template;
68
69
        return $this;
70
    }
71
72
    /**
73
     * Add javascript from outside
74
     * @param string $file
75
     * @return self
76
     */
77
    public function addScript($file) :self
78
    {
79
        $this->variable['assetsJs'][] = $file;
80
        return $this;
81
    }
82
83
    /**
84
     * Add stylesheet from outside
85
     * @param string $file
86
     * @return self
87
     */
88
    public function addStylesheet($file) :self
89
    {
90
        $this->variable['assetsCss'][] = $file;
91
        return $this;
92
    }
93
94
    /**
95
     * Return current template
96
     * @return string
97
     */
98
    public function getTemplate() :string
99
    {
100
        return (string)$this->template;
101
    }
102
103
    /**
104
     * Set a single variable
105
     * @param string $key
106
     * @param string|array $value
107
     */
108
    public function setVariable(string $key = '', $value = '')
109
    {
110
        $this->variable[$key] = $value;
111
    }
112
113
    /**
114
     * Get a single variable
115
     * @param $key
116
     * @return string|array
117
     */
118
    public function getVariable($key)
119
    {
120
        if(isset($this->variable[$key])) {
121
            return $this->variable[$key];
122
        }
123
124
        return '';
125
    }
126
127
    /**
128
     * Check if variable exists
129
     * @param string $key
130
     * @return bool
131
     */
132
    public function hasVariable(string $key) :bool
133
    {
134
        if(isset($this->variable[$key])) {
135
            return true;
136
        }
137
138
        return false;
139
    }
140
141
    /**
142
     * Set many variables at once
143
     * @param array $variables
144
     * @return self
145
     */
146
    public function setVariables(array $variables = []) :self
147
    {
148
        foreach($variables AS $key=>$value) {
149
            $this->setVariable($key, $value);
150
        }
151
152
        return $this;
153
    }
154
155
    /**
156
     * Get all variables
157
     * @return array
158
     */
159
    public function getVariables() :array
160
    {
161
        return $this->variable;
162
    }
163
164
    /**
165
     * Define parent template
166
     * @param ViewController $view
167
     */
168
    public function setParentTemplate(ViewController $view)
169
    {
170
        $this->parentTemplate = $view;
171
    }
172
173
    /**
174
     * Get parent template
175
     * @return ViewController
176
     */
177
    public function getParentTemplate()
178
    {
179
        return $this->parentTemplate;
180
    }
181
182
    /**
183
     * Strip spaces and tabs from output
184
     * @param $output
185
     * @return string
186
     */
187
    private function cleanOutput($output) :string
188
    {
189
        return str_replace(array("\t", "\r", "  "), "", trim($output));
190
    }
191
192
    /**
193
     * Render the current view
194
     * @return string
195
     */
196
    public function render() :string
197
    {
198
        extract($this->variable);
199
200
        ob_start();
201
202
        include $this->getTemplate();
203
204
        $content = ob_get_contents();
205
206
        ob_end_clean();
207
208
        if( $this->getParentTemplate() instanceof ViewController ) {
209
            return $this->cleanOutput($this->getParentTemplate()->setVariables($this->getVariables())->render());
210
        } else {
211
            return $this->cleanOutput($content);
212
        }
213
    }
214
215
    /**
216
     * Magic method for providing a view helper
217
     * @param $name
218
     * @param $arguments
219
     * @return string
220
     * @throws FileNotFoundException
221
     * @throws ViewHelperIncompatibleException
222
     * @throws ClassNotFoundException
223
     */
224
    public function __call($name, $arguments)
225
    {
226
        $coreViewHelper = __NAMESPACE__ . '\Helper\\' . ucfirst($name);
227
228 View Code Duplication
        if (class_exists($coreViewHelper)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
229
            $class = new $coreViewHelper;
230
            array_unshift($arguments, $this);
231
            $this->viewHelper[$coreViewHelper] = call_user_func_array($class, $arguments);
232
            return $this->viewHelper[$coreViewHelper];
233
        }
234
235
        /** @var Config $config */
236
        $config    = ServiceLocator::instance()->get(Config::class);
237
        $namespace = '\\' . $config->get('namespacePrefix');
238
239
        $customViewHelper = $namespace . '\\View\\' . ucfirst($name);
240
241 View Code Duplication
        if (class_exists($customViewHelper)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
            $class = new $customViewHelper;
243
            array_unshift($arguments, $this);
244
            $this->viewHelper[$customViewHelper] = $class($arguments);
245
            return $this->viewHelper[$customViewHelper];
246
        }
247
248
        throw new ClassNotFoundException('No compatible view helper for "' . $name . '" found.');
249
    }
250
251
    /**
252
     * Destructor
253
     */
254
    public function __destruct()
255
    {
256
        unset( $this->variable );
257
        unset( $this->template );
258
    }
259
260
}