Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smarty creates cache for includes with cache_id even when it's null and cache disabled #1061

Open
Razunter opened this issue Sep 2, 2024 · 19 comments

Comments

@Razunter
Copy link

Razunter commented Sep 2, 2024

I have Smarty cache globally disabled, cache_lifetime set to 0, but include with any cache_id still creates cache files.

{include file='example.tpl' cache_id=NULL}

Any way to disable this behavior?


v5.4.1

@devthisath
Copy link

Hello,

  1. To disable caching for a specific code snippet or include file, wrap the include tag or code snippet with {nocache}{/nocache} and remove the cache_id attribute from the include tag.

Example: {nocache}{include file='example.tpl'}{/nocache}

@Razunter
Copy link
Author

Razunter commented Sep 3, 2024

But I need to cache it when cache is enabled or cache_id is not null.

@devthisath
Copy link

Then you should use a statement behaviour {if} {/else} like {if $cache_enabled} {include file='example.tpl'} {else} {nocache} {include file='example.tpl'} {/nocache} {/if}

@Razunter
Copy link
Author

Razunter commented Sep 3, 2024

I thought about it, but it's too verbose. The main problem is with cache_id - if set to NULL in PHP, Smarty stops caching, if set to NULL in the Smarty template, it still caches. And it shouldn't ignore the fact that caching is actually disabled.

@devthisath
Copy link

It would be better if you provide the proper code snippet that addresses your issue, so I can help you more effectively. We can also optimize the code by understanding its functionality once you provide it

@Razunter
Copy link
Author

Razunter commented Sep 3, 2024

  1. Normally, cache is enabled globally and Smarty is called with Smarty->fetch($template, $cache_id)
  2. cache_id is generated with special function:
public function generateCacheKey(string|null $prefix = null, array|null $options = null): string|null
    {
        if (!$this->design->cachingEnabled) {
            return null;
        }

        $defaultOptions = [
            'useHost' => true,
            'usePath' => true,
            'useQuery' => true,
            'cachedQueryParams' => ['page'],
            'ignoredQueryParams' => []
        ];
        
        ...
  1. Same function is used in .tpl for parts that require different caching policy: {include file='components/page--catalog/footer/brands-and-categories.tpl' cache_id=generateCacheKey('brands-and-categories', ['useHost' => false, 'useQuery' => false])}

Works fine usually, but in .tpl Smarty still creates cache files even when function returns null and when caching is disabled in Smarty... I think this is a bug.

UPD... Actually, ->fetch is used via custom function that has if ($cache_id === null) { $this->smarty->setCaching(0); }. That explains the difference in behavior, but doesn't solve the issue.

@devthisath
Copy link

Hey,

Sorry for taking so long. This could be a bug. But here is a solution for you :

  1. Edit : /smarty/smarty/src/Compile/Tag/IncludeTag.php
  2. Line 137 change from if (isset($_attr['cache_id']){ to if (isset($_attr['cache_id']) && $_attr['cache_id'] != 'null') {

@devthisath
Copy link

This is because assigning the cache_id seems to be set as a string and not as a null type

@devthisath
Copy link

Could you please let me know if it works or not?

@Razunter
Copy link
Author

Razunter commented Sep 3, 2024

Huh, turns out, it's not that simple... Tried printing $_attr['cache_id'], it is not processed at this point:
$_smarty_tpl->getSmarty()->getModifierCallback('generateCacheKey')('head-analytics--google',array('usePath'=>false,'useQuery'=>false))

@Razunter
Copy link
Author

Razunter commented Sep 3, 2024

Verbose syntax it is, I guess...

@devthisath
Copy link

Huh, turns out, it's not that simple... Tried printing $_attr['cache_id'], it is not processed at this point: $_smarty_tpl->getSmarty()->getModifierCallback('generateCacheKey')('head-analytics--google',array('usePath'=>false,'useQuery'=>false))

Mmm🤔

@devthisath
Copy link

Well, $_smarty_tpl->getSmarty()->getModifierCallback('generateCacheKey')('head-analytics--google', array('usePath' => false, 'useQuery' => false)) is not directly related to the include tag class that I asked you to modify and is only processed if the .tpl file contains any include tags.

@wisskid
Copy link
Contributor

wisskid commented Sep 4, 2024

I thought about it, but it's too verbose. The main problem is with cache_id - if set to NULL in PHP, Smarty stops caching, if set to NULL in the Smarty template, it still caches. And it shouldn't ignore the fact that caching is actually disabled.

Have you tried passing the value for cache_id from a template variable (populated from PHP) instead of literally using NULL in the template? NULL is not a reserved word in Smarty in the way it is in PHP. It is interpreted as a string 'NULL'.

@devthisath
Copy link

devthisath commented Sep 4, 2024

I thought about it, but it's too verbose. The main problem is with cache_id - if set to NULL in PHP, Smarty stops caching, if set to NULL in the Smarty template, it still caches. And it shouldn't ignore the fact that caching is actually disabled.

Have you tried passing the value for cache_id from a template variable (populated from PHP) instead of literally using NULL in the template? NULL is not a reserved word in Smarty in the way it is in PHP. It is interpreted as a string 'NULL'.

I created a structure identical to the code snippet he provided, keeping if (isset($_attr['cache_id']) && strtolower($_attr['cache_id']) != 'null') {, so cache_id works even when it's assigned the string 'NULL', and it works fine for me.

@Razunter
Copy link
Author

Razunter commented Sep 4, 2024

I created a structure identical to the code snippet he provided, keeping if (isset($_attr['cache_id']) && strtolower($_attr['cache_id']) != 'null') {, so cache_id works even when it's assigned the string 'NULL', and it works fine for me.

With function call?

@devthisath
Copy link

devthisath commented Sep 4, 2024

I created a structure identical to the code snippet he provided, keeping if (isset($_attr['cache_id']) && strtolower($_attr['cache_id']) != 'null') {, so cache_id works even when it's assigned the string 'NULL', and it works fine for me.

With function call?

No, $_smarty_tpl->getSmarty()->getModifierCallback(...) doesn't affect the cache_id value. What if you consider assigning a value in PHP and setting it as the cache_id instead of calling the function?

@Razunter
Copy link
Author

Razunter commented Sep 4, 2024

No, $_smarty_tpl->getSmarty()->getModifierCallback(...) doesn't affect the cache_id value. What if you consider assigning a value in PHP and setting it as the cache_id instead of calling the function?

But then cache_id will be $_smarty_tpl->getValue('cache_id'), not calculated value.
That's not really relevant. The more important issue is that with any cache_id present, Smarty will create a cache, even though caching is disabled by default in init.

@devthisath
Copy link

Then we should try adding another statement to check whether the cache is disabled by default in the initialization or not, and proceed accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants