How to test if latte cache is valid?
- Čamo
- Member | 798
Hello,
Today I wrote some caching for my menu component which looks like:
{cache 'menu_key', tags => [ 'menu_tag' ] }
{block menu}
<ul>
{foreach $section as $item}
<li>
{if $item->url_params}
<a href="{plink $item->url (expand)explode(' ', $item->url_params)}">{$item->title}</a>
{else}
<a href="{plink $item->url}">{$item->title}</a>
{/if}
{ifset $menuArr[$item->id] }
{include menu, section => $menuArr[$item->id]} {* RECURSION *}
{/ifset}
</li>
{/foreach}
</ul>
{/block}
{/cache}
Everything works fine. But I would like to skip some code in component render method which loads data from database. I tried this:
if( ! $this->cache->load( 'menu_key' ) )
{
$arr = $this->categories->getArray();
}
but it does not work of course.
Question is how to check if template cache is not null? Probably the problem is in cache namespaces but how to solve it?
Thanks.
Last edited by Čamo (2016-02-06 22:52)
- petr.jirous
- Member | 128
Čamo wrote:
Why not? Aren't generating links and db queries expensive?
Of course, they are. But what DB layer do you use? If you have your db queries lazy and your view is cached, it does not execute the query even not generate links.
- petr.jirous
- Member | 128
I don't think so. It's conceptually wrong idea. Why don't you cache the query result then?
- Čamo
- Member | 798
But which part?
This is what throws me an exception.
$this->cache->save( 'categories', $arr = $this->categories->getArray() );
This is method which generates $arr
/**
* @return array
* @desc returns array of arrays
* like $a[0][5] $a[0][6] where [0] is parent_id which is array of his children
*/
public function getArray($admin = false)
{
$selection = $this->findAll($admin);
$arr = array();
while($row = $selection->fetch())
{
$arr[$row['parent_id']][$row['id']] = $row;
}
return $arr;
}
- Čamo
- Member | 798
Now I have this
if( $arr = $this->cache->load( 'categories_key' ) )
{
$this->cache->save( 'categories_key', $this->categories->getArray(), [ Cache::TAGS => [ 'categories_tag' ] ] );
$arr = $this->cache->load( 'categories_key' );
}
but latte throws me “Invalid argument passed to foreach; array or Traversable expected, NULL given.”
Last edited by Čamo (2016-02-07 01:41)
- petr.jirous
- Member | 128
Čamo wrote:
Now I have this
if( $arr = $this->cache->load( 'categories_key' ) ) { $this->cache->save( 'categories_key', $this->categories->getArray(), [ Cache::TAGS => [ 'categories_tag' ] ] ); $arr = $this->cache->load( 'categories_array' ); }
but latte throws me “Invalid argument passed to foreach; array or Traversable expected, NULL given.”
You should cache the result if it was not successful to load it.
So if (!($arr = $this->cache->load('categories_key')))
- petr.jirous
- Member | 128
Because you're trying to cache ActiveRow objects. When you do
$selection->fetch() it returns IRow (most probably ActiveRow, which couldn't
be serialized). Think about using Selection::fetchAssoc()
or ActiveRow::toArray()
- petr.jirous
- Member | 128
Oh, I really don't understand this. You cache indicator if the query result was in the cache? It's fundamental misunderstanding how cache works.