Kontakty
Možná jste instalovali modul pro OpenCart 3 a po jeho zapnutí se stránka, kde se modul vykresluje, výrazně zpomalila. Častou příčinou bývá to, že modul při každém načtení znovu skládá stejná data z databáze. Řešením bývá doplnění datové cache do system/storage/cache/.
Tento návod popisuje obecný a bezpečný postup pro moduly třetích stran v OpenCart 3. Je zaměřený na situaci, kdy modul na frontendu generuje stejný výstup opakovaně a jeho výpočet je zbytečně drahý.
OpenCart má vestavěnou třídu Cache. Pokud je použit adaptér file, ukládají se data do souborů ve složce system/storage/cache/.
Průběh je obvykle tento:
Typicky tehdy, když modul na frontendu opakovaně:
Naopak opatrnost je potřeba u modulů, jejichž výstup závisí na konkrétním zákazníkovi, košíku, přihlášení, měně, aktivní kategorii, jazyku nebo jiném kontextu. V takovém případě musí být tyto hodnoty součástí cache klíče, nebo se daná část nesmí cachovat vůbec.
Otevřete controller modulu, nejčastěji v cestě catalog/controller/extension/module/[nazev_modulu].php.
Obvykle hledáte metodu index($setting) nebo podobnou hlavní metodu. Cílem je obalit cache pouze tu část, která připravuje datové pole pro šablonu. Běžné načtení jazyka, připojení JS/CSS nebo jiné lehké operace mohou zůstat mimo cache.
Klíč musí rozlišit všechny stavy, ve kterých může mít modul jiný výstup. Nestačí jen název modulu. Často je potřeba zahrnout například:
Bezpečný obecný vzor:
$cache_key = 'module_[nazev_modulu].' . md5(json_encode(array( 'setting' => $setting, 'store_id' => (int)$this->config->get('config_store_id'), 'language_id' => (int)$this->config->get('config_language_id'), 'customer_group_id' => (int)$this->config->get('config_customer_group_id'), 'theme' => $this->config->get('theme_' . $this->config->get('config_theme') . '_directory'), 'path' => isset($this->request->get['path']) ? (string)$this->request->get['path'] : '' )));
Pokud výstup na path nebo jiné URL proměnné nezávisí, do klíče je nedávejte. Zbytečně byste si rozdrobili cache do mnoha souborů.
Na začátek náročné části vložte kontrolu cache. Pokud data existují, rovnou je použijte.
$cache_data = $this->cache->get($cache_key); if ($cache_data) { return $this->load->view('extension/module/[nazev_modulu]', $cache_data); }
Tady je důležité, že ukládáte přímo finální datové pole pro šablonu, typicky proměnnou $data. OpenCart file cache už sama řeší životnost souboru, takže není potřeba do cache ukládat další pole typu expire nebo ttl.
Původní náročný kód zůstane prakticky beze změny. Jen po jeho dokončení uložíte finální data do cache.
// Pokud cache neexistuje, proběhne původní logika modulu: // - načtení kategorií // - načtení produktů // - skládání stromu // - příprava pole $data pro twig $this->cache->set($cache_key, $data); return $this->load->view('extension/module/[nazev_modulu]', $data);
Tím dosáhnete toho, že první návštěvník výstup spočítá a další už dostanou hotová data z cache souboru.
Otevřete administrátorský controller modulu, obvykle admin/controller/extension/module/[nazev_modulu].php.
Po uložení nastavení vložte smazání cache. Doporučený postup je mazat společný prefix, ne konkrétní hash.
$this->cache->delete('module_[nazev_modulu]');
U file cache v OpenCartu se tím smažou všechny soubory začínající na tomto prefixu, například cache.module_[nazev_modulu].abc123.... To je důležité, protože jednotlivé varianty modulu bývají rozlišeny hashí podle jazyka, obchodu, nastavení nebo URL kontextu.
Samotné uložení nastavení modulu často nestačí. Pokud modul zobrazuje produkty, kategorie, výrobce, recenze nebo jiná data z administrace, je vhodné mazat cache i při změně těchto dat.
Příklady:
Jinak se může stát, že modul zůstane funkční a rychlý, ale bude po určitou dobu zobrazovat zastaralá data až do expirace cache.
Ve standardním OpenCart 3 je u file cache běžná životnost často 3600 sekund, tedy 1 hodina. Tato hodnota se předává při vytvoření instance cache a file adaptor ji zapisuje do názvu souboru.
Praktický důsledek:
Při ladění nebo testování můžete cache odstranit i ručně ve složce system/storage/cache/.
Poznámka: v některých instalacích OpenCartu tlačítka pro vyčištění vývojářských cache řeší hlavně Twig, SASS nebo modification cache. Datovou file cache modulu je jistější mazat přímo přes $this->cache->delete(...) nebo ručně ve složce system/storage/cache/.
public function index($setting) { $this->load->language('extension/module/[nazev_modulu]'); $cache_key = 'module_[nazev_modulu].' . md5(json_encode(array( 'setting' => $setting, 'store_id' => (int)$this->config->get('config_store_id'), 'language_id' => (int)$this->config->get('config_language_id'), 'customer_group_id' => (int)$this->config->get('config_customer_group_id') ))); $cache_data = $this->cache->get($cache_key); if ($cache_data) { return $this->load->view('extension/module/[nazev_modulu]', $cache_data); } $data = array(); /* === ZDE ZAČÍNÁ PŮVODNÍ NÁROČNÁ LOGIKA MODULU === */ /* načtení modelů, SQL dotazy, cykly, skládání výstupních dat */ /* === ZDE KONČÍ PŮVODNÍ NÁROČNÁ LOGIKA MODULU === */ $this->cache->set($cache_key, $data); return $this->load->view('extension/module/[nazev_modulu]', $data); }
Pokud se stejný modul používá na více layoutech nebo ve více instancích, je velmi důležité, aby byl součástí klíče i obsah $setting nebo alespoň module_id. Jinak si jednotlivé instance mohou přepisovat navzájem cache.
Po správném doplnění file cache se databázově náročný výpočet provede jen při prvním načtení nebo po invalidaci. Ostatní návštěvníci pak dostanou rychle připravená data ze souboru v system/storage/cache/.