1
0

remove in-memory caching, 60e15aa, since this needs to have enabled cache set

Since this is not possible with current template structure in Serendipity, this also removes the serendipity_smarty_class caching section and its notes to a text file.
This commit is contained in:
Ian
2014-11-02 14:23:30 +01:00
parent 0ce1d8991d
commit e11cbbc88f
3 changed files with 182 additions and 166 deletions

View File

@ -0,0 +1,124 @@
// enable properties with removing #cache#
#cache# $this->setCacheDir($serendipity['serendipityPath'] . 'cache');
#cache# $this->caching = true; // $this->setCaching(true);
/*
Caching is disabled, as long as we haven't figured out on how to use it best here....
Note: rodneyrehm
A cache_id is (ideally) supposed to identify a single page.
md5(REQUEST_URI) may _seem_ to be doing that, but /foo.html and /foo.html?foo=bar are the same resource
from S9Y's point of view - with DIFFERENT REQUEST_URIs. Your approach leads to a number of problems:
* flooding the cache space with duplicate content
* essentially making clearCache() useless, as md5 checksums of /foo.html and /foo.html?foo=bar have
exactly nothing in common.
You want to specify the pieces of cachable content yourself. Go with a structure like
post-123
post-123|comments (if you have a page for all comments belonging to that post)
post-123|comments|feed (if you have a comment feed for a certain post)
now you can clearCache('post-123') and comments and comments|feed are killed as well.
*/
/*
// APC and MEMCACHE are loaded from this libs plugins folder,
// but you need to have enabled caching by $smarty->caching = true (see Rodneys upper template structure note),
// which makes clear why we can't use Smarty caching currently with S9y
// enable for APC in-memory (RAM) storage caching - must be enabled in PHP
if(APC_EXTENSION_LOADED && !$serendipity['disable_apc']) {
$this->addPluginsDir ( SMARTY_DIR . 'plugins/' );
$this->caching_type = 'apc'; //$this->setCachingType ( 'apc' );
}
// enable for MEMCACHE storage caching - must be enabled in PHP
if(MEMCACHE_EXTENSION_LOADED && !$serendipity['disable_memcache']) {
$this->addPluginsDir ( SMARTY_DIR . 'plugins/' );
$this->caching_type = 'memcache'; //$this->setCachingType ( 'memcache' );
}
*/
// does set cache also need to be set to true?
#cache# $this->cache_modified_check = true; // to be used with display() method only, must be true to enable 304 headers
/*
Note: rodneyrehm
$cache_modified_check only works if you're using display() - it won't do anything on fetch().
It won't do anything if you have non-caching plugins or {insert} tags, either.
We're working on making this more intelligent for 3.2, but? work with what you've got in 3.1 first.
*/
// some documentary from the smarty forum
/*
With Smarty::CACHING_LIFETIME_SAVED the expiration date is written into the cached file.
So each cache_id / compile_id combination may have their own cache lifetime.
The point is simply, that once the cache lifetime (expiration date) has been saved to the cache file,
it cannot be altered except for clearing and regenerating said cache file
Template Inheritance
Using is_cached() on sub-templates has to set up caching before is_cached() calls,
e.g if (!$smarty->isCached('sub_test.tpl')) { $smarty->assign('foo', $foo); }.
The subtemplate will always be cached as specified in the {include} tag.
Otherwise you could never cache a subtemplate with caching disabled for the main template.
If you don't want to have the main template cached, turn caching off again after the is_cached() calls for the subtemplate.
So the example will cache sub_test.tpl, but not test.tpl
Using is_cached() on subtemplates has to set up caching before is_cached() calls.
The subtemplate will always be cached as specified in the {include} tag.
Otherwise you could never cache a subtemplate with caching disabled for the main template.
If you don't want to have the main template cached, turn caching off again after the is_cached() calls for the subtemplate.
So the example will cache sub_test.tpl but not test.tpl
Use $smarty->caching = Smarty::CACHING_LIFETIME_SAVED; with {include file="sub_test.tpl" cache_lifetime="120"} in test.tpl;
Use $smarty->caching = Smarty::CACHING_LIFETIME_CURRENT; with {include .... caching}
*/
#cache# $this->caching = Smarty::CACHING_LIFETIME_CURRENT; // $this->setCaching(2); // 1 will change the end of lifetime immediately.
# $this->caching = Smarty::CACHING_LIFETIME_SAVED; // $this->setCaching(Smarty::CACHING_LIFETIME_SAVED);
# $this->caching = Smarty::CACHING_OFF; // $this->setCaching(Smarty::CACHING_OFF) // stop caching >= 3.1.4
/*
Note: rodneyrehm
The CACHING_LIFETIME_SAVED option is something you only really "need" if many cache files have different lifetimes.
I've used Smarty intensively over the past years and I _never_ required LIFETIME_SAVED...
you can do $force_cache = true; to make the current page re-render to cache. This actually allows you to work with a very high
cache_lifetime and poll a secondary modified time from somewhere. You could then implement the serve-stale-until-updated caching approach.
I'll blog about this? probably around christmas
*/
// set the cache_lifetime for index.tpl to 5 minutes
#cache# $this->cache_lifetime = 300; // $this->setCacheLifetime(300); // 86400; // one day: 60*60*24
// some documentary from the smarty forum
/*
Smarty caching is based purely on the fetch() or display() call. So:
$smarty->fetch('application.tpl');
Will generate a cached output and use that on repeated calls. If you have multiple versions of this call, you need to pass a cache_id. Example:
$cache_id = md5($_SERVER['REQUEST_URI']);
$smarty->fetch('application.tpl',$cache_id);
It is entirely up to you what is taken into account for the cache_id (URL, etc.)
*/
// does this mean $this->setCacheId($id); is useless here and has to be set where the actual templates are called? or does ist work as something default?
/*
Note: rodneyrehm
when fetch(tpl) is called, Smarty::$cache_id is injected. If you need a single cache_id for the whole render complex, this may be the sane thing to do.
But you'll probably segment certain content. A Post does not have to be reendered for every new comment. It thus makes sense to separate these entities
into their own cache spaces. In turn they'd probably receive their own cache_ids. Although that is not _necessary_ as template_name and cache_id work in
conjunction. If both are supplied (to say clearCache()) template_name increases the specificity of cache_id, so only those items are purged that meet
both criteria.
*/
// some documentary from the smarty forum
/*
Smarty will use the cache_id for distributing the cache files into sub_dirs
A cache id is used if you cache different output generated by the same template as for example on a product page.
In such a case you should use a product id as cache id.
$this->cache_id($id); // $this->setCacheId($id);
*/
#cache# $this->cache_id = md5($_SERVER['REQUEST_URI']); // this isn't a good idea either, better have it disabled or use a special id
/*
Note: Ian
What kind of Serendipity ID could this be?
- see Rodneys first caching note
*/

