Adding tests for securing private variable inclussion on templates.
[akelos.git] / lib / AkActionView / AkPhpTemplateHandler.php
blobdc60082cd64a2d76f0c585980083345d301db532
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
11 /**
12 * @package ActionView
13 * @subpackage TemplateEngines
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
19 defined('AK_DEFAULT_TEMPLATE_ENGINE') ? null : define('AK_DEFAULT_TEMPLATE_ENGINE', 'AkSintags');
20 defined('AK_TEMPLATE_SECURITY_CHECK') ? null : define('AK_TEMPLATE_SECURITY_CHECK', true);
21 defined('AK_PHP_CODE_SANITIZER_FOR_TEMPLATE_HANDLER')? null : define('AK_PHP_CODE_SANITIZER_FOR_TEMPLATE_HANDLER', 'AkPhpCodeSanitizer');
23 class AkPhpTemplateHandler
25 var $_options = array();
26 var $_AkActionView;
27 var $_templateEngine = AK_DEFAULT_TEMPLATE_ENGINE;
28 var $_codeSanitizerClass = AK_PHP_CODE_SANITIZER_FOR_TEMPLATE_HANDLER;
30 function AkPhpTemplateHandler(&$AkActionView)
32 $this->_AkActionView =& $AkActionView;
35 function render(&$____code, $____local_assigns, $____file_path)
37 $this->_options['variables'] = $____local_assigns;
38 $this->_options['code'] =& $____code;
39 $this->_options['functions'] = array('');
40 $this->_options['file_path'] = $____file_path;
42 if($this->_templateNeedsCompilation()){
43 if(!class_exists($this->_templateEngine)){
44 require_once(AK_LIB_DIR.DS.'AkActionView'.DS.'TemplateEngines'.DS.$this->_templateEngine.'.php');
46 $____template_engine_name = $this->_templateEngine;
48 $TemplateEngine =& new $____template_engine_name();
50 $TemplateEngine->init(array(
51 'code' => $____code,
52 ));
54 $____code = $TemplateEngine->toPhp();
56 if($____code === false){
57 trigger_error(join("\n",$TemplateEngine->getErrors()), E_USER_ERROR);
58 return false;
60 if(AK_TEMPLATE_SECURITY_CHECK && $this->_templateNeedsValidation()){
61 if(!$this->_assertForValidTemplate()){
62 return false;
65 $this->_saveCompiledTemplate();
68 (array)$____local_assigns;
69 extract($____local_assigns, EXTR_SKIP);
70 ob_start();
71 include($this->_getCompiledTemplatePath());
73 !empty($shared) ? $this->_AkActionView->addSharedAttributes($shared) : null;
75 return ob_get_clean();
79 function _assertForValidTemplate()
81 static $CodeSanitizer;
82 if(empty($CodeSanitizer)){
83 if($this->_codeSanitizerClass == 'AkPhpCodeSanitizer'){
84 require_once(AK_LIB_DIR.DS.'AkActionView'.DS.'AkPhpCodeSanitizer.php');
86 $class = $this->_codeSanitizerClass;
87 $CodeSanitizer = new $class();
89 $CodeSanitizer->setOptions($this->_options);
90 return $CodeSanitizer->isCodeSecure();
93 function _templateNeedsCompilation()
95 if(!file_exists($this->_getCompiledTemplatePath())){
96 return true;
98 $tpl_time = @filemtime($this->_getTemplatePath());
99 $compiled_tpl_time = filemtime($this->_getCompiledTemplatePath());
100 if($tpl_time > $compiled_tpl_time){
101 return true;
104 return false;
107 function _templateNeedsValidation()
109 return true;
112 function _getTemplateBasePath()
114 if(empty($this->_options['template_base_path'])){
115 $template_file_name = $this->_getTemplateFilename();
116 if(!empty($template_file_name)){
117 $this->_options['template_base_path'] = rtrim(str_replace($template_file_name,'',$this->_options['file_path']),'\/');
118 if(defined('AK_COMPILED_VIEWS_DIR') && !strstr($this->_options['template_base_path'], AK_TMP_DIR)){
119 $this->_options['template_base_path'] = str_replace(AK_BASE_DIR, AK_COMPILED_VIEWS_DIR, $this->_options['template_base_path']);
121 }else{
122 $this->_options['template_base_path'] = AK_COMPILED_VIEWS_DIR;
125 return $this->_options['template_base_path'];
129 function _getTemplatePath()
131 return $this->_options['file_path'];
134 function _getTemplateFilename()
136 $this->_options['template_filename'] = empty($this->_options['template_filename']) && preg_match('/[^\/^\\\]+$/',$this->_options['file_path'],$match) ? $match[0] : @$this->_options['template_filename'];
137 return $this->_options['template_filename'];
140 function _getCompiledTemplateBasePath()
142 if(empty($this->_options['compiled_template_base_path'])){
143 $this->_options['compiled_template_base_path'] = $this->_getTemplateBasePath().DS.'compiled';
145 return $this->_options['compiled_template_base_path'];
148 function _getCompiledTemplatePath()
150 if(empty($this->_options['compiled_file_name'])){
151 $template_filename = $this->_getTemplateFilename();
152 $this->_options['compiled_file_name'] = $this->_getCompiledTemplateBasePath().DS.
153 (empty($template_filename) ? 'tpl_'.md5($this->_options['code']) : $template_filename).'.php';
155 return $this->_options['compiled_file_name'];
160 function _saveCompiledTemplate()
162 Ak::file_put_contents($this->_getCompiledTemplatePath(),$this->_options['code']);