Opencart CSV export - filtriranje kategorija

Koristim CSV generator malo prilagođen.

https://www.opencart.com/index.php?route=extension/extension/info&extension_id=20036&token=1edc8581be9d12ce7cd2102eca49c3fa

Problem se javio jer moram filtrirati kategoriju (možda par njih) iz krajnjeg .csv rezultata.

Plugin radi sve ali uzima sve kategorije.

E sad, probao sam izmjeniti $result iz
$results = $this->model_catalog_product->getProducts();
u

$results = $this->model_catalog_product->getProducts(array('filter_category_id' => '30'));

Ali no-go i dalje prikazuje sve rezultate.

Kompletni kod je ovdje:
<?php
class ControllerModuleCsvcreator extends Controller{
public $error = array();
public function index(){

        $this->language->load('module/csvcreator');
        $this->document->setTitle($this->language->get('heading_title'));
        $this->load->model('setting/setting'); // Load the Setting Model  (All of the OpenCart Module & General Settings are saved using this Model )
        $this->data['heading_title'] = $this->language->get('heading_title');
         /* Making of Breadcrumbs to be displayed on site*/
    
    $this->data['breadcrumbs'] = array();
 
    $this->data['breadcrumbs'][] = array(
        'text'      => $this->language->get('text_home'),
        'href'      => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'),
        'separator' => false
    );
 
    $this->data['breadcrumbs'][] = array(
        'text'      => $this->language->get('text_module'),
        'href'      => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'),
        'separator' => '  ::  '
    );
 
    $this->data['breadcrumbs'][] = array(
        'text'      => $this->language->get('heading_title'),
        'href'      => $this->url->link('module/helloworld', 'token=' . $this->session->data['token'], 'SSL'),
        'separator' => '  ::   '
    );
    
      /*This Block returns the warning if any*/
    if (isset($this->error['warning'])) {
        $this->data['error_warning'] = $this->error['warning'];
    } else {
        $this->data['error_warning'] = '';
    }
    /*End Block*/
    $this->load->model('tool/image');
    
    
    $this->load->model('design/layout'); // Loading the Design Layout Models
 
    $this->data['layouts'] = $this->model_design_layout->getLayouts(); // Getting all the Layouts available on system
 
    $this->template = 'module/csvcreator.tpl'; // Loading the <span class="skimlinks-unlinked">helloworld.tpl</span> template
    $this->children = array(
        'common/header',
        'common/footer'
    );  // Adding children to our default template i.e., <span class="skimlinks-unlinked">helloworld.tpl</span> 
     
    $this->response->setOutput($this->render()); // Rendering the Output
    }
    
    function file_csv()
    {
        $this->load->model('tool/image');
        $this->load->model('catalog/product');
        $this->load->model('catalog/category');
        $results = $this->model_catalog_product->getProducts();
        
               $this->load->helper('csv_helper');
         $fields = (
           $this->data['products'][] = array ("post_title","post_name","ID","post_excerpt","post_content","post_status","menu_order","post_date","post_parent","post_author","comment_status","sku","downloadable","virtual","visibility","stock","stock_status","backorders","manage_stock","regular_price","sale_price","weight","length","width","height","tax_status","tax_class","upsell_ids","crosssell_ids","featured","sale_price_dates_from","sale_price_dates_to","download_limit","download_expiry","product_url","button_text","meta:_yoast_wpseo_focuskw","meta:_yoast_wpseo_title","meta:_yoast_wpseo_metadesc","meta:_yoast_wpseo_metakeywords","images","downloadable_files","tax:product_type","tax:product_cat","tax:product_tag","tax:product_shipping_class","tax:vtwpr_rule_category","meta:total_sales")
                   );
                   
        foreach ($results as $result)
       {
           if($result['image']){
               $image = $this->model_tool_image->resize($result['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height'));
           }
           
          $category = $this->model_catalog_product->getProductCategories($result['product_id']);
        
        if ($category){
              $category_array = $this->model_catalog_category->getCategory($category[0]);
        
            $catname = htmlspecialchars_decode($category_array['name']);
        }
        if(isset($category[1])){ $category_array_sub =  $this->model_catalog_category->getCategory($category[1]);
         $cat_name = $catname .'>'.  htmlspecialchars_decode($category_array_sub['name']); }
           
          $this->data['products'][] = array(
                      'post_title'        => $result['name'],
                    'post_name'         => $result['name'],
                    'ID'                => $result['product_id'],
                    'post_excerpt'      => strip_tags(htmlspecialchars_decode($result['meta_description'])),
                    'post_content'      => strip_tags(htmlspecialchars_decode($result['description'])),
                    'post_status'       => 'publish',
                    'menu_order'        => 0,
                    'post_date'         => $result['date_added'],
                    'post_parent'       => 0,
                    'post_author'       => 'admin',
                    'comment_status'     => 'open',
                    'sku'                 =>  $result['sku'],
                    'downloadable'      => 'no',
                    'virtual'             => 'no',
                    'visibility'         => 'visible',
                    'stock'             => '',
                    'stock_status'         => 'instock',
                    'backorders'          => 'no',
                    'manage_stock'      => 'no',
                    'regular_price'     => $result['price'],
                    'sale_price'         => $result['price'],
                    'weight'             => $result['weight'],
                    'length'             => $result['length'],
                    'width'             => $result['width'],
                    'height'            => $result['height'],
                    'tax_status'         => '',
                    'tax_class'         => '',
                    'upsell_ids'        => '',
                    'crosssell_ids'        => '',
                    '_featured'           => 'no',
                    'sale_price_dates_from'         => '',
                    'sale_price_dates_to_tmp'         => '',
                    'download_limit'     => '',
                    'download_expiry'    => '',
                    'product_url'         => '',
                    'button_text'        => '',
                    'meta:_yoast_wpseo_focuskw'     => '',
                    'meta:_yoast_wpseo_title'        => '',
                    'meta:_yoast_wpseo_metadesc'     => '',
                    'meta:_yoast_wpseo_metakeywords'=> '',
                    'images'            => $image,
                    'downloadable_files'=> '',
                    'tax:product_type'    => '',
                    'tax:product_cat'     => $cat_name,
                    'tax:product_tag'    => '',
                    'tax:product_shipping_class'    => '',
                    'tax:vtwpr_rule_category'          => '',
                    'meta:total_sales'  => 0,
                );
                  
       }
       
       $csv = new Csv_helper;
       $csv->array_to_csv($this->data['products'],'products.csv');
    }
    
    
}