View File

@ -1,4 +1,4 @@
<?php # $Id$
<?php
# Copyright (c) 2003-2005, Jannis Hermanns (on behalf the Serendipity Developer Team)
# All rights reserved. See LICENSE file for licensing details
@ -885,7 +885,9 @@ function serendipity_smarty_init($vars = array()) {
global $serendipity, $template_config, $template_global_config, $template_config_groups;
if (!isset($serendipity['smarty'])) {
$template_dir = $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template'];
if (!defined('IN_serendipity_admin') && file_exists($template_dir . '/template.inc.php')) {
// If this file exists, a custom template engine will be loaded.
// Beware: Smarty is used in the Admin backend, despite of this.
@ -905,9 +907,9 @@ function serendipity_smarty_init($vars = array()) {
@define('SMARTY_RESOURCE_CHAR_SET', LANG_CHARSET);
}
// define cache resources to load with smarty - see smarty class
@define('APC_EXTENSION_LOADED', extension_loaded('apc') && ini_get('apc.enabled'));
@define('MEMCACHE_EXTENSION_LOADED', (class_exists('Memcached',false) || class_exists('Memcache',false)) && (extension_loaded("memcached") || extension_loaded("memcache")));
// define cache resources to load with smarty - see smarty cache readme - needs enabled cache!
#@define('APC_EXTENSION_LOADED', extension_loaded('apc') && ini_get('apc.enabled'));
#@define('MEMCACHE_EXTENSION_LOADED', (class_exists('Memcached',false) || class_exists('Memcache',false)) && (extension_loaded("memcached") || extension_loaded("memcache")));
// Default Smarty Engine will be used
@define('SMARTY_DIR', S9Y_PEAR_PATH . 'Smarty/libs/');
@ -943,10 +945,12 @@ function serendipity_smarty_init($vars = array()) {
// debugging...
#echo '<pre>';print_r($serendipity['smarty']);echo '</pre>';#exit;
#$serendipity['smarty']->testInstall();exit;
// extreme debugging with undocumented internal flag which enables a trace output from the parser during debugging
#$serendipity['smarty']->_parserdebug = true; // be careful!
/**
* ToDo: Check for possible API changes in Smarty 3.2 [smarty_modifier_foobar, --> [smarty_modifier_foobar, smarty_function_foobar, smarty_block_foobar] (in class)]
* smarty_modifier_foobar(Smarty $smarty, $string, <EFBFBD>) vs. smarty_modifier_foobar($string, <EFBFBD>)
* smarty_modifier_foobar(Smarty $smarty, $string, ...) vs. smarty_modifier_foobar($string, ...)
**/
$serendipity['smarty']->registerPlugin('modifier', 'makeFilename', 'serendipity_makeFilename');
$serendipity['smarty']->registerPlugin('modifier', 'xhtml_target', 'serendipity_xhtml_target');

View File

@ -1,12 +1,12 @@
<?php
// serendipity_smarty_class.inc.php 2013-01-24 Ian
<?php
// serendipity_smarty_class.inc.php lm 2014-11-02 Ian
// define secure_dir and trusted_dirs for Serendipity_Smarty_Security_Policy class.
@define('S9Y_TEMPLATE_FALLBACK', $serendipity['serendipityPath'] . $serendipity['templatePath'] . 'default');
@define('S9Y_TEMPLATE_USERDEFAULT', $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template']);
@define('S9Y_TEMPLATE_USERDEFAULT_BACKEND', $serendipity['serendipityPath'] . $serendipity['templatePath'] . $serendipity['template_backend']);
@define('S9Y_TEMPLATE_SECUREDIR', $serendipity['serendipityPath'] . $serendipity['templatePath']);
// Create a wrapper class extended from Smarty_Security - which allows access to S9Y-plugin and S9Y-template dirs
class Serendipity_Smarty_Security_Policy extends Smarty_Security
@ -15,28 +15,28 @@ class Serendipity_Smarty_Security_Policy extends Smarty_Security
public $php_functions = array('isset', 'empty', 'count', 'sizeof', 'in_array', 'is_array', 'time', 'nl2br');
// to disable all PHP functions
#public $php_functions = null;
// remove PHP tags
public $php_handling = Smarty::PHP_REMOVE; // = 2
// set allowed modifiers only. (default = array( 'escape', 'count' );)
public $php_modifiers = array('escape', 'sprintf', 'sizeof', 'count', 'rand', 'print_r', 'str_repeat', 'nl2br');
public $allow_constants = true;
public $allow_super_globals = true;
// array of template directories that are considered secure. No need, as ...TemplateDir concidered secure implicitly. (unproofed)
public $secure_dir = array(S9Y_TEMPLATE_SECUREDIR); // do we need this then?
// actually no need, as template dirs are explicit defined as trusted_dirs. (unproofed)
public $trusted_dir = array(S9Y_TEMPLATE_USERDEFAULT, S9Y_TEMPLATE_USERDEFAULT_BACKEND, S9Y_TEMPLATE_FALLBACK); // do we need this then?
#public $modifiers = array(); // can be omitted, when all allowed
// to test this - overwrites Serendipity_Smarty::default_modifiers and Serendipity_Smarty_Security_Policy::php_modifiers - modifier 'escape' not allowed by security setting
#public $allowed_modifiers = array('escape:"htmlall"');
// This allows the fetch() and include calls to pull .tpl files from any directory,
// so that symlinked plugin directories outside the s9y path can be included properly.
// TODO / FUTURE: If Smarty will implement a seperation option to dissect fetch() from
@ -46,7 +46,7 @@ class Serendipity_Smarty_Security_Policy extends Smarty_Security
public function isTrustedResourceDir($path) {
return true;
}
public static function test()
{
var_dump(get_called_class());
@ -58,20 +58,20 @@ class Serendipity_Smarty extends Smarty
{
// bc mode for plugins Smarty2 compat INCLUDE_ANY fetch() calls - to avoid an undefinied property error.
public $security_settings = false;
public function __set($name, $value) {
if ($name == 'security') {
if ($value) {
$this->enableSecurity('Serendipity_Smarty_Security_Policy');
} else {
$this->disableSecurity();
}
}
} else {
parent::__set($name, $value);
}
}
/**
* It is often helpful to access the Smarty object from anywhere in your code, e.g in Plugins.
* Enables the Smarty object by instance always. The singleton pattern ensures that there is only one instance of the object available.
@ -95,7 +95,7 @@ class Serendipity_Smarty extends Smarty
{
// Class Constructor. These automatically get set with each new instance.
parent::__construct();
// call the objects initialization parameters
self::setParams();
}
@ -104,23 +104,24 @@ class Serendipity_Smarty extends Smarty
private function setParams()
{
global $serendipity;
// some documentary from the smarty forum
/*
Adressing a specific $template_dir (see 3.1 release notes)
Smarty 3.1 introduces the $template_dir index notation.
$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"} require the template bar.tpl to be loaded from $template_dir['foo'];
Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to define indexes along with the actual directories.
Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to define indexes along with the actual directories.
*/
/* +++++++++++++++++++++++++++++++++++++++++++
Set all directory setters
Smarty will always use the first template found in order of the given array. Move the least significant directory to the end.
*/
$template_engine = serendipity_get_config_var('template_engine');
$template_dirs = array();
$template_dirs = array();
if ($template_engine) {
$p = explode(',', $template_engine);
foreach($p AS $te) {
@ -137,7 +138,7 @@ class Serendipity_Smarty extends Smarty
if (S9Y_TEMPLATE_SECUREDIR != $serendipity['serendipityPath'] . $serendipity['templatePath']) {
$template_dirs[] = S9Y_TEMPLATE_SECUREDIR;
}
// disable plugin dir as added template dir is not adviced, if set security is enabled (backend & frontend need access to fetch plugin templates)
$template_dirs[] = $serendipity['serendipityPath'] . 'plugins';
// add default template to addTemplate array, if not already set in engine
@ -146,158 +147,45 @@ class Serendipity_Smarty extends Smarty
$this->setTemplateDir($template_dirs);
$this->setCompileDir($serendipity['serendipityPath'] . PATH_SMARTY_COMPILE);
$this->setConfigDir(array(S9Y_TEMPLATE_USERDEFAULT));
if ( ( !is_dir($this->getCompileDir()) || !is_writable($this->getCompileDir()) ) && IN_installer !== true) {
if(ini_get('display_errors') == 0 || ini_get('display_errors') == 'off') printf(DIRECTORY_WRITE_ERROR, $this->getCompileDir());
trigger_error(sprintf(DIRECTORY_WRITE_ERROR, $this->getCompileDir()), E_USER_ERROR);
}
#cache# $this->setCacheDir($serendipity['serendipityPath'] . 'cache'); // (enable #cache# properties)
/*
here we go with our other Smarty class properties, which can all be called by their property name (recommended)
$smarty->use_sub_dirs = true; or by $smarty->setUseSubDirs(true); and echo $smarty->getUseSubDirs();
$smarty->use_sub_dirs = true; or by $smarty->setUseSubDirs(true); and echo $smarty->getUseSubDirs();
as the latter's would run through an internal __call() wrapper function.
Note: rodneyrehm - From within the Smarty class context you can safely access properties like Smarty::$use_sub_dirs directly.
*/
/* +++++++++++++++++++++++++++++++++++
Set Smarty caching
*/
// enable for APC in-memory (RAM) storage caching - must be enabled in PHP
if(APC_EXTENSION_LOADED && !$serendipity['disable_apc']) {
$this->addPluginsDir ( SMARTY_DIR . 'plugins/' );
$this->caching_type = 'apc'; //$this->setCachingType ( 'apc' );
}
// enable for MEMCACHE storage caching - must be enabled in PHP
if(MEMCACHE_EXTENSION_LOADED && !$serendipity['disable_memcache']) {
$this->addPluginsDir ( SMARTY_DIR . 'plugins/' );
$this->caching_type = 'memcache'; //$this->setCachingType ( 'memcache' );
}
/*
Caching is disabled, as long as we haven't figured out on how to use it best here....
Note: rodneyrehm
A cache_id is (ideally) supposed to identify a single page.
md5(REQUEST_URI) may _seem_ to be doing that, but /foo.html and /foo.html?foo=bar are the same resource
from S9Y's point of view - with DIFFERENT REQUEST_URIs. Your approach leads to a number of problems:
* flooding the cache space with duplicate content
* essentially making clearCache() useless, as md5 checksums of /foo.html and /foo.html?foo=bar have
exactly nothing in common.
You want to specify the pieces of cachable content yourself. Go with a structure like
post-123
post-123|comments (if you have a page for all comments belonging to that post)
post-123|comments|feed (if you have a comment feed for a certain post)
now you can clearCache('post-123') and comments and comments|feed are killed as well.
*/
// does set cache also need to be set to true?
#cache# $this->cache_modified_check = true; // to be used with display() method only, must be true to enable 304 headers
/*
Note: rodneyrehm
$cache_modified_check only works if you're using display() - it won't do anything on fetch().
It won't do anything if you have non-caching plugins or {insert} tags, either.
We're working on making this more intelligent for 3.2, but<75> work with what you've got in 3.1 first.
Set Smarty caching - outsourced to README_SMARTY_CACHING_PURPOSES.txt
Not usable in Serendipity with current template structure!
*/
// some documentary from the smarty forum
/*
With Smarty::CACHING_LIFETIME_SAVED the expiration date is written into the cached file.
So each cache_id / compile_id combination may have their own cache lifetime.
The point is simply, that once the cache lifetime (expiration date) has been saved to the cache file,
it cannot be altered except for clearing and regenerating said cache file
Template Inheritance
Using is_cached() on sub-templates has to set up caching before is_cached() calls,
e.g if (!$smarty->isCached('sub_test.tpl')) { $smarty->assign('foo', $foo); }.
The subtemplate will always be cached as specified in the {include} tag.
Otherwise you could never cache a subtemplate with caching disabled for the main template.
If you don't want to have the main template cached, turn caching off again after the is_cached() calls for the subtemplate.
So the example will cache sub_test.tpl, but not test.tpl
Using is_cached() on subtemplates has to set up caching before is_cached() calls.
The subtemplate will always be cached as specified in the {include} tag.
Otherwise you could never cache a subtemplate with caching disabled for the main template.
If you don't want to have the main template cached, turn caching off again after the is_cached() calls for the subtemplate.
So the example will cache sub_test.tpl but not test.tpl
Use $smarty->caching = Smarty::CACHING_LIFETIME_SAVED; with {include file="sub_test.tpl" cache_lifetime="120"} in test.tpl;
Use $smarty->caching = Smarty::CACHING_LIFETIME_CURRENT; with {include .... caching}
*/
#cache# $this->caching = Smarty::CACHING_LIFETIME_CURRENT; // $this->setCaching(2); // 1 will change the end of lifetime immediately.
# $this->caching = Smarty::CACHING_LIFETIME_SAVED; // $this->setCaching(Smarty::CACHING_LIFETIME_SAVED);
# $this->caching = Smarty::CACHING_OFF; // $this->setCaching(Smarty::CACHING_OFF) // stop caching >= 3.1.4
/*
Note: rodneyrehm
The CACHING_LIFETIME_SAVED option is something you only really "need" if many cache files have different lifetimes.
I've used Smarty intensively over the past years and I _never_ required LIFETIME_SAVED...
you can do $force_cache = true; to make the current page re-render to cache. This actually allows you to work with a very high
cache_lifetime and poll a secondary modified time from somewhere. You could then implement the serve-stale-until-updated caching approach.
I'll blog about this<69> probably around christmas
*/
// set the cache_lifetime for index.tpl to 5 minutes
#cache# $this->cache_lifetime = 300; // $this->setCacheLifetime(300); // 86400; // one day: 60*60*24
// some documentary from the smarty forum
/*
Smarty caching is based purely on the fetch() or display() call. So:
$smarty->fetch('application.tpl');
Will generate a cached output and use that on repeated calls. If you have multiple versions of this call, you need to pass a cache_id. Example:
$cache_id = md5($_SERVER['REQUEST_URI']);
$smarty->fetch('application.tpl',$cache_id);
It is entirely up to you what is taken into account for the cache_id (URL, etc.)
*/
// does this mean $this->setCacheId($id); is useless here and has to be set where the actual templates are called? or does ist work as something default?
/*
Note: rodneyrehm
when fetch(tpl) is called, Smarty::$cache_id is injected. If you need a single cache_id for the whole render complex, this may be the sane thing to do.
But you'll probably segment certain content. A Post does not have to be reendered for every new comment. It thus makes sense to separate these entities
into their own cache spaces. In turn they'd probably receive their own cache_ids. Although that is not _necessary_ as template_name and cache_id work in
conjunction. If both are supplied (to say clearCache()) template_name increases the specificity of cache_id, so only those items are purged that meet
both criteria.
*/
// some documentary from the smarty forum
/*
Smarty will use the cache_id for distributing the cache files into sub_dirs
A cache id is used if you cache different output generated by the same template as for example on a product page.
In such a case you should use a product id as cache id.
$this->cache_id($id); // $this->setCacheId($id);
*/
#cache# $this->cache_id = md5($_SERVER['REQUEST_URI']); // this isn't a good idea either, better have it disabled or use a special id
/*
Note: Ian
What kind of Serendipity ID could this be?
- see Rodneys first caching note
*/
/* ++++++++++++++++++++++++++++++++++++++++++++++
Set all other needed Smarty class properties
*/
#???# $this->merge_compiled_includes = true; // $this->setMergeCompiledIncludes(true); // what is this for?
#$this->merge_compiled_includes = true; // $this->setMergeCompiledIncludes(true); // With this option the subtemplate code is stored together with the calling template.
// default here to be overwritten by $serendipity['production'] == 'debug' - see below!
$this->debugging = false; // $this->setDebugging(false);
$this->debugging = false; // $this->setDebugging(false);
// Smarty will create subdirectories under the compiled templates and cache directories if $use_sub_dirs is set to TRUE, default is FALSE.
$this->use_sub_dirs = ( ini_get('safe_mode') ? false : true ); // $this->setUseSubDirs(false); // cache and compile dir only
// Smarty should update the cache files automatically if $smarty->compile_check is true.
// Smarty should update the cache files automatically if $smarty->compile_check is true.
$this->compile_check = true; // $this->setCompileCheck(true);
#$this->compile_check = COMPILECHECK_OFF (false) - template files will not be checked
#$this->compile_check = COMPILECHECK_ON (true) - template files will always be checked
#$this->compile_check = COMPILECHECK_CACHEMISS - template files will be checked, if caching is enabled and there is no existing cache file, or it has expired
#$this->compile_check = COMPILECHECK_CACHEMISS - template files will be checked, if caching is enabled and there is no existing cache file, or it has expired
/*
Note: rodneyrehm
If you actually manage to build a page from a single template (with inclusions and plugins and stuff)
@ -316,25 +204,25 @@ class Serendipity_Smarty extends Smarty
// production == debug extends from s9y version information (alpha|beta|cvs) is always debug | USE ===
if ($serendipity['production'] === 'debug') {
$this->force_compile = true; // $this->setForceCompile(true);
$this->caching = false; // $this->setCaching(false);
$this->caching = false; // $this->setCaching(false);
$this->debugging = true; // $this->setDebugging(true);
}
// set smarty error reporting. General error_reporting is set in serendipity/serendipity_config.inc.php
$this->error_reporting = E_ALL & ~(E_NOTICE|E_STRICT);
// we use our own error_handler and get in conflicts with smarty?
// $this->muteExpectedErrors();
}
}
/*
Note: Ian
These BC methods are to be kept as long as not converted to new syntax in additional plugins
Search "$serendipity['smarty']->register_" (11 hits in 6 files) in additional_plugins
serendipity_event_communityrating.php, serendipity_event_customarchive.php, serendipity_event_microformats.php,
serendipity_event_communityrating.php, serendipity_event_customarchive.php, serendipity_event_microformats.php,
serendipity_event_multilingual.php, serendipity_event_smartymarkup.php, serendipity_event_staticpage.php
*/
/**
* Registers custom function to be used in templates - BC mode Smarty 2 -> 3
*
@ -392,9 +280,9 @@ class Serendipity_Smarty extends Smarty
return $this->getTemplateVars($name);
}
public static function test()
{
public static function test()
{
var_dump(get_called_class());
}
}
}