Školská úloha – vytvorenie internetového portálu

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
craz
Člen | 34
+
0
-

Dobrý deň,

v škole som dostal zadanie na vytvorenie internetového portálu pre vymyslenú firmu. Podmienky boli dané, je nutný aj jednoduchý eshop. S Nette mám len pár dňové skúsenosti, ale vybral som si ho, keďže je to pre mňa výzva a zaujala ma myšlienka využitia frameworku následne aj v pracovnej sfére.

Približné znenie, stránka sa bude skladať z dvoch častí:

čast front

  • 6 podstránok (Uvod, O nas, Ponuka, Referencie, Pracovny tim, Kontakt)
  • – na podstránke Kontakt formulár, odosiela mail
  • zoznam udalostí na každej podstránke (nazov, cas, miesto)
  • – možnosť pridania udalosti návštevníkom
  • jednoduchý „eshop“
  • – kategórie, produkty, formulár na objednávku

čast admin

  • prihlasovanie (s možnosťou nastavenia práv)
  • úprava podstránok front časti pomocou Texy!
  • editácia eshopu (pridávanie/mazanie/editácia kategórií, produktov)
  • editácia udalostí, ktoré sa zobrazujú vo front časti ako zoznam

Používam Nette pre php5.3 bežiacom na XAMPPe. Aj keď mi nerobí problém študovať dokumentáciu a podobné dokumenty, pri Nette som sa naozaj stratil a neviem, kde by som mal čo sledovať. Začínam s prednastaveným sandboxom. Dopracoval som sa zatial len k fornt časti, kde sa dá preklikavať podstránkami.

Navrhujete mi rozdeliť časti admin a front na 2 moduly, kde by každý mal vlastné modely, presentery a templaty v podobe akej sa nachádzaju v sandboxe ? aspoň tak som to pochopil z MVC architektúry (podľa ktorej som doteraz tiež nepracoval).

Poprípade skúste napísať, ako by ste postupovali.

Od toho sa budem snažiť odpichnúť ďalej. Vopred ďakujem ľuďom, ktorí sa budú snažiť pomôcť :)

Ani
Člen | 226
+
0
-

Osobně si myslím, že rozdělení na Front a Admin modul je v mnoha věcech nejednoznačné a návzájem se překrývajicí. Lepší mi přijde rozdělení na Page, Shop, User moduly a práva v nich řídit přes ACL, ale je to asi o něco těžší. Front/Admin určitě nic nezkazíš.

Editoval Ani (5. 3. 2011 17:23)

ic
Člen | 430
+
0
-

Na školní projekt je to hodně věcí, zvlášť pokud by se to nemělo úplně odflánkout, rozhodně to nějakou dobu potrvá. O jakou školu vlastně jde, jestli to teda není tajné?

Droid
Člen | 92
+
0
-

Na takové CRUD based věci upřímně volím Ruby on Rails. Je to v tom záležitost na pár hodin.

craz
Člen | 34
+
0
-

študujem na Fakulte elektrotechniky a informtiky, TUKE .. jedná sa o bakalársku prácu.

Cifro
Člen | 245
+
0
-

No bratmm maš čo robiť, keď v máji sa odovzdáva…

craz
Člen | 34
+
0
-

Tak som sa postupne prepracoval ku poslednému bodu mojho zadania. Ta vysoka krivka ucenia asi ma daco do seba, ale bez fora by som sa nepohol :)

Pracujem akurat na jednoduchom nakupnom kosiku, kde som sa zasekol. Kedze to chcem mat co najjednoduchsie, tak produkty v kosiku su ulozene v session.

  • mal by sa dat vyprazdnit cely kosik
  • pod kosikom formular na odoslanie objednavky, kde sa kontaktne udaje s cislom objednavky ulozia v jednej tabulke a typ a pocet produktov v druhej, viazanych cez cislo objednavky.

moj handler na pridanie produktu do kosika:

<?php
public function handleAdd($id) {
		$id = (int) $this->getParam('id');
        $count = 1;

		$items = Environment::getSession(__CLASS__);

		if (isset($items->items[$id])) {
			$items->items[$id]++;
			$this->flashMessage("Zvýšil sa počet produktu.");
		} else {
			$items->items[$id] = $count;
			$this->flashMessage("Produkt bol pridaný do košíka.");
		}

		$this->redirect("this");
	}
?>

handler, ktory by mal zrusit pole „items“, ale nerobi to:

<?php
public function handleEmpty()
	{
		//$items = Environment::getSession(__CLASS__)->items;
		unset($items);

		$this->redirect("this");
	}
?>

skusal som aj $items->remove(); na zrusenie session, ale neuspesne, ako na to?

dalej som sa zasekol aj pri generovani „stavu“ kosika, kde by som chcel zobrazit meno produktu, pocet kusov a vyslednu cenu, no neviem prist na logiku ako to spojit. zatial som sa dopracoval len k tomuto:

