Kontakty
Možná jste nainstalovali modul pro OpenCart 3 a po jeho zapnutí se stránka, na které 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 opakovaně generuje stejný výstup a jeho výpočet je zbytečně náročný.
OpenCart má vestavěnou třídu Cache. Pokud je použitý adaptér file, data se ukládají do souborů ve složce system/storage/cache/.
Průběh je obvykle takovýto:
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/[nazov_modulu].php.
Obvykle hledejte 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:
$customer_group_id = $this->customer->isLogged() ? (int)$this->customer->getGroupId() : (int)$this->config->get('config_customer_group_id'); $cache_key = 'module_[nazov_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' => $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ých URL proměnných nezávisí, do klíče je nedávejte. Zbytečně byste si rozdělili 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 !== false) { return $this->load->view('extension/module/[nazov_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/[nazov_modulu]', $data);
Tím dosáhnete toho, že první návštěvník výstup vypočítá a další už dostanou hotová data z cache souboru.
Otevřete administrátorský controller modulu, obvykle admin/controller/extension/module/[nazov_modulu].php.
Po uložení nastavení vložte smazání cache. Pokud používáte standardní OpenCart cache klíč přes $this->cache->set(), doporučený postup je mazat společný prefix, ne konkrétní hash.
$this->cache->delete('module_[nazov_modulu]');
U file cache v OpenCartu se tím smažou všechny soubory začínající tímto prefixem, například cache.module_[nazov_modulu].abc123.... To je důležité, protože jednotlivé varianty modulu bývají rozlišené hashem podle jazyka, obchodu, nastavení nebo URL kontextu.
Pokud však modul používá vlastní název souboru nebo vlastní prefix mimo standardní cache adaptér, je potřeba mazat právě tento vlastní prefix, případně konkrétní soubory přes glob() a unlink().
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 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 adaptér 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/[nazov_modulu]'); $customer_group_id = $this->customer->isLogged() ? (int)$this->customer->getGroupId() : (int)$this->config->get('config_customer_group_id'); $cache_key = 'module_[nazov_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' => $customer_group_id ))); $cache_data = $this->cache->get($cache_key); if ($cache_data !== false) { return $this->load->view('extension/module/[nazov_modulu]', $cache_data); } $data = array(); /* === ZDE ZAČÍNÁ PŮVODNÍ NÁROČNÁ LOGIKA MODULU === */ /* načítání 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/[nazov_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 navzájem přepisovat 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 potom dostanou rychle připravená data ze souboru v system/storage/cache/.