Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F772189
template_cache.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Feb 1, 5:35 AM
Size
11 KB
Mime Type
text/x-php
Expires
Mon, Feb 3, 5:35 AM (3 h, 27 m)
Engine
blob
Format
Raw Data
Handle
555730
Attached To
rINP In-Portal
template_cache.php
View Options
<?php
/**
* @version $Id: template_cache.php 14241 2011-03-16 20:24:35Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined
(
'FULL_PATH'
)
or
die
(
'restricted access!'
);
class
TemplatesCache
extends
kHelper
{
/**
* Base path for searching templates
*
* @var string
*/
var
$BasePath
;
/**
* Force templates cache to search templates on front-end:
* true - search for theme name in template name
* false - don't search anywhere
* name - theme name to prepend for each template name
*
* @var mixed
*/
var
$forceThemeName
=
false
;
/**
* Compile templates to database
*
* @var bool
*/
var
$_compileToDatabase
=
false
;
/**
* Compress compiled templates
*
* @var bool
*/
var
$_compressOutput
=
false
;
/**
* Template locations of each module
*
* @var Array
*/
var
$_modulePaths
=
Array
();
function
TemplatesCache
()
{
parent
::
kHelper
();
if
(
!
defined
(
'T_DOC_COMMENT'
)
)
{
// method "TemplatesCache::_compress" uses such constant, but it's only available since PHP 5.0.0
define
(
'T_DOC_COMMENT'
,
366
);
}
$this
->
BasePath
=
FULL_PATH
.
THEMES_PATH
;
$this
->
_compileToDatabase
=
defined
(
'SAFE_MODE'
)
&&
SAFE_MODE
;
$this
->
_compressOutput
=
$this
->
Application
->
ConfigValue
(
'UseTemplateCompression'
);
if
(
$this
->
Application
->
isAdmin
)
{
// prepare module template paths for quick access
$module_paths
=
Array
();
foreach
(
$this
->
Application
->
ModuleInfo
as
$module_name
=>
$module_info
)
{
$module_paths
[
mb_strtolower
(
$module_name
)
]
=
rtrim
(
$module_info
[
'Path'
],
'/'
);
}
$this
->
_modulePaths
=
$module_paths
;
}
}
/**
* Based on template name gets it's location on disk and owner module
*
* @param string $filename
* @return Array 0 - path on disk, 1 - template name
*/
function
GetTemplatePaths
(
$filename
)
{
if
(
$this
->
Application
->
isAdmin
&&
array_key_exists
(
$filename
,
$this
->
Application
->
ReplacementTemplates
))
{
// process admin template replacement
$filename
=
$this
->
Application
->
ReplacementTemplates
[
$filename
];
}
// allows to use non-replaced version of replaced template
$filename
=
preg_replace
(
'/^original:(.*)/'
,
'
\\
1'
,
$filename
);
if
(
preg_match
(
'#^[
\/
]{0,1}([^
\/
]*)
\/
(.*)#'
,
$filename
,
$regs
))
{
$first_dir
=
$regs
[
1
];
$module_filename
=
$regs
[
2
];
}
else
{
$first_dir
=
''
;
$module_filename
=
$filename
;
}
if
(
is_string
(
$this
->
forceThemeName
))
{
// when defined, then all templates are read from given theme name
$first_dir
=
'theme:'
.
$this
->
forceThemeName
.
(
$first_dir
?
'/'
.
$first_dir
:
''
);
}
if
(
$this
->
Application
->
isAdmin
&&
array_key_exists
(
$first_dir
,
$this
->
_modulePaths
))
{
// template belongs to one of the modules
$path
=
FULL_PATH
.
'/'
.
$this
->
_modulePaths
[
$first_dir
]
.
'/admin_templates'
;
}
elseif
(
$this
->
forceThemeName
&&
preg_match
(
'/^theme:(.*)/'
,
$first_dir
,
$regs
))
{
// ability to use Front-End templates in admin (only during mass compilation)
$path
=
FULL_PATH
.
'/themes/'
.
$regs
[
1
];
}
else
{
// template from "core" module
$path
=
$this
->
BasePath
;
$module_filename
=
$first_dir
.
'/'
.
$module_filename
;
}
return
Array
(
$path
,
$module_filename
);
}
/**
* Returns template filename by given template name
*
* @param string $filename
* @return string
*/
function
GetRealFilename
(
$filename
)
{
list
(
$path
,
$module_filename
)
=
$this
->
GetTemplatePaths
(
$filename
);
return
$path
.
'/'
.
trim
(
$module_filename
,
'/'
);
}
/**
* Checks, that given template exists on disk
*
* @param string $filename
* @return bool
*/
function
TemplateExists
(
$filename
)
{
if
((
strpos
(
$filename
,
'../'
)
!==
false
)
||
(
trim
(
$filename
)
!==
$filename
))
{
// when relative paths or special chars are found template names from url, then it's hacking attempt
return
false
;
}
$real_file
=
$this
->
GetRealFilename
(
strtolower
(
$filename
)
);
if
(
substr
(
$real_file
,
-
4
)
!=
'.tpl'
)
{
// add ".tpl" file extension, when not specified in template name
$real_file
.=
'.tpl'
;
}
return
file_exists
(
$real_file
);
}
/**
* Returns information about template compilation status
*
* @param string $template
* @return Array
*/
function
GetPreParsed
(
$template
)
{
$real_name
=
$this
->
GetRealFilename
(
$template
);
$fname
=
str_replace
(
FULL_PATH
,
WRITEABLE
.
'/cache'
,
$real_name
.
'.php'
);
$tname
=
$real_name
.
'.tpl'
;
if
(!
file_exists
(
$tname
))
{
// given template doesn't exist
return
false
;
}
if
(
$this
->
_compileToDatabase
)
{
$sql
=
'SELECT *
FROM '
.
TABLE_PREFIX
.
'Cache
WHERE VarName = "'
.
$fname
.
'"'
;
$cached
=
$this
->
Conn
->
GetRow
(
$sql
);
if
(
$cached
!==
false
&&
$cached
[
'Cached'
]
>
filemtime
(
$tname
))
{
return
Array
(
'active'
=>
1
,
'fname'
=>
$fname
,
'tname'
=>
$tname
,
'mode'
=>
'db'
,
'content'
=>
$cached
[
'Data'
]);
}
}
else
{
if
(
file_exists
(
$fname
)
&&
file_exists
(
$tname
)
&&
filemtime
(
$fname
)
>
filemtime
(
$tname
))
{
return
Array
(
'active'
=>
1
,
'fname'
=>
$fname
,
'tname'
=>
$tname
,
'mode'
=>
'file'
);
}
if
(!
file_exists
(
$fname
))
{
// make sure to create directory if pre-parsed file does not exist
$this
->
CheckDir
(
dirname
(
$fname
),
WRITEABLE
.
'/cache'
);
}
}
// when compiled template is expired or doesn't exist
return
Array
(
'active'
=>
0
,
'fname'
=>
$fname
,
'tname'
=>
$tname
,
'mode'
=>
'file'
);
}
/**
* Saves compiled template version to database or disk
*
* @param string $filename
* @param string $compiled_template
*/
function
saveTemplate
(
$filename
,
&
$compiled_template
)
{
if
(
$this
->
_compileToDatabase
)
{
$fields_hash
=
Array
(
'VarName'
=>
$filename
,
'Data'
=>
&
$compiled_template
,
'Cached'
=>
adodb_mktime
(),
);
$this
->
Conn
->
doInsert
(
$fields_hash
,
TABLE_PREFIX
.
'Cache'
,
'REPLACE'
);
}
else
{
$fp
=
fopen
(
$filename
,
'w'
);
if
(
$this
->
_compressOutput
)
{
$compiled_template
=
$this
->
_compress
(
$compiled_template
);
}
if
(!
fwrite
(
$fp
,
$compiled_template
))
{
trigger_error
(
'Saving compiled template failed'
,
E_USER_ERROR
);
}
fclose
(
$fp
);
}
}
/**
* Runs template and returns result (template already should be compiled by now)
*
* @param NParser $_parser
* @param Array $pre_parsed
* @return string
*/
function
&
runTemplate
(&
$_parser
,
&
$pre_parsed
)
{
ob_start
();
if
(
$this
->
_compileToDatabase
)
{
$sql
=
'SELECT *
FROM '
.
TABLE_PREFIX
.
'Cache
WHERE VarName = "'
.
$pre_parsed
[
'fname'
]
.
'"'
;
$cached
=
$this
->
Conn
->
GetRow
(
$sql
);
if
((
$cached
!==
false
)
&&
(
$cached
[
'Cached'
]
>
filemtime
(
$pre_parsed
[
'tname'
])))
{
eval
(
'?'
.
'>'
.
$cached
[
'Data'
]);
}
}
else
{
if
(
$pre_parsed
[
'mode'
]
==
'file'
)
{
include
(
$pre_parsed
[
'fname'
]);
}
else
{
eval
(
'?'
.
'>'
.
$pre_parsed
[
'content'
]);
}
}
$output
=
ob_get_clean
();
return
$output
;
}
/**
* Compress given php code
*
* @param string $src
* @return string
*/
function
_compress
(
$src
)
{
// Whitespaces left and right from this signs can be ignored
static
$IW
=
array
(
T_CONCAT_EQUAL
,
// .=
T_DOUBLE_ARROW
,
// =>
T_BOOLEAN_AND
,
// &&
T_BOOLEAN_OR
,
// ||
T_IS_EQUAL
,
// ==
T_IS_NOT_EQUAL
,
// != or <>
T_IS_SMALLER_OR_EQUAL
,
// <=
T_IS_GREATER_OR_EQUAL
,
// >=
T_INC
,
// ++
T_DEC
,
// --
T_PLUS_EQUAL
,
// +=
T_MINUS_EQUAL
,
// -=
T_MUL_EQUAL
,
// *=
T_DIV_EQUAL
,
// /=
T_IS_IDENTICAL
,
// ===
T_IS_NOT_IDENTICAL
,
// !==
T_DOUBLE_COLON
,
// ::
T_PAAMAYIM_NEKUDOTAYIM
,
// ::
T_OBJECT_OPERATOR
,
// ->
T_DOLLAR_OPEN_CURLY_BRACES
,
// ${
T_AND_EQUAL
,
// &=
T_MOD_EQUAL
,
// %=
T_XOR_EQUAL
,
// ^=
T_OR_EQUAL
,
// |=
T_SL
,
// <<
T_SR
,
// >>
T_SL_EQUAL
,
// <<=
T_SR_EQUAL
,
// >>=
);
$tokens
=
token_get_all
(
$src
);
$new
=
""
;
$c
=
sizeof
(
$tokens
);
$iw
=
false
;
// ignore whitespace
$ih
=
false
;
// in HEREDOC
$ls
=
""
;
// last sign
$ot
=
null
;
// open tag
for
(
$i
=
0
;
$i
<
$c
;
$i
++)
{
$token
=
$tokens
[
$i
];
if
(
is_array
(
$token
))
{
list
(
$tn
,
$ts
)
=
$token
;
// tokens: number, string, line
$tname
=
token_name
(
$tn
);
if
(
$tn
==
T_INLINE_HTML
)
{
$new
.=
$ts
;
$iw
=
false
;
}
else
{
if
(
$tn
==
T_OPEN_TAG
)
{
if
(
strpos
(
$ts
,
" "
)
||
strpos
(
$ts
,
"
\n
"
)
||
strpos
(
$ts
,
"
\t
"
)
||
strpos
(
$ts
,
"
\r
"
))
{
$ts
=
rtrim
(
$ts
);
}
$ts
.=
" "
;
$new
.=
$ts
;
$ot
=
T_OPEN_TAG
;
$iw
=
true
;
}
elseif
(
$tn
==
T_OPEN_TAG_WITH_ECHO
)
{
$new
.=
$ts
;
$ot
=
T_OPEN_TAG_WITH_ECHO
;
$iw
=
true
;
}
elseif
(
$tn
==
T_CLOSE_TAG
)
{
if
(
$ot
==
T_OPEN_TAG_WITH_ECHO
)
{
$new
=
rtrim
(
$new
,
"; "
);
}
else
{
$ts
=
" "
.
$ts
;
}
$new
.=
$ts
;
$ot
=
null
;
$iw
=
false
;
}
elseif
(
in_array
(
$tn
,
$IW
))
{
$new
.=
$ts
;
$iw
=
true
;
}
elseif
(
$tn
==
T_CONSTANT_ENCAPSED_STRING
||
$tn
==
T_ENCAPSED_AND_WHITESPACE
)
{
if
(
$ts
[
0
]
==
'"'
)
{
$ts
=
addcslashes
(
$ts
,
"
\n\t\r
"
);
}
$new
.=
$ts
;
$iw
=
true
;
}
elseif
(
$tn
==
T_WHITESPACE
)
{
$nt
=
@
$tokens
[
$i
+
1
];
if
(!
$iw
&&
(!
is_string
(
$nt
)
||
$nt
==
'$'
)
&&
!
in_array
(
$nt
[
0
],
$IW
))
{
$new
.=
" "
;
}
$iw
=
false
;
}
elseif
(
$tn
==
T_START_HEREDOC
)
{
$new
.=
"<<<S
\n
"
;
$iw
=
false
;
$ih
=
true
;
// in HEREDOC
}
elseif
(
$tn
==
T_END_HEREDOC
)
{
$new
.=
"S;"
;
$iw
=
true
;
$ih
=
false
;
// in HEREDOC
for
(
$j
=
$i
+
1
;
$j
<
$c
;
$j
++)
{
if
(
is_string
(
$tokens
[
$j
])
&&
$tokens
[
$j
]
==
";"
)
{
$i
=
$j
;
break
;
}
else
if
(
$tokens
[
$j
][
0
]
==
T_CLOSE_TAG
)
{
break
;
}
}
}
elseif
(
$tn
==
T_COMMENT
||
$tn
==
T_DOC_COMMENT
)
{
$iw
=
true
;
}
else
{
/*if (!$ih) {
// this also lowecases attribute names :(
$ts = strtolower($ts);
}*/
$new
.=
$ts
;
$iw
=
false
;
}
}
$ls
=
""
;
}
else
{
if
((
$token
!=
";"
&&
$token
!=
":"
)
||
$ls
!=
$token
)
{
$new
.=
$token
;
$ls
=
$token
;
}
$iw
=
true
;
}
}
return
$new
;
}
/**
* Recursive mkdir
*
* @param string $dir
* @param string $base_path base path to directory where folders should be created in
*/
function
CheckDir
(
$dir
,
$base_path
=
''
)
{
if
(
file_exists
(
$dir
))
{
return
;
}
else
{
// remove $base_path from beggining because it is already created during install
$dir
=
preg_replace
(
'/^'
.
preg_quote
(
$base_path
.
'/'
,
'/'
).
'/'
,
''
,
$dir
,
1
);
$segments
=
explode
(
'/'
,
$dir
);
$cur_path
=
$base_path
;
foreach
(
$segments
as
$segment
)
{
// do not add leading / for windows paths (c:\...)
$cur_path
.=
preg_match
(
'/^[a-zA-Z]{1}:/'
,
$segment
)
?
$segment
:
'/'
.
$segment
;
if
(!
file_exists
(
$cur_path
))
{
mkdir
(
$cur_path
);
}
}
}
}
}
Event Timeline
Log In to Comment