Ovo:
$results = $this->model_catalog_product->getProducts(array('filter_category_id' => '30'));

I iz niza dobijenog nazad vidimo da nema takvog polja. Nego i da ga ima, u default-nom metodu modela ne postoji check za takvo polje filter_category_id.
Osim ako plugin nije mijenjao sta u default open cart kodu (moguce da nije), nema takvog polja u fajlu. Linija 342. Mozda bi trebalo dodati if check za konkretno polje.

Da , još sam krivu funckiju gledao. Mijenjam stalno isti rezultat na kraju vidim da krivu funkciju mijenjam.

Ovak sve ide od product.php gdje ovaj modul vuče getProducts funckiju.
Tamo nije ništa mijenjano od osnovnog originalnog fajla.

Sada sam dodao funckiju getProductsCsv kopiju, da po njoj mijenjam stvari. Odmah ispod getProducts u product.php
Ali predaja recimo:
filter_category_id’ => '30’
ne funckionira.
Kao da taj getProducts uopće ne registrira izmjene, ili kategorije.
Ne znam sada više što trebam samo da ili navedem sve kategorije ili isključim samo tu jednu faking kategoriju.
Znači bolje tipa “exclude”.
Sad ne znam gdje da filtriram $result, i da li uopće to mogu tamo napraviti.
Dakle trebao bi isfiltrirati sve rezultate koji imaju određenu kategoriju van.

Ma stvar je banalna vjerovatno kao obično, ali već sam ispao iz kodiranja, i da me ubiješ ne vidim gdje i što.
Ako netko ima, odužiti ću mu se.

Ne bi li trebalo koristiti metod getProductsByCategoryId($category_id) (ln. 405)? Ako bi bilo u pitanju vise kategorija trebalo bi izmijeniti metod da prihvata niz u parametru.

1 Like

Da to mi vraća rezultate, ali samo po jednu kategoriju.
Potrebne su mi sve osim jedne, ili dvije.

Probaj da zamijenis ovo umjesto nativnog metoda:

public function getProductsByCategoryId($category_id) {
	
	if ((int)$category_id > 0)
	{
		$query = $this->db->query(
			"SELECT * FROM " . DB_PREFIX . "product p 
			LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) 
			LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) 
			WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' 
			AND p2c.category_id = '" . (int)$category_id . "' 
			ORDER BY pd.name ASC");
		return $query->rows;
	}
	elseif (is_array($category_id))
	{
		$query = $this->db->query(
			"SELECT * FROM " . DB_PREFIX . "product p 
			LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) 
			LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) 
			WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' 
			AND p2c.category_id IN '" . implode(',', $category_id) . "' 
			ORDER BY pd.name ASC");
		return $query->rows;
	}
	return FALSE;
}

Disclaimer: nije testirano.

