[Feed] Generování dat pro feed

jAkErCZ
Člen | 322
+
-1
-

Zdravím pomocí componette feed pro heureku a zboži se snažím natáhnout data do HeurekaGenerator

<?php

namespace App\CliModule\Model;

use Mk\Feed\Generators\Heureka\Generator;
use Mk\Feed\Generators\Heureka\Item;
use Tracy\Debugger;

class HeurekaGenerator extends Generator
{

    /** @var \App\CliModule\Model\DataLoader @inject */
    public $dataLoader;


    public function __construct(DataLoader $dataLoader)
    {
        $this->dataLoader = $dataLoader;
    }

    function generate()
    {
        $items = $this->dataLoader->getProducts();

        $items = [
            $this->createItem(),
            $this->createItem(),
            $this->createItem(),
            $this->createItem(),
        ];

        foreach ($items as $item) {
            $this->addItem($item);
        }
    }

    protected function createItem()
    {
        $item = new Item();
        $item->setProductName('title')#název nabídky, povinné, doporučená délka 70 znaků
        ->setDescription('Description')#popis nabídky, povinné (doporučená délka do 1000 znaků)
        ->setUrl('http://www.seznam.cz')#adresa nabídky v eshopu, povinné
        ->setPriceVat(10)#cena, povinné; číselná hodnota, max. dvě desetinná místa
        ->setDeliveryDate(0)#dostupnost, povinné (celé číslo nebo datum ve formátu RRRR-MM-DD)
        ->setItemId(123)#identifikátor nabídky v eshopu, nepovinné (alfanumerické znaky)
        ->setEan(87458965)#kód obchodní položky (čárový kód), nepovinné
        ->setIsbn('978-1-78038-067-4')#identifikační číslo knihy, nepovinné
        ->setProduct('PRO1548')#produktový kód výrobce, nepovinné
        ->setItemGroupId(10)#označení skupiny nabídek, nepovinné
        ->setManufacturer('Adidas')#výrobce produktu, nepovinné
        ->setProduct('Cerny'); #název nabídky ve výsledcích vyhledávání, např. "+ dárek zdarma", nepovinné

        #category text
        $item->setCategoryText('Kategorie | Subkategorie');

        #images
        $item->addImage('http://placehold.it/350x150'); #adresa obrázku, nepovinné, doporučujeme uvádět; značku je možné opakovat

        #parameters
        $item->addParameter('Barva', 'Hnědá'); #parametry nabídky
        $item->addParameter('Váha', '10', 'Kg');
        bdump($item);

        return $item;
    }

}

Jak docílím toho aby do toho createItem() se dostala data tak aby ten foreach ($items as $item) začal generovat data dle všechny záznamů v db?

Myslel sem že by to šlo formou $items = $this->dataLoader->getProducts(); ale to bohužel nejde…

Předem všem děkuji za pomoc

David Matějka
Moderator | 6445
+
+3
-

se na to poradne koukni. polozky sice nactes do promenne $items, ale hned je zas prepises.

jAkErCZ
Člen | 322
+
-1
-

@DavidMatějka No ale ten createItem() mi ale vypisuje parametry které to xml musí mít… To znamená bych měl ty data nahrát už v createItem() ne? ALe zase nevím jestli budou ve foreach…

Gavrilo
Člen | 46
+
+2
-

Uvedomuješ si čo robíš ? Ty si naplníš premennu $items s $this->dataLoader->getProducts(); a hneď v dalšiom riadku to prepíšeš … Ako sme ti už povedali na pehapkaroch nauč sa základy PHP lebo zbytočne trápiš nás aj seba …

jAkErCZ
Člen | 322
+
0
-

No ale jak tedy dostanu do toho create item ty data? Vím že je tam přepisuji ale nevím teď přesně jak je tam dostat…

$item->setProductName(‚Název‘) a myslel sem něco ve stylu $item->setProductName($item->title) ale to samozřejmě bude blbost… ale něco takového..

Šaman
Člen | 2666
+
+1
-

Pro začátek odděl přijatá data (to je nějaké pole, či co?) od hotových položek ($item, $items).

Pak projdi ta přijatá data foreachem a vytvářej položky přesně jak píšeš

<?php
foreach ($loadedData as $itemData) {
	$item = $this->createItem();
	$item->setProductName($itemData->title); // nebo $itemData['title'], podle toho jak vypadají přijatá data
	// …
	$items[] = $item;
}
?>

P.S. Nevím, co ti přijde na vstupu z toho $this->dataLoader->getProducts();
A taky nevím, co dělá addItem($item), možná je to připravená metoda pro vytvoření položky a přidání do seznamu. Pak by to ruční vytváření položek bylo zbytečné. To už musíš vědět sám.

Editoval Šaman (9. 2. 2018 12:51)

David Matějka
Moderator | 6445
+
+1
-

ano, ale musis si tu $item predat do createItem, sama se tam nedostane

jAkErCZ
Člen | 322
+
0
-

Tak ono to přece mělo jít i tímto způsobem ne?

