Upgrade Smarty to Smarty3+
This is a meta issue for looking at moving off legacy Smarty2
Status
-
Smarty3 is recommended in 5.69+ as the preferred version
-
From 5.71 Smarty4 is the preferred version.
-
Smarty5 is the preferred version in CiviCRM 5.74+
-
Smarty2 is still usable in all versions but is being phased out (some extensions, like Extended Reports, may not fully support Smarty2 in recent releases)
to enable - add a define to civicrm_settings.php
like this (adjust sample path as desired)
5.74
if (!defined('CIVICRM_SMARTY_AUTOLOAD_PATH')) {
define('CIVICRM_SMARTY_AUTOLOAD_PATH', $civicrm_root . '/packages/smarty5/Smarty.php');
}
5.71
if (!defined('CIVICRM_SMARTY_AUTOLOAD_PATH')) {
define('CIVICRM_SMARTY_AUTOLOAD_PATH', $civicrm_root . '/packages/smarty4/vendor/autoload.php');
}
5.69
if (!defined('CIVICRM_SMARTY3_AUTOLOAD_PATH')) {
define('CIVICRM_SMARTY3_AUTOLOAD_PATH', $civicrm_root . '/packages/smarty3/vendor/autoload.php');
}
Gaps as of 5.68
-
resolve Sections section of civi-report https://github.com/civicrm/civicrm-core/pull/27777 -
the online membership receipt has an instance of 'crmMoney maths' - this should be the same as other templates - I'm just struggling to understand the double contribution thing with separate membership payment -
not all extensions are compatible - see below
Things that cause compatibility issues (resolve in core with the exception of the 2 listed)
-
maths in Smartyv2 {amount+taxAmount|crmMoney} is implicitly
{($amount+$taxAmount)|crmMoney}
- whereas in Smarty3 it does not resolve correctly without the braces - which Smarty2 does not support. Generally the maths can be moved to the php layer - Extensions with CiviX versions lower than 23.01 - mostly these only cause notices & smarty files will not load - although some very old civix versions will cause a hard fail. Running civix will remove these lines
And add in the smarty mixin if smarty files are in use
- Accessing the smarty property
_tplVars
directly (in most cases running civix will fix) - usage of
{php}
within tpl files - incorrect variable assignments in templates for correct quotes and backticks, e.g.
{assign var="foo" value="bar-`$something.else`"}
if a variable is being concatenated into a string in a template, the string should be surrounded by double quotes, not single. If the variable name contains characters other than a-zA-Z0-9_ (e.g. a period), then it needs to be surrounded by backticks. If a variable is an int and you're doing math, don't use backticks (e.g. value=$one.thing+1
).
Why smarty3/4/5
- Accessing documentation is less confusing as Smarty documentation targets v3+
- Smarty3 is more secure - in part because it has security releases, in part because escaping is on by default - which actually still seems disabled in the working version - but it makes sense to upgrade smarty first
- Smarty3 is more efficient in handling one-off strings. We have kinda hacked this into Smartyv2 with a combination of the core function
CRM_Utils_String::parseOneOffStringThroughSmarty
and hacking some security intofetch
but under volume this can result in #4143 (closed) and also reads & writes to disk more than is ideal - We initially worked to get Smarty3 working. We have since built on that to get Smarty4 & the since-released Smarty5 version.
Things that need to be done in extensions
Other than the first item these are fairly uncommon
-
run
civix upgrade
on extensions where the civix version of the extension is 23.01 or lower. (it's worth making sure you have the latest civix first -
test any unusual smarty screens
Challenges outstanding
- When we are happy from a QA point ov view we need to roll it out as part of our package. At that point we will need to decide if it is opt in & what that looks like or whether it is a hard-switch.
** Challenges that we are doing OK on **
- Autoloading - works OK if extensions are updated to recent civix.
-
Function Naming - Smarty3 has renamed a bunch of functions - eg
register_resource
becomes -
Fetch override - We have overridden the
fetch
function to try to mimic Smartyv3 security in v2 - this function has a different signature inv3
so overriding it is a noisy experience. Solution is to move our patches to Smartyv2 packages - Escape by default - so far this seems to have not been enabled on Smarty3 - I think it's fine to defer worrying about it until the upgrade is done if it is not hurting us
- Invalid Smarty Syntax - so far I have identified that the use of '`' in Smarty causes a hard crash - we don't do this much, mostly in older code... @larssg has done a pretty solid clean up in core but there could be some in extensions
-
Direct access of class properties - we have a couple of places that do things like
$smarty->_tpl_vars
- those need replacing withget_template_vars or, if we add compatibility
getTemplateVars` -
Register String Resource - this is not an issue for
v3
but is the current blocker onv4
the parameter type in our functioncivicrm_smarty_register_string_resource
is anarray
but that is not v4-compatible
Related