<?php
public function renderKosik()
	{
		$items = Environment::getSession(__CLASS__)->items;

		$products = array();

		if ($items) {
			foreach ($items as $id => $count) {
				//$products[] = array($product:id=>);
				$products[] = \EshopModel::fetchSingleProduct($id);
			}
		}
		$this->template->products = $products;
	}
?>

chcem to mat co najjednoduchsie, avsak aj tak sa mi nedari, vedel by mi niekto poradit?

Pavel Kouřil
Člen | 128
+
0
-

Osobne to resim pres singleton, ktery pracuje s $_SESSION[‚basket‘] – obsahuje metody jako addProduct($productId, $quantity) a truncate() apod… kdyztak odpoledne ukazu tu tridu. Ale mozna by to slo i cisteji a vic nette, kdovi

bojovyletoun
Člen | 667
+
0
-

Proměnná $items definovaná v handleAdd bude jen viditelná uvnitř funkce handleAdd. Takže v handleEmpty $items je jiná proměnná a bude prázdná.
Takže si přidej do třídy property $items a ve funkci startup nastav $this->items=Env::getSession a dál používej $this->items.
* lepší je používat místo Evironment::getsession $this->getSession

public  $items;
function startup(){$this->items=$this->getSession('...');}
public function handleEmpty()
        {
                //$items = Environment::getSession(__CLASS__)->items;
                unset($items); //tohle je nesmysl, $items jsi nikde nedeklaroval
		unset($this->items);
                $this->redirect("this");
        }

Editoval bojovyletoun (18. 4. 2011 11:18)

craz
Člen | 34
+
0
-

dakujem za reakcie.

@bojovyletoun – idem to hned vyskusat

@Pajka – ak sa da, skus poslat tvoj kod, mozno sa niecim inspirujem, vdaka :)

craz
Člen | 34
+
0
-

dakujem, tymto postupom mi to uz funguje. idem to teda dokoncit :)

craz
Člen | 34
+
0
-

chyba mi uz len posledna vec. zasekol som sa na aktualizacii stavu objednavky:

presenter:

<?php
public  $statusA;

	public function beforeRender()
	{
		$this->statusA = array (
			"expand" => "Expandovaná",
			"handle" => "Vybavuje sa",
			"none" => "Nevybavená"
			);
	}
	public function renderOrder($id = 0)
	{
		$order = \EshopModel::fetchOrder($id);

		//nastavenie stavu z databazy
		$this["status"]->setDefaults($order);

		$this->template->order = $order;
	}

	//formular na zmenu stavu
	public function createComponentStatus($name)
	{
		$form = new AppForm($this, $name);

		$form->addSelect('status', "Stav:", $this->statusA);

		$form->addSubmit('send', 'Zmeniť stav');
		$form->onSubmit[] = callback($this, 'statusSubmitted');
		return $form;
	}
	public function statusSubmitted(AppForm $form)
	{
		$id = (int) $this->getParam('id');
		//tu je pravdepodobne chyba
		$data = $form->getValues();

		\EshopModel::setStatus($data,$id);
		$this->flashMessage("Status upravený");
		$this->redirect("this");
	}
?>

model:

<?php
public static function setStatus($data,$id)
	{
		return dibi::query('
			UPDATE [orders]
			SET ', (array) $data,'
			WHERE [id] = %i', $id
		);
	}
?>

edit: este pridavam priklad vykresleneho selectboxu

<select name="status" id="frmstatus-status">
	<option value="expand">Expandovaná</option>
	<option value="handle" selected>Vybavuje sa</option>
	<option value="none">Nevybavená</option>

</select>

SQL prikaz prebehne, ale namiesto vlozenia stavu zo selectboxu sa vlozi prazdna hodnota. kde moze byt chyba?

Editoval craz (19. 4. 2011 10:16)

Pavel Kouřil
Člen | 128
+
0
-

K tomu singletonu košíku – vypadá nějak takhle, psaný je ještě pro php5.2 a prefixované nette. Vzhledem k tomu, že mi stačí ukládat pole $productId => $quantity, tak se mi to vyřešit takhle zdálo jako nejrozumnější (navíc s ohledem na další rozšířitelnost) – a taky proto, že potřebuju obsluhovat košík na víc místech a kopírovat všude delší kód by bylo imho zbytečné; a o to víc, kdyby se něco změnilo.

<?php

class Basket extends NObject
{

    private static $instance;

    private $basket;

    private function __construct()
    {
        $this->basket = NEnvironment::getSession('basket');
    }

    /**
     * Returns singleton Basket instance
     * @return Basket
     */
    public static function getInstance()
    {
        if (!isset(self::$instance))
        {
            $class = __CLASS__;
            self::$instance = new $class;
        }

        return self::$instance;
    }

    /**
     * Adds product to basket
     * @param int $id
     * @param int $count
     */
    public function addProduct($id, $count = 1)
    {
        if (isset($this->basket[$id]))
        {
            $this->basket[$id] += $count;
        }
        else
        {
            $this->basket[$id] = $count;
        }
    }

