Post by djdaca » Wed Jun 02, 2010 4:52 am

Zdravím,

Možná že mi poradíte, v opencart jsem uplný nováček a migruju jeden náš eshop právě na tento systém.
Problém nastal když jsem měl migrovat kategorie (je jich asi 800 s mnoha potomky) opencart evidentně nepočítá s tolika položkami a tak se načítá skutečně nechutně pomalu (cca 60 sec).

Problém je ve funkci getCategories která se nachází v ./catalog/controller/common/header.php:

Code: Select all

private function getCategories($parent_id, $level = 0) {
        $level++;
        $data = array();
        
        $results = $this->model_catalog_category->getCategories($parent_id);
        
        foreach ($results as $result) {
            $data[] = array(
                'category_id' => $result['category_id'],
                'name'        => str_repeat('    ', $level) . $result['name']
            );
            
            $children = $this->getCategories($result['category_id'], $level);
            
            if ($children) {
              $data = array_merge($data, $children);
            }
        }
        return $data;
    }
 


Funkce udělá loop a ptá se mnohokrát za sebou jaký má potomky což vyvolá u mnoha kategorií šílené zdržení.
Řešení jsem našel jediné v té samé třídě na řádce 115 kde je volání této funkce kterou jsem zakomentoval.

Code: Select all

//$this->data['categories'] = $this->getCategories(0);
 
Tím je problém dočasně vyřešen nicméně z profesionálního hlediska (strašně rád zapomínám) budu mít při updatu problém.

Je nějaký dobrodivec který by mi pomohl říci jak problém vyřešit ? Všiml jsem si například že opencart má cache kde ovšem ukládá kategorie jen administrace, nelze tuto funkci uplně vyřadit pluginem popřípadě ji pluginem vylepšit ?

Děkuji za odpovědi.

Ten kdo mě zná - ten ví, kdo mě nezná ten mě pozná a bude dělat že mě nezná jako ti co mě znají.


User avatar
Newbie

Posts

Joined
Mon May 31, 2010 7:03 pm
Location - Prague/Czech Republic

Post by djdaca » Wed Jun 02, 2010 7:54 am

Tak pro všechny kdo mají podobný problém (verze 1.4.7) a nechtějí se kategorií u vyhledávacího boxu vzdát za cenu neautorizované změny (problem i řešení jsem nahlásil):

Upravte soubor: "catalog/model/catalog/category.php" a optimálně pod funkci getCategories přidejte funkci:

Code: Select all

    public function getAllCategories() {
        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "category c LEFT JOIN " . DB_PREFIX . "category_description cd ON (c.category_id = cd.category_id) LEFT JOIN " . DB_PREFIX . "category_to_store c2s ON (c.category_id = c2s.category_id) WHERE cd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND c2s.store_id = '" . (int)$this->config->get('config_store_id') . "'  AND c.status = '1' ORDER BY c.sort_order, LCASE(cd.name)");
        
        return $query->rows;
    }
 
Upravte soubor: "catalog/controller/common/header.php" a "catalog/controller/product/search.php" (a možná i další, problém nastal například u google sitemap)

přidejte na vrch třídy proměnou:

Code: Select all

private $category;
 
Pod funkcí index přidejte:

Code: Select all

    private function getCategoriesChilds($array, $parent_id = 0) {
        if(is_array($array)){
            $data = array();
            foreach($array as $arr){
                if($parent_id == $arr['parent_id']) {
                    $data[$arr['category_id']] = $arr;
                    $data[$arr['category_id']]['child'] = $this->getCategoriesChilds($array,$arr['category_id']);
                }
            }
        }
        return $data;
    }
 
Funkci getCategories přepište takto:

Code: Select all

    private function getCategories($results = "", $level = 0) {
        $data = array();
        if(!$this->categories) {
            $category = $this->model_catalog_category->getAllCategories();
            $this->categories = $this->getCategoriesChilds($category);
        }
        if($level == 0) {
            $results = $this->categories;
        }
        $level++;
        foreach ($results as $result) {
            $data[] = array(
                'category_id' => $result['category_id'],
                'name'        => str_repeat('    ', ($level-1)) . $result['name']
            );
            if(is_array($result['child'])) {
                $children = $this->getCategories($result['child'], $level);
                if ($children) {
                    $data = array_merge($data, $children);
                }
            }
        }
        
        return $data;
    }
 
A co jste právě udělali:

Funkce getAllCategories vám načte všechny kategorie které máte uložené a vloží do pole které vám pošle do controlleru

Funkce getAllChilds vám vygeneruje asociativní stromove pole s potomky.

Funkce getCategories vám jediným dotazem vygeneruje kategorie použitelné do selectboxu a tudíž se nemusíte ptát na potomky.

Zvažuji zda by nebylo vhodné v indexu pole s kategoriema vyprázdnit neboť nejsou pro další použití potřebné taktéž se vybízí otázka jestli by nebyla pro více kategorií vhodná i cache kterou lze relativne jednoduše v construktoru uložit popřípadě zcela jiné načítání například ajaxem (pro lidi kteří mají 1000 a více kategorií)

Pište připomínky.

Ten kdo mě zná - ten ví, kdo mě nezná ten mě pozná a bude dělat že mě nezná jako ti co mě znají.


User avatar
Newbie

Posts

Joined
Mon May 31, 2010 7:03 pm
Location - Prague/Czech Republic

Post by djdaca » Thu Jun 03, 2010 6:17 am

Nahrávám pathe pro opencart 1.4.7 pro jeho rychlejší zpracování, kromě kromě selectboxů u vyhledávání přibyla taky oprava pro rozšířené vyhledávání a také pro sitemapu (tam jsem přidal taky cache)

Přibude možná také controller pro google sitemap.

Attachments


Ten kdo mě zná - ten ví, kdo mě nezná ten mě pozná a bude dělat že mě nezná jako ti co mě znají.


User avatar
Newbie

Posts

Joined
Mon May 31, 2010 7:03 pm
Location - Prague/Czech Republic

Post by hawkey » Thu Jun 03, 2010 3:27 pm

Jsem rád, že se tady objevil někdo, kdo i programuje, českých vývojářů opencartu je poskrovnu, díky za informace. Zrovna řeším volitelné atributy pro produkty, tak kdybyste měl něco i v této oblasti, dejte vědět.

Visit OpencartEx - Opencart extensions
Opencart rady a návody česky | Podpora Opencart


Active Member

Posts

Joined
Sun Apr 25, 2010 12:10 am
Location - Olomouc, Czech Republic, Europe

Post by mykky » Wed Nov 03, 2010 6:03 pm

Zdarec,
chci se zeptat zda někdo vytvořil už nějaké novější načítání kategorií než je už zde uvedeno. Mám taky rozsáhlý eshop a celkem zatěžuje server. Nebo to nějak vyřešit, už jak se zde píše tím AJAXem? A nedoporučili by ste nějaký dobrý hosting na opencart?
Díky

Newbie

Posts

Joined
Wed Nov 03, 2010 5:51 pm
Who is online

Users browsing this forum: No registered users and 3 guests