Passed
Push — enums ( 8bfe56...7bf697 )
by Fabio
06:38 queued 01:28
created

TTemplateManager::getTemplateByFileName()   C

Complexity

Conditions 12
Paths 34

Size

Total Lines 42
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 31
nc 34
nop 3
dl 0
loc 42
rs 6.9666
c 1
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * TTemplateManager and TTemplate class file
4
 *
5
 * @author Qiang Xue <[email protected]>
6
 * @link https://github.com/pradosoft/prado
7
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
8
 */
9
10
namespace Prado\Web\UI;
11
12
use Prado\Prado;
13
use Prado\TApplicationMode;
14
use Prado\TPropertyValue;
15
16
/**
17
 * TTemplateManager class
18
 *
19
 * TTemplateManager manages the loading and parsing of control templates.
20
 *
21
 * There are two ways of loading a template, either by the associated template
22
 * control class name, or the template file name.
23
 * The former is via calling {@link getTemplateByClassName}, which tries to
24
 * locate the corresponding template file under the directory containing
25
 * the class file. The name of the template file is the class name with
26
 * the extension '.tpl'. To load a template from a template file path,
27
 * call {@link getTemplateByFileName}.
28
 *
29
 * By default, TTemplateManager is registered with {@link TPageService} as the
30
 * template manager module that can be accessed via {@link TPageService::getTemplateManager()}.
31
 *
32
 * @author Qiang Xue <[email protected]>
33
 * @since 3.0
34
 * @method \Prado\Web\Services\TPageService getService()
35
 */
36
class TTemplateManager extends \Prado\TModule
37
{
38
	/**
39
	 * Template file extension
40
	 */
41
	public const TEMPLATE_FILE_EXT = '.tpl';
42
	/**
43
	 * Prefix of the cache variable name for storing parsed templates
44
	 */
45
	public const TEMPLATE_CACHE_PREFIX = 'prado:template:';
46
	/**
47
	 * @var string Default template class, default '\Prado\Web\UI\TTemplate'
48
	 */
49
	private string $_defaultTemplateClass = TTemplate::class;
50
51
	/**
52
	 * Initializes the module.
53
	 * This method is required by IModule and is invoked by application.
54
	 * It starts output buffer if it is enabled.
55
	 * @param \Prado\Xml\TXmlElement $config module configuration
56
	 */
57
	public function init($config)
58
	{
59
		Prado::getApplication()->setTemplateManager($this);
60
		parent::init($config);
61
	}
62
63
	/**
64
	 * Loads the template corresponding to the specified class name.
65
	 * @param mixed $className
66
	 * @return \Prado\Web\UI\TTemplate template for the class name, null if template doesn't exist.
67
	 */
68
	public function getTemplateByClassName($className)
69
	{
70
		$class = new \ReflectionClass($className);
71
		$tplFile = dirname($class->getFileName()) . DIRECTORY_SEPARATOR . $class->getShortName() . self::TEMPLATE_FILE_EXT;
72
		return $this->getTemplateByFileName($tplFile);
73
	}
74
75
	/**
76
	 * Loads the template from the specified file.
77
	 * @param string $fileName The file path and name of the template.
78
	 * @param string $tplClass, default null for the Default Template Class
79
	 * @param string $culture culture string, null to use current application culture
80
	 * @return \Prado\Web\UI\TTemplate or subclass template parsed from the specified file, null if the file doesn't exist.
81
	 */
82
	public function getTemplateByFileName($fileName, $tplClass = null, $culture = null)
83
	{
84
		if ($tplClass === null) {
85
			$tplClass = $this->_defaultTemplateClass;
86
		}
87
		if (!is_subclass_of($tplClass, ITemplate::class)) {
88
			return null;
89
		}
90
		if (($fileName = $this->getLocalizedTemplate($fileName, $culture)) !== null) {
91
			Prado::trace("Loading template $fileName", TTemplateManager::class);
92
			if (($cache = $this->getApplication()->getCache()) === null) {
93
				return new $tplClass(file_get_contents($fileName), dirname($fileName), $fileName);
94
			} else {
95
				$array = $cache->get(self::TEMPLATE_CACHE_PREFIX . $fileName . ':' . $tplClass);
96
				if (is_array($array)) {
97
					[$template, $timestamps] = $array;
98
					if ($this->getApplication()->getMode() === TApplicationMode::Performance) {
99
						return $template;
100
					}
101
					$cacheValid = true;
102
					foreach ($timestamps as $tplFile => $timestamp) {
103
						if (!is_file($tplFile) || filemtime($tplFile) > $timestamp) {
104
							$cacheValid = false;
105
							break;
106
						}
107
					}
108
					if ($cacheValid) {
109
						return $template;
110
					}
111
				}
112
				$template = new $tplClass(file_get_contents($fileName), dirname($fileName), $fileName);
113
				$includedFiles = $template->getIncludedFiles();
114
				$timestamps = [];
115
				$timestamps[$fileName] = filemtime($fileName);
116
				foreach ($includedFiles as $includedFile) {
117
					$timestamps[$includedFile] = filemtime($includedFile);
118
				}
119
				$cache->set(self::TEMPLATE_CACHE_PREFIX . $fileName . ':' . $tplClass, [$template, $timestamps]);
120
				return $template;
121
			}
122
		} else {
123
			return null;
124
		}
125
	}
126
127
	/**
128
	 * Finds a localized template file.
129
	 * @param string $filename template file.
130
	 * @param string $culture culture string, null to use current culture
131
	 * @return null|string a localized template file if found, null otherwise.
132
	 */
133
	protected function getLocalizedTemplate($filename, $culture = null)
134
	{
135
		if (($app = $this->getApplication()->getGlobalization(false)) === null) {
136
			return is_file($filename) ? $filename : null;
137
		}
138
		foreach ($app->getLocalizedResource($filename, $culture) as $file) {
139
			if (($file = realpath($file)) !== false && is_file($file)) {
140
				return $file;
141
			}
142
		}
143
		return null;
144
	}
145
146
	/**
147
	 * @return string the default template class.
148
	 */
149
	public function getDefaultTemplateClass(): string
150
	{
151
		return $this->_defaultTemplateClass;
152
	}
153
154
	/**
155
	 * @param string $tplClass the default template class.
156
	 */
157
	public function setDefaultTemplateClass($tplClass)
158
	{
159
		$this->_defaultTemplateClass = TPropertyValue::ensureString($tplClass);
160
	}
161
}
162