    /**
     * Removes product from basket
     * @param int $id
     */
    public function removeProduct($id)
    {
        unset($this->basket[$id]);
    }

    /**
     * Updates product count
     * @param int $id
     * @param int $count
     */
    public function updateProduct($id, $count)
    {
        $this->basket[$id] = $count;
    }

    /**
     * Removes all products from basket
     */
    public function truncate()
    {
        foreach ($this->basket as $key => $value)
        {
            unset($this->basket[$key]);
        }
    }

    public function getBasket()
    {
        return $this->basket;
    }

}

… a k druhému dotazu; jaký SQL dotaz se přesně provede? Ale zkus to přepsat takto:

public function statusSubmitted(AppForm $form)
{
        $id = (int) $this->getParam('id');

        $data = $form->getValues();
		unset($data['send']);

        \EshopModel::setStatus($data,$id);
        $this->flashMessage("Status upravený");
        $this->redirect("this");
}
public static function setStatus($data,$id)
        {
                return dibi::query('
                        UPDATE [orders]
                        SET ', $data,'
                        WHERE [id] = %i', $id
                );
        }
?>
craz
Člen | 34
+
0
-

Pajka – dakujem za kod, skusim neskor mozno daco z toho prepisat pre moj pripad.

co sa tyka mojho posledneho problemu, tak to unset vlastne netreba, kedze to myslim robi Nette automaticky.

kazdopadne som si skusil Dumpnut premennu $data po odoslani formulara a dostavam NULL. cize aj ked sa vyberie zo selectu nejaka polozka, nepriradi alebo sa hodnota neodosle na spracovanie.

je to zvlastne, lebo tie hodnoty mam priradene v premennej $statusA a do formulara ich vkladam ako defaultne a z vykreslenej stranky je jasne, ze sa tam aj tie hodnoty dostali.

tatyalien
Člen | 239
+
0
-

Až to doděláš a odevzdáš, nehodíš to někam? Protože pokud to je bakalářka, tak to budeš mít nejspíš všechno pěkně komentované a pro začátečníky (mě :-D) by se to hodilo na jukandu, jak se dají dané věci řešit ;)

Pavel Kouřil
Člen | 128
+
0
-

Má to ten statusA jako proměnná celé třídy nějaké opodstatnění? Každopádně je blbost ji definovat v beforeRender() *) – buď ji nadefinuj přímo jako public $statusA = array(„key“ ⇒ „value“) rovnou nebo ve startup() nebo až v definici formuláře

) *k tomu beforeRender() – podezříval bych z toho https://doc.nette.org/…n/presenters , ale ruku do ohně za to nedám, protože jsem taky jen začátečník

craz
Člen | 34
+
0
-

Pajka – vyborne! … statusA som dal ako public $statusA = array()… a funguje to. Ked sa pozriem na ten priebeh presenteru, tak to aj dava logicky zmysel. dakujem za pomoc, teraz to mozem povazovat za dokoncene :)

tatyalien – komentovane to zatial nemam, ale asi to budem musiet spravit. a urcite to potom niekde zavesim, aj ked neviem, ci z mojho prveho pokusu o „OOP“ niekto vyjde. No mozno to naozaj niekomu pomoze :) … tak do 2 tyzdnov to hodim, mozno tam este nieco dorobim, ak bude cas.

tatyalien
Člen | 239
+
0
-

Oki, jen mě zajímá jak to bude vypadat ;) ze zadání atd :-)

craz
Člen | 34
+
0
-

tak bakalarka odovzdana, uz len obhajit :)

pridavam moj „projekt“ na stiahnutie, ak by sa chcel niekto na to pozriet. vopred upozornujem, ze moj postup nemusi byt stale spravny (ak vobec niekedy), ako vyplyva z prveho prispevku, ucil som sa za behu :)

http://www.uloz.to/…eprojekt-zip

tatyalien
Člen | 239
+
0
-

Staženo, po víkendu se na to juknu ;) díky

Edit: zatím jsem se jen podíval na výsledek a pěkný ;) ale po tejdu se prohrabu v kódu ;)

Editoval tatyalien (27. 5. 2011 15:18)

srigi
Nette Blogger | 558
+
0
-

Kcelo by to live demo.

craz
Člen | 34
+
0
-

nahodil som to sem: http://craz.php5.sk/www/

edit: vsimol som si jednu zmenu – akoby nefungoval helper date. Datumy pri kongresoch mali byt v tvare DD. MM. YYYY, ale tu sa zobrazuju ako MM/DD/YY. V podstate ma to uz netrapi, pretoze na skolskom serveri to beha, ako ma, ale predsa, vie niekto, preco je to tak ?

Editoval craz (27. 5. 2011 18:53)

Pepis
Člen | 16
+
0
-

Ahoj,
demo nějak nefunguje, dalo by se s tím něco udělat. Díky

craz
Člen | 34
+
0
-

Pepis – narychlo ta viem odkazat na skolsky server – http://krabik.fei.tuke.sk:8080/vesely/www/