summaryrefslogtreecommitdiff
path: root/framework/Web/UI/TTemplateManager.php
blob: 7dd406c72433c55830add7c2d0c9e990fd525700 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
/**
 * TTemplateManager and TTemplate class file
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.pradosoft.com/
 * @copyright Copyright &copy; 2005-2014 PradoSoft
 * @license http://www.pradosoft.com/license/
 * @package System.Web.UI
 */

/**
 * Includes TOutputCache class file
 */
Prado::using('System.Web.UI.WebControls.TOutputCache');

/**
 * TTemplateManager class
 *
 * TTemplateManager manages the loading and parsing of control templates.
 *
 * There are two ways of loading a template, either by the associated template
 * control class name, or the template file name.
 * The former is via calling {@link getTemplateByClassName}, which tries to
 * locate the corresponding template file under the directory containing
 * the class file. The name of the template file is the class name with
 * the extension '.tpl'. To load a template from a template file path,
 * call {@link getTemplateByFileName}.
 *
 * By default, TTemplateManager is registered with {@link TPageService} as the
 * template manager module that can be accessed via {@link TPageService::getTemplateManager()}.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @package System.Web.UI
 * @since 3.0
 */
class TTemplateManager extends TModule
{
	/**
	 * Template file extension
	 */
	const TEMPLATE_FILE_EXT='.tpl';
	/**
	 * Prefix of the cache variable name for storing parsed templates
	 */
	const TEMPLATE_CACHE_PREFIX='prado:template:';

	/**
	 * Initializes the module.
	 * This method is required by IModule and is invoked by application.
	 * It starts output buffer if it is enabled.
	 * @param TXmlElement module configuration
	 */
	public function init($config)
	{
		$this->getService()->setTemplateManager($this);
	}

	/**
	 * Loads the template corresponding to the specified class name.
	 * @return ITemplate template for the class name, null if template doesn't exist.
	 */
	public function getTemplateByClassName($className)
	{
		$class=new ReflectionClass($className);
		$tplFile=dirname($class->getFileName()).DIRECTORY_SEPARATOR.$className.self::TEMPLATE_FILE_EXT;
		return $this->getTemplateByFileName($tplFile);
	}

	/**
	 * Loads the template from the specified file.
	 * @return ITemplate template parsed from the specified file, null if the file doesn't exist.
	 */
	public function getTemplateByFileName($fileName)
	{
		if(($fileName=$this->getLocalizedTemplate($fileName))!==null)
		{
			Prado::trace("Loading template $fileName",'System.Web.UI.TTemplateManager');
			if(($cache=$this->getApplication()->getCache())===null)
				return new TTemplate(file_get_contents($fileName),dirname($fileName),$fileName);
			else
			{
				$array=$cache->get(self::TEMPLATE_CACHE_PREFIX.$fileName);
				if(is_array($array))
				{
					list($template,$timestamps)=$array;
					if($this->getApplication()->getMode()===TApplicationMode::Performance)
						return $template;
					$cacheValid=true;
					foreach($timestamps as $tplFile=>$timestamp)
					{
						if(!is_file($tplFile) || filemtime($tplFile)>$timestamp)
						{
							$cacheValid=false;
							break;
						}
					}
					if($cacheValid)
						return $template;
				}
				$template=new TTemplate(file_get_contents($fileName),dirname($fileName),$fileName);
				$includedFiles=$template->getIncludedFiles();
				$timestamps=array();
				$timestamps[$fileName]=filemtime($fileName);
				foreach($includedFiles as $includedFile)
					$timestamps[$includedFile]=filemtime($includedFile);
				$cache->set(self::TEMPLATE_CACHE_PREFIX.$fileName,array($template,$timestamps));
				return $template;
			}
		}
		else
			return null;
	}

	/**
	 * Finds a localized template file.
	 * @param string template file.
	 * @return string|null a localized template file if found, null otherwise.
	 */
	protected function getLocalizedTemplate($filename)
	{
		if(($app=$this->getApplication()->getGlobalization(false))===null)
			return is_file($filename)?$filename:null;
		foreach($app->getLocalizedResource($filename) as $file)
		{
			if(($file=realpath($file))!==false && is_file($file))
				return $file;
		}
		return null;
	}
}