function generate()
{
    $loadedData = $this->dataLoader->getProducts();

    foreach ($loadedData as $itemData) {
        $item = new Item();
        $item->setProductName($itemData->title)#název nabídky, povinné, doporučená délka 70 znaků
        ->setDescription($itemData->description)#popis nabídky, povinné (doporučená délka do 1000 znaků)
        ->setUrl($itemData->url)#adresa nabídky v eshopu, povinné
        ->setPriceVat($itemData->price)#cena, povinné; číselná hodnota, max. dvě desetinná místa
        ->setDeliveryDate($itemData->stock)#dostupnost, povinné (celé číslo nebo datum ve formátu RRRR-MM-DD)
        ->setItemId($itemData->code)#identifikátor nabídky v eshopu, nepovinné (alfanumerické znaky)
        ->setProduct($itemData->code)#produktový kód výrobce, nepovinné
        ->setManufacturer('Spokey');#výrobce produktu, nepovinné

        $items[] = $item;
    }

    foreach ($items as $item) {
        $this->addItem($item);
        bdump($item);
    }

}

Takto by to mělo fungovat ne?

P.S Tak funguje jen mi to nechce uložit :D :D a nevím proč..

Editoval jAkErCZ (9. 2. 2018 13:31)

CZechBoY
Člen | 3608
+
0
-

To bude asi problém metody addItem, ale tu si nám sem nevložil.

jAkErCZ
Člen | 322
+
0
-

Celý BaseGenerator

<?php

namespace Mk\Feed\Generators;

use Latte\Engine;
use Mk\Feed\Storage;
use Mk\Feed\FileEmptyException;
use Mk\Feed\ItemIncompletedException;

/**
 * Class BaseGenerator
 * @author Martin Knor <martin.knor@gmail.com>
 * @package Mk\Feed\Generators
 */
abstract class BaseGenerator implements IGenerator {

    /* Použití smartobject viz php 7.2 to nette 2.4 */
    use \Nette\SmartObject;

    /** @var bool true if some products added */
    private $prepared = false;

    /** @var resource|bool|null temp file */
    private $handle;

    /** @var \Mk\Feed\Storage */
    private $storage;

    /**
     * BaseGenerator constructor.
     * @param \Mk\Feed\Storage $storage
     */
    public function __construct(Storage $storage)
    {
        $this->storage = $storage;
    }

    /**
     * @param $name
     * @return string path to template
     */
    abstract protected function getTemplate($name);


    /**
     * Prepare temp file
     */
    protected function prepare()
    {
        $this->handle = tmpfile();
        $this->prepareTemplate('header');
        $this->prepared = true;
    }

    /**
     * @param \Mk\Feed\Generators\IItem $item
     * @throws \Exception
     * @throws \Throwable
     */
    public function addItem(IItem $item)
    {
        if (!$this->prepared) {
            $this->prepare();
        }

        if (!$item->validate()) {
            throw new ItemIncompletedException('Item is not complete');
        }

        $latte = new Engine;
        $xmlItem = $latte->renderToString($this->getTemplate('item'), array('item' => $item));
        fwrite($this->handle, $xmlItem);
    }

    /**
     * Generate file by addItem from db for example
     * @return void
     */
    abstract function generate();

    /**
     * @param $filename
     * @return void
     */
    public function save($filename)
    {
        $this->generate();

        if (!$this->prepared) {
            throw new FileEmptyException('File has not any items');
        }

        $this->prepareTemplate('footer');

        $size = ftell($this->handle);
        rewind($this->handle);
        $this->storage->save($filename, fread($this->handle, $size));

        fclose($this->handle);

        $this->prepared = false;
    }

    /**
     * @param $template
     */
    protected function prepareTemplate($template)
    {
        $file = $this->getTemplate($template);
        $footerHandle = fopen('safe://' . $file, 'r');
        $footer = fread($footerHandle, filesize($file));
        fclose($footerHandle);
        fwrite($this->handle, $footer);
    }

}

Ale tohle už není má práce ale někoho jiného kdo tento componette dělal :)

jAkErCZ
Člen | 322
+
0
-

@CZechBoY Takže jak to opravím?

CZechBoY
Člen | 3608
+
+3
-

možnost 1: vydebuguj si to
možnost 2: napiš tomu co to dělal že to neukládá data a ať provede možnost 1

jAkErCZ
Člen | 322
+
0
-

CZechBoY napsal(a):

možnost 1: vydebuguj si to
možnost 2: napiš tomu co to dělal že to neukládá data a ať provede možnost 1

Tak jsem zjistil že funkce

addItem($item);

Funguje v pořádku a vrací co má… ale ta

save($filename)

mi nic nevyhazuje… Tak vyhazuje na

$this->generate();

Háže NULL To znamená že funkce save nezíská data… ale funkce AddItem je vygeneruje ale přitom tu funkci generate() pouštím při vytváření save a když si to dupnu i tam tak tam data mám jen se prostě za boha nechtějí uložit… Ale ta ironie je že když data nahrávám ručně že tam na pevno narvu (Název,ID,url..) tak se mi to uloží v pořádku :) jen když těch dat dostane z db víc tak končí…

Editoval jAkErCZ (12. 2. 2018 9:43)