Ovo gore bi trebalo znači skužiti ako je jedna kategorija ili niz njih koji onda idu u polje.
Dodao sam tu fukciju sa nazivom
public function getProductsByCategoryId2($category_id) {

Na mejstu gdje je funkcija:

$cat_id = array(30,33,34,35);

    $results = $this->model_catalog_product->getProductsByCategoryId2($cat_id);

Vraća prazni rezultat. Tj. nema rezultata.
Čak ni sa jednom kategorijom.

Nisam ga dobro bio prepravio, plus sam zaboravio zagrade za IN () funkciju.

AND p2c.category_id IN (" . implode(',', $category_id) . ") 

Btw. Ne moras koristiti drugi metod jer ce prvi ionako odradjivati standardni posao preko prvog bloka u kontrolnoj strukturi.

Komplet:

public function getProductsByCategoryId($category_id) 
{
    if ((int)$category_id > 0)
    {
        $query = $this->db->query(
        "SELECT * FROM " . DB_PREFIX . "product p 
	LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) 
        LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) 
        WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' 
        AND p2c.category_id = '" . (int)$category_id . "' 
        ORDER BY pd.name ASC");
	
        return $query->rows;
    }
    elseif (is_array($category_id))
    {
	$query = $this->db->query(
	"SELECT * FROM " . DB_PREFIX . "product p 
	LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) 
	LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) 
	WHERE pd.language_id = '" . (int)$this->config->get('config_language_id') . "' 
	AND p2c.category_id IN (" . implode(',', $category_id) . ") 
	ORDER BY pd.name ASC");
	
        return $query->rows;
    }
    return FALSE;
}

Ok napravio sam slijedeće:
Nova funkcija u product.php

public function getProductsByCategoryIdNew($category_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . “product_to_category p2c ON (p.product_id = p2c.product_id) WHERE pd.language_id = '” . (int)$this->config->get(‘config_language_id’) . “’ AND p2c.category_id = '” . implode(’,’, $category_id) . “’ ORDER BY pd.name ASC”);
return $query->rows;
}

U php fajlu za csvcreator.php

$results = $this->model_catalog_product->getProductsByCategoryIdNew(array(25,20,33));

Dohvaća samo prvi iz niza. Dakle kategoriju 25.

Šteta da to radi, pronašao bi popis svih kategorija >> filtrirao iz rezultata kategorije po broju ID kategorije koje trebam izostaviti i predati polje da vuče ostale.

Ali eto dohvaća samo prvi iz polja. Dakle 25.
Da li je do sintakse upita na bazu? Da li uopće može pokupiti više rezultata iz više navedenih kategorija, tj. da li polje tu može uopće biti?

Uporedi

var_dump($this->model_catalog_product->getProducts());exit;

i

var_dump(getProductsByCategoryIdNew($category_id));exit;

strukturu rezultata.

Stavio sam u SQL upit IN, da pregledava polje koje mu predajem, ne samo prvu vrijednost.
public function getProductsByCategoryIdNew($category_id) {
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . “product_to_category p2c ON (p.product_id = p2c.product_id) WHERE pd.language_id = '” . (int)$this->config->get(‘config_language_id’) . “’ AND p2c.category_id IN (". implode(’,’, $category_id) .") ORDER BY pd.name ASC”);

    return $query->rows;

}

Izmjenjeni dio je p2c.category_id IN (". implode(’,’, $category_id) .") ORDER BY pd.name ASC");
gdje sam stavio IN te prilagodio zagrade navodnike.

Sada filtrira ono što mi treba, samo moram vidjeti kad to sada s testne integriram u live i napravim onaj izlist svih kategorija, da oduzmem samo one koje mi ne trebaju.

Eto. Na dobrom si putu. :wink:

Ma ispao sam iz svga toga, stalno CMS ovo ono, teme, dizajn, a programiranje sam ostavio davno davno. Hvala ti puno na pomoći, poslao si me na dobar puta sa getbycategoryId, a ne gdje sam dohvaćao proizvode pa onda kategorije.

Stavio sam u biti sada NOT IN, pa nadam se da je to to. Baš me zanima.

Jasta je nego to. Mozes da proslijedis i drugi argument u metod, tipa:

public function getProductsByCategoryIdNew($category_id, $in = FALSE)
{
    //pseudo code
    /*
    if ($in !== FALSE)
    {
        $search = 'IN';
    }
    else
    {
        $search = 'NOT IN'
    }
    ...
    ...
    AND p2c.category_id $search (". implode(',', $category_id) .") ORDER BY pd.name ASC");
    */
}

Nema puno filozofiranja.
Programiranje radi po principu “Gdje svrbi - pocesi!”. :smiley:

Hehe. Postavio online, isprobao radi kako treba…
Bože ja za ovo 2 dana izgubio sporadično…

Ma dao sam nekome da složi ispis u csv. Koristio je neki modul besplatni za opencart, izmjenjao ga, pa onda došao ja povrh njega sa još izmjena, dok sam pohvato tko što i gdje prođe vremena. Zato volim kad nekome dam da napravio sve od početka do kraja, ovak sporadične fore su koma.

Hardkodirao sam tih 5 kategorija koje trebam, ali razmišljam da napravim možda neki unput field u sučelje da se postave ili brojevi kategorija ili neki checbox.

No o tom potom, klijent tražio sam filter ako hoće sučelje mora javiti, jer nije isto :smile:

Tema je neka blesava nema nativni main menu gore, ni pod razno, pa sam morao tamo još i staviti drop down za kategorije, u temu, ali 3+ nivoa, a opencart defaultno 2 levela, pa sam se i tu zezao.

tpojka tnx još jednom na pomoći!