1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This software package is licensed under `AGPL, Commercial` license[s]. |
5
|
|
|
* |
6
|
|
|
* @package maslosoft/miniview |
7
|
|
|
* @license AGPL, Commercial |
8
|
|
|
* |
9
|
|
|
* @copyright Copyright (c) Peter Maselkowski <[email protected]> |
10
|
|
|
* |
11
|
|
|
* @link http://maslosoft.com/miniview/ |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace Maslosoft\MiniView; |
15
|
|
|
|
16
|
|
|
use Maslosoft\MiniView\Interfaces\OwnerAwareInterface; |
17
|
|
|
use Maslosoft\MiniView\Interfaces\RendererAwareInterface; |
18
|
|
|
use Maslosoft\MiniView\Interfaces\ViewRendererInterface; |
19
|
|
|
use Maslosoft\MiniView\Renderers\LatteRenderer; |
20
|
|
|
use Maslosoft\MiniView\Renderers\PhpRenderer; |
21
|
|
|
use Maslosoft\MiniView\Renderers\TwigRenderer; |
22
|
|
|
use ReflectionObject; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* MiniRender |
26
|
|
|
* Based on Yii CWidget |
27
|
|
|
* @author Piotr Maselkowski <pmaselkowski at gmail.com> |
28
|
|
|
* @author Qiang Xue <[email protected]> |
29
|
|
|
* @property string @version Current MiniView version |
30
|
|
|
*/ |
31
|
|
|
class MiniView implements ViewRendererInterface, OwnerAwareInterface, RendererAwareInterface |
32
|
|
|
{ |
33
|
|
|
|
34
|
|
|
use Traits\OwnerAwareTrait, |
35
|
|
|
Traits\RendererAwareTrait; |
36
|
|
|
|
37
|
|
|
public $renderers = [ |
38
|
|
|
'latte' => LatteRenderer::class, |
39
|
|
|
'php' => PhpRenderer::class, |
40
|
|
|
'twig' => TwigRenderer::class |
41
|
|
|
]; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Current version |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
private static $version = null; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* View path |
51
|
|
|
* @var string |
52
|
|
|
*/ |
53
|
|
|
private $path = ''; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* View path. This is relative to base path. |
57
|
|
|
* @var string |
58
|
|
|
*/ |
59
|
|
|
private $viewsPath = 'views'; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Create MiniView instance. If path is not set, it will be based on location of owner class. |
63
|
|
|
* @param object $owner |
64
|
|
|
* @param string $path |
65
|
|
|
*/ |
66
|
|
|
public function __construct($owner, $path = null) |
67
|
|
|
{ |
68
|
|
|
$this->path = $path; |
69
|
|
|
$this->setOwner($owner); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Get current MiniView version |
74
|
|
|
* @return string Version string |
75
|
|
|
*/ |
76
|
|
|
public function getVersion() |
77
|
|
|
{ |
78
|
|
|
if (null === self::$version) |
79
|
|
|
{ |
80
|
|
|
self::$version = require __DIR__ . '/version.php'; |
81
|
|
|
} |
82
|
|
|
return self::$version; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Set views path. This is relative path for view resolving. |
87
|
|
|
* By default it's `views` folder. |
88
|
|
|
* @param string $path |
89
|
|
|
* @return static |
90
|
|
|
*/ |
91
|
|
|
public function setViewsPath($path) |
92
|
|
|
{ |
93
|
|
|
$this->viewsPath = $path; |
94
|
|
|
return $this; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Render view with data provided. |
99
|
|
|
* View name may contain `php` extension. If no extension is passed or |
100
|
|
|
* it not match extensions from renderer configuration, |
101
|
|
|
* it will append extension based on current renderer. |
102
|
|
|
* |
103
|
|
|
* Example with default or previously set renderer: |
104
|
|
|
* |
105
|
|
|
* ```php |
106
|
|
|
* $view->render('myView'); |
107
|
|
|
* ``` |
108
|
|
|
* |
109
|
|
|
* Example with enforced php renderer: |
110
|
|
|
* |
111
|
|
|
* ```php |
112
|
|
|
* $view->render('myView.php'); |
113
|
|
|
* ``` |
114
|
|
|
* |
115
|
|
|
* Example with enforced latte renderer: |
116
|
|
|
* |
117
|
|
|
* ```php |
118
|
|
|
* $view->render('myView.latte'); |
119
|
|
|
* ``` |
120
|
|
|
* |
121
|
|
|
* @param string $view |
122
|
|
|
* @param mixed[] $data |
123
|
|
|
* @param bool $return |
124
|
|
|
* @return string |
125
|
|
|
*/ |
126
|
|
|
public function render($view, $data = null, $return = false) |
127
|
|
|
{ |
128
|
|
|
$viewFile = sprintf('%s/%s/%s', $this->getPath(), $this->viewsPath, $view); |
129
|
|
|
$extensions = array_keys($this->renderers); |
130
|
|
|
$pattern = sprintf('~\.(%s)$~', implode('|', $extensions)); |
131
|
|
|
$currentRenderer = $this->getRenderer(); |
132
|
|
|
|
133
|
|
|
// Append extension if not set |
134
|
|
|
if (!preg_match($pattern, $view, $matches)) |
135
|
|
|
{ |
136
|
|
|
// Get extension from current renderer |
137
|
|
|
$extension = 'php'; |
138
|
|
|
foreach ($this->renderers as $extension => $rendererMatch) |
139
|
|
|
{ |
140
|
|
|
if ($currentRenderer instanceof $rendererMatch) |
141
|
|
|
{ |
142
|
|
|
break; |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
// Set proper extension |
147
|
|
|
$viewFile = sprintf('%s.%s', $viewFile, $extension); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
// Matched extension, detect renderer |
151
|
|
|
if (!empty($matches) && !empty($matches[1])) |
152
|
|
|
{ |
153
|
|
|
$key = $matches[1]; |
154
|
|
|
$rendererClass = $this->renderers[$key]; |
155
|
|
|
// Set proper renderer |
156
|
|
|
if (!$currentRenderer instanceof $rendererClass) |
157
|
|
|
{ |
158
|
|
|
// Use setRenderer as it contains additional logic |
159
|
|
|
$this->setRenderer(new $rendererClass); |
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
$result = $this->getRenderer()->render($viewFile, $data, $return); |
163
|
|
|
$this->setRenderer($currentRenderer); |
164
|
|
|
return $result; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Render file with data provided. |
169
|
|
|
* @param string $file |
170
|
|
|
* @param mixed[] $data |
171
|
|
|
* @param bool $return |
172
|
|
|
* @return string |
173
|
|
|
*/ |
174
|
|
|
public function renderFile($file, $data = null, $return = false) |
175
|
|
|
{ |
176
|
|
|
return $this->getRenderer()->render($file, $data, $return); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
function getPath() |
|
|
|
|
180
|
|
|
{ |
181
|
|
|
if (empty($this->path)) |
182
|
|
|
{ |
183
|
|
|
$class = new ReflectionObject($this->getOwner()); |
184
|
|
|
$this->path = dirname($class->getFileName()); |
185
|
|
|
} |
186
|
|
|
return $this->path; |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
} |
190
|
|
|
|
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.
If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with
private
, and only raise it toprotected
if a sub-class needs to have access, orpublic
if an external class needs access.