smarty-php / smarty

Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.
Other
2.26k stars 711 forks source link

Bug when using cache #119

Closed fernandoval closed 8 years ago

fernandoval commented 8 years ago

The Composer upgrade to 3.1.28 version, then this bug happened in all cached pages:

Smarty_Internal_Template->render() undefined method in [omited path]/smarty/smarty/libs/sysplugins/smarty_internal_undefined.php on line 46

This not occurs in version 3.1.27

fernandoval commented 8 years ago

Example of code with problem:

$tpl = new \Smarty;
/* now I set smarty template directories */
$tpl->use_sub_dirs = true;
$tpl->setCacheDir('path-to-cache-dir');
$tpl->setCompileDir('path-to-compile-dir');
$tpl->setTemplateDir('path-to-template-dir');
$tpl->templateName = 'mytemplate.html';
$tpl->setCaching( \Smarty::CACHING_LIFETIME_CURRENT );
$tpl->setCacheLifetime(60);
if ( !$tpl->isCached('mytemplate.html', null, null) ) {
// go to database and assign variables
}
$tpl->assign('other_var', 'other data');
echo $tpl->fetch();

The error only happens when cache does not exists or is not expired (60s).

I supose any assigned variable is not cached.

uwetews commented 8 years ago

It was never intended that you call fetch() without a template name on a Smarty object. It can be used without parameter only on template objects created with smarty->create_template().

Note that isCached() could be called several time with different template names when you use {include} with individual caching parameter. There is no 1:1 relationship between the template name in isCached() and fetch(). Looks like it did work in 3.1.27 by chance.

Anyway Smarty should throw an exception in this case.

fernandoval commented 8 years ago

This code is a sample and not the real code. I did write this code rapidly only to do a sample and forgot to put a tamplate name into fetch() method.

I use Smarty inside my own framework. The developer can use Smarty or Twig template class when constructing your project. You can see how I do that into my personal open source framework, if you want.

This always did work fine until today. But when Composer did update Smarty to version 3.1.28, all pages that use cache stopping work.

I have some projects working fine with Smarty version 3.1.27.

The real code is like this:

class Index_Controller
{
    function __construct()
    {
        $tpl = new FW\Template('index');
        $tpl->setCaching('current');
        $tpl->setCacheLifetime(60);
        if (!$tpl->isCached()) {
            // Get data from database and then
            $tpl->assign('data', DataModel::get_data());
        }
        $tpl->assign('me', UserModel::me());
        $tpl->display();
    }
}

The display() method print the result of fetch() method and fetch() method returns like this:

return $this->tplObj->fetch($this->templateName . self::TPL_NAME_SUFIX, $this->templateCacheId, $this->templateCompileId);

I use Smarty in my projects about 5 years and only in this version I have a problem like this.

This error Smarty_Internal_Template->render() undefined method in /vendor/smarty/libs/sysplugins/smarty_internal_undefined.php on line 46 happens only in cached templates.

uwetews commented 8 years ago

Now I see what you have done. I will check it tomorrow.

uwetews commented 8 years ago

I have simulated your use case and could not find any problem. Have you emptied the compiled and cache folders after the upgrade? May be for some reason the version change was not detected automatically.

fernandoval commented 8 years ago

Yes, I have emptied the compiled and cache folders, then the system works for the first time. When I refresh, error occurs.

The system works when cache file does not exists or when cache life time expires. The error happens only when cached file is used.

I think the include command is causing the exception. Then I emptied include template file and error still happens.

Look the include line:

{include "_common/_header.tpl.html" class='sidebar-collapse fixed' skin='default' plugins='jqueryui,slimScroll,iCheck' wrapper=true pageTitle="About" style='about' nocache}

If I remove nocache from include command and put {nocache}{/nocache} into included file, the error is not throwed, but variables passed by include command is not sent to included file.

What changed in way how 3.1.28 version "include" other templates and cache it?

emmanix2002 commented 8 years ago

I just updated using composer to 3.1.29 and I've been getting the same error as @fernandoval . I haven't had the time to trace it but I'll be downgrading back to 3.1.27 for the meantime.

tniemann commented 8 years ago

Same for me, any new informations how to fix that?

I just updated using composer to 3.1.29 and I've been getting the same error as @fernandoval . I haven't had the time to trace it but I'll be downgrading back to 3.1.27 for the meantime.

tibahut commented 8 years ago

Same for me with 3.1.29. I fixed it by replacing $_smarty_tpl->smarty->ext->_subtemplate->render by $_smarty_tpl->smarty->ext->_subTemplate->render at line 272 in "smarty\libs\sysplugins\smarty_internal_compile_include.php"

fernandoval commented 8 years ago

Testing with the development version apparently the problem was solved. But I will still using the 3.1.27 version and wait for an official stable release 3.1.30.

implico commented 8 years ago

I have same problem (including a template inside nocache), also waiting for v3.1.30 of the best templating system :)

fernandoval commented 8 years ago

This bug was solved in 3.1.30 version.