Magento: How to know many blocks are cached - caching

i cached my custom block inherit of Mage_Core_Block_Template. I cached the bloc with the next constructor:
protected function _construct()
{
$this->addData(array(
'cache_lifetime' => 120,
'cache_tags' => array(Mage_Core_Model_Store::CACHE_TAG, Mage_Cms_Model_Block::CACHE_TAG),
));
}
Right, i want verify that this block is cached. How i can list all block cached in my Magento.
I want a similar instruction:
var_dump($this->getLayout()->getUpdate()->getHandles());exit;
to see all layout , in blocks cached.
thx.

You can specify cache_key for your block:
protected function _construct()
{
$this->addData(array(
'cache_key' => 'some_static_or_dynamic_key', // can be static or dynamic
'cache_lifetime' => 120,
'cache_tags' => array(
Mage_Core_Model_Store::CACHE_TAG,
Mage_Cms_Model_Block::CACHE_TAG),
)
);
}
And then you can ensure that block is cached by calling:
Mage::app()->loadCache('your_cache_key');
Here is good article about blocks caching.

To see if Magento created your cache, you could search for the file that contains in it's name your tags in the var folder. Also make sure you have your cache activated for this to work.

Related

Cache files permissions fix for Kohana Twig module

How to configure Kohana + Twig module so the Twig will set "writable by all" permissions on all of it's cache directory and it's descendant files?
So, for example, when I run my application through the Apache module (mod_php) and cache file owner is apache (or httpd) user, I will be able to remove cache files (to clean the cache or completely remove whole application) using regular user and ssh access.
I'm able to do it with Kohana's cache, but Twig's cache is created somehow differently.
It's not very easy, but not too complicated either. I have achieved state presented below by trial-and-error method.
Create a class that inherits from Twig_Cache_Filesystem and will be used instead of it. Check this out:
<?php
namespace Application\Twig;
class Cache_Filesystem extends \Twig_Cache_Filesystem
{
public function write($key, $content)
{
$old = umask(0000);
parent::write($key, $content);
umask($old);
}
}
Note, that this class must have it's name unique, so it is a good idea to namespace it. Also, it must be accessible to other code, so consider using composer's autoloading feature.
This is the fix itself, rest of the guide is just the way of implementing it into Kohana+Twig ecosystem.
Copy Twig.php from modules/kohana-twig/classes/Twig.php into your application's directory, i.e. application/classes/Twig.php (thank you Kohana's Cascading Filesystem!)
Modify a bit newly copied file, to let Twig_CacheInterface instance be passed in the config file (application/config/twig.php) instead of just a simple string (specifying to the Twig's cache directory). Take a look of my example:
<?php defined('SYSPATH') or die('No direct script access.');
class Twig extends Kohana_Twig
{
/**
* Initialize the Twig module
*
* #throws Kohana_Exception
* #return bool
*/
public static function init()
{
$path = Kohana::$config->load('twig.environment.cache');
if (is_string($path)) {
return parent::init();
} else if ($path instanceof Twig_CacheInterface) {
return true;
}
throw new Kohana_Exception('Twig cache could not be initialized');
}
}
In configuration file for kohana-twig module, i.e. application/config/twig.php (if not yet copied from module to your application, do it now), define environment.cache key like this:
return array(
'loader' => array(
'extension' => 'twig',
'path' => 'views',
),
'environment' => array(
'auto_reload' => (Kohana::$environment >= Kohana::TESTING),
'autoescape' => true,
'base_template_class' => 'Twig_Template',
// Following line is related to this issue and fix:
'cache' => new \Application\Twig\Cache_Filesystem(APPPATH . 'cache/twig'),
'charset' => 'utf-8',
'optimizations' => - 1,
'strict_variables' => false,
),
'functions' => array(),
'filters' => array(),
'tests' => array(),
}
This works for me. Hopefully it will help someone struggling with similar problem.

ZF2 - Saving a result of a function in cache

I made a view helper that checks if an external URL exists before outputting it. Some of those URLs are in my main layout, so that check is quite slowing down my site by calling all those urls all the times, to check if they exist. I would like to save the output of that function so that it only checks an URL if the same one hasn't been checked already in less than an hour, or a day. I believe I should use Zend Cache to do that? But I have no idea where to start, do you have any suggestions, easy solutions or some basic tutorial to learn? Thanks!
Add global config for cache service, like here:
config/autoload/global.php
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
)
),
config/autoload/cache.global.php
return array(
'caches' => array(
// Cache config
)
)
Use factory to create your View Helper:
Application/Module.php::getViewHelperConfig()
'LinkHelper' => function ($sm) {
$locator = $sm->getServiceLocator();
return new LinkHelper($locator->get('memcached'))
}
Use cache service in your View Helper:
LinkHelper.php
protected $cache;
public function __construct($cache)
{
$this->cache = $cache;
}
public function __invoke($url)
{
$cacheKey = md5($url);
if ($this->cache->hasItem($cacheKey) {
return $this->cache->getItem($cacheKey);
}
$link = ''; // Parse link
$this->cache->setItem($cacheKey, $link);
return $link;
}

Magento Form with Tabs Fieldset Issue

I'm writing a custom Magento module for my store and I'm facing a weird issue with a fieldset in one form. The form is assigned to a tab, however the fieldset starts from the top of container, not from just below buttons area. Please see the image attached
I want it to display like:
This module is being developed on Magento 1.9.0.1 without any modification whatsoever, just the demo data.
Below is the code for all the classes:
Controller:
added form container and tabs to left column
class Koala_Socialmanager_Adminhtml_TwitterController extends Mage_Adminhtml_Controller_Action {
public function directTweetAction(){
$this->loadLayout();
$this->_addContent($this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_tweet','directTweet'))
->_addLeft($this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs'));
$this->renderLayout();
Form container:
class Koala_Socialmanager_Block_Twitter_DirectTweet_Tweet extends Mage_Adminhtml_Block_Widget_Form_Container {
public function __construct()
{
$this->_blockGroup = 'koala_socialmanager';
$this->_controller = 'twitter_directTweet';
$this->_headerText = Mage::helper('koala_socialmanager')->__('Direct Tweets');
parent::__construct();
$this->_updateButton('save', 'label', Mage::helper('adminhtml')->__('Tweet Now!'));
}
}
Tabs:
class Koala_Socialmanager_Block_Twitter_DirectTweet_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs{
public function __construct(){
parent::__construct();
$this->setId('tweetTabs');
$this->setDestinationElementId('edit_form');
$this->setTitle(Mage::helper('koala_socialmanager')->__('Twitter'));
}
public function _beforeToHtml(){
$this->addTab('form_section_form',array(
'label' => Mage::helper('koala_socialmanager')->__("Tweet"),
'title' => Mage::helper('koala_socialmanager')->__("Tweet"),
'content' => $this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs_form')->initForm()->toHtml(),
'active' => true
));
$this->addTab('form_section_external_media',array(
'label' => Mage::helper('koala_socialmanager')->__("External Media"),
'title' => Mage::helper('koala_socialmanager')->__("External Media"),
'content' => $this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs_externalMedia')->initForm()->toHtml()
));
$this->addTab('form_section_magento_media',array(
'label' => Mage::helper('koala_socialmanager')->__("Magento Product Media"),
'title' => Mage::helper('koala_socialmanager')->__("Magento Product Media"),
'content' => $this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs_magentoProductMedia')->toHtml()
));
return parent::_beforeToHtml();
}
}
And form with fieldset:
class Koala_Socialmanager_Block_Twitter_DirectTweet_Edit_Tabs_Form extends Mage_Adminhtml_Block_Widget_Form {
public function __construct()
{
parent::__construct();
}
public function initForm(){
$form = new Varien_Data_Form();
$this->setForm($form);
$form->setHtmlIdPrefix('socialmanager');
$helper = Mage::helper('koala_socialmanager');
$fieldset = $form->addFieldset('base_fieldset', array(
'legend' => Mage::helper('koala_socialmanager')->__('Tweeter Message')
));
$fieldset->addField('statusUpdate', 'textarea', array(
'name'=>'tweet',
'label'=>$helper->__("Tweet this Message:"),
'after_element_html'=>'<div class="characterCounter">0</div>'
));
Mage::helper('koala_socialmanager')->getTwitterFormScript();
return $this;
I believe I'm missing something silly. Any help appreciated.
Cheers
Paul
I've solved the problem, still don't know the cause though. I simply rewritten everything to another folder changing the class names, created another action in controller called testAction, so all files from DirectTweet folder are located in Message folder, and guess what? when you display that form from testActoin it works as it should, when I display the old form from DirectTweet folder - fieldset is broken.
I have magento cache disabled all the time, I cleared all tmp, cache, session folders, cleared browser cache and had no luck with fixing it, so I'm wondering why the new "version" works even though there is no changes to the code apart from cosmetic ones (removing empty lines, or changed text for labels/headers).
For the last 20 minutes I was comparing file by file in phpstorm, and seriously no differences apart from class names and texts to output.... I'm to tired to think about it anymore.
Below desired output :)
Happy New Year
Paul

How to approach caching in ZF2

I am just starting to get my head into caching as a whole. I have a simple indexAction() that fetches all given Datasets. My approach is:
check for existing key 'controllername-index-index'
if existing: return the value of the key
if not existing, do the normal action and add the key
The value inside the key should be the ViewModel that will be generated and populated with my data.
Here's what i have done so far:
<?php
public function indexAction()
{
$sl = $this->getServiceLocator();
// $cache = $sl->get('cache');
// $key = 'kennzahlen-index-index';
//
// if ($cache->hasItem($key)) {
// return $cache->getItem($key);
// }
$viewModel = new ViewModel();
$viewModel->setTemplate('kennzahlen/index/index');
$entityService = $sl->get('kennzahlen_referenzwert_service');
$viewModel->setVariable('entities', $entityService->findAll());
// $cache->setItem($key, $viewModel);
return $viewModel;
}
The Caching parts are commented out for testing purposes, but basically this is all that i am doing. The Caching config/service looks like the following:
<?php
'cache' => function () {
return \Zend\Cache\StorageFactory::factory(array(
'adapter' => array(
'name' => 'filesystem',
'options' => array(
'cache_dir' => __DIR__ . '/../../data/cache',
'ttl' => 100
),
),
'plugins' => array(
array(
'name' => 'serializer',
'options' => array(
)
)
)
));
},
The serialization and caching works quite well, but i am surprised by the missing results. Going by what the ZendDevelopersToolbar tells me, the times WITHOUT caching range between 1.8s to 2.5s. Having the caching parts uncommented (enabled) doesn't really improve the loading time of my page at all.
So my question is: Is this approach completely wrong? Are there different, more speedy parts, that can be saved with some neat configuration tricks?
I Feel that a 2 second load time of a page is DEFINITELY too slow. 1s to me is the maximum given a huge amount of data, but certainly not anything more than that :S
All help/hints/suggestions will be greatly appreciated. Thanks in advance!
One option would be to cache the complete output of your page, for example based on the route match. You need to listen between routing and dispatching which route has been found as match and then act accordingly:
namespace MyModule;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $e)
{
// A list of routes to be cached
$routes = array('foo/bar', 'foo/baz');
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($sm) {
$route = $e->getRouteMatch()->getMatchedRouteName();
$cache = $sm->get('cache-service');
$key = 'route-cache-' . $route;
if ($cache->hasItem($key)) {
// Handle response
$content = $cache->getItem($key);
$response = $e->getResponse();
$response->setContent($content);
return $response;
}
}, -1000); // Low, then routing has happened
$em->attach(MvcEvent::EVENT_RENDER, function($e) use ($sm, $routes) {
$route = $e->getRouteMatch()->getMatchedRouteName();
if (!in_array($route, $routes)) {
return;
}
$response = $e->getResponse();
$content = $response->getContent();
$cache = $sm->get('cache-service');
$key = 'route-cache-' . $route;
$cache->setItem($key, $content);
}, -1000); // Late, then rendering has happened
}
}
The second listener checks at the render event. If that happens, the result of the response will be cached.
This system (perhaps not with 100% copy/paste, but the concept) works because if you return a Response during the route or dispatch event, the application will short circuit the application flow and stop further triggering listeners. It will then serve this response as it is.
Bear in mind it will be the complete page (including layout). If you don't want that (only the controller), move the logic to the controller. The first event (now route) will be dispatch of the controller. Listen to that early, so the normal execution of the action will be omitted. To cache the result, check the render event for the view layer to listen to.
/update: I wrote a small module to use this DRY in your app: SlmCache

change checkout page headings in Magento

How can I change the checkout page headings in Magento?
Of course, the simplest way is to change this headings in translation file (Mage_Checkout.csv). But if you want to use some custom labels, and you don't want to conflict with native translations for other blocks on checkout, you should update those labels:
these classes are located in app/code/core/Mage/Checkout/Block/Onepage.
Billing.php
Shipping.php
Payment.php
Review.php
You can change label in _construct() method.
For example:
class Mage_Checkout_Block_Onepage_Review extends Mage_Checkout_Block_Onepage_Abstract
{
protected function _construct()
{
$this->getCheckout()->setStepData('review', array(
'label' => Mage::helper('checkout')->__('Order Review'), // your custom label here
'is_show' => $this->isShow()
));
parent::_construct();
$this->getQuote()->collectTotals()->save();
}
}
You can override those classes.

Resources