Completed
Push — master ( 9a7fc1...319399 )
by Peter
01:58
created

MiniView::render()   C

Complexity

Conditions 7
Paths 12

Size

Total Lines 39
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 39
rs 6.7272
cc 7
eloc 18
nc 12
nop 3
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 ReflectionObject;
22
23
/**
24
 * MiniRender
25
 * Based on Yii CWidget
26
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
27
 * @author Qiang Xue <[email protected]>
28
 * @property string @version Current MiniView version
29
 */
30
class MiniView implements ViewRendererInterface, OwnerAwareInterface, RendererAwareInterface
31
{
32
33
	use Traits\OwnerAwareTrait,
34
	  Traits\RendererAwareTrait;
35
36
	public $renderers = [
37
		'latte' => LatteRenderer::class,
38
		'php' => PhpRenderer::class
39
	];
40
41
	/**
42
	 * Current version
43
	 * @var string
44
	 */
45
	private static $version = null;
46
47
	/**
48
	 * View path
49
	 * @var string
50
	 */
51
	private $path = '';
52
53
	/**
54
	 * View path. This is relative to base path.
55
	 * @var string
56
	 */
57
	private $viewsPath = 'views';
58
59
	/**
60
	 * Create MiniView instance. If path is not set, it will be based on location of owner class.
61
	 * @param object $owner
62
	 * @param string $path
63
	 */
64
	public function __construct($owner, $path = null)
65
	{
66
		$this->path = $path;
67
		$this->setOwner($owner);
68
	}
69
70
	/**
71
	 * Get current MiniView version
72
	 * @return string Version string
73
	 */
74
	public function getVersion()
75
	{
76
		if (null === self::$version)
77
		{
78
			self::$version = require __DIR__ . '/version.php';
79
		}
80
		return self::$version;
81
	}
82
83
	/**
84
	 * Set views path. This is relative path for view resolving.
85
	 * By default it's `views` folder.
86
	 * @param string $path
87
	 */
88
	public function setViewsPath($path)
89
	{
90
		$this->viewsPath = $path;
91
	}
92
93
	/**
94
	 * Render view with data provided.
95
	 * View name may contain `php` extension. If no extension is passed or
96
	 * it not match extensions from renderer configuration,
97
	 * it will append extension based on current renderer.
98
	 *
99
	 * Example with default or previously set renderer:
100
	 *
101
	 * ```php
102
	 * $view->render('myView');
103
	 * ```
104
	 *
105
	 * Example with enforced php renderer:
106
	 *
107
	 * ```php
108
	 * $view->render('myView.php');
109
	 * ```
110
	 *
111
	 * Example with enforced latte renderer:
112
	 * 
113
	 * ```php
114
	 * $view->render('myView.latte');
115
	 * ```
116
	 *
117
	 * @param string $view
118
	 * @param mixed[] $data
119
	 * @param bool $return
120
	 * @return string
121
	 */
122
	public function render($view, $data = null, $return = false)
123
	{
124
		$viewFile = sprintf('%s/%s/%s', $this->getPath(), $this->viewsPath, $view);
125
		$extensions = array_keys($this->renderers);
126
		$pattern = sprintf('~\.(%s)$~', implode('|', $extensions));
127
		$currentRenderer = $this->getRenderer();
128
129
		// Append extension if not set
130
		if (!preg_match($pattern, $view, $matches))
131
		{
132
			// Get extension from current renderer
133
			foreach ($this->renderers as $extension => $rendererMatch)
134
			{
135
				if ($currentRenderer instanceof $rendererMatch)
136
				{
137
					break;
138
				}
139
			}
140
141
			// Set proper extension
142
			$viewFile = sprintf('%s.%s', $viewFile, $extension);
0 ignored issues
show
Bug introduced by
The variable $extension seems to be defined by a foreach iteration on line 133. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
143
		}
144
145
		// Matched extension, detect renderer
146
		if (!empty($matches) && !empty($matches[1]))
147
		{
148
			$key = $matches[1];
149
			$rendererClass = $this->renderers[$key];
150
			// Set proper renderer
151
			if (!$currentRenderer instanceof $rendererClass)
152
			{
153
				// Use setRenderer as it contains additional logic
154
				$this->setRenderer(new $rendererClass);
155
			}
156
		}
157
		$result = $this->getRenderer()->render($viewFile, $data, $return);
158
		$this->setRenderer($currentRenderer);
159
		return $result;
160
	}
161
162
	/**
163
	 * Render file with data provided.
164
	 * @param string $file
165
	 * @param mixed[] $data
166
	 * @param bool $return
167
	 * @return string
168
	 */
169
	public function renderFile($file, $data = null, $return = false)
170
	{
171
		return $this->getRenderer()->render($file, $data, $return);
172
	}
173
174
	function getPath()
175
	{
176
		if (empty($this->path))
177
		{
178
			$class = new ReflectionObject($this->getOwner());
179
			$this->path = dirname($class->getFileName());
180
		}
181
		return $this->path;
182
	}
183
184
}
185