připojení databáze v modelu a předání dat presenterům

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

Ahoj, několikrát se to tu řešilo, našel jsem hned několik vláken, ale jsem – jak by řekla moje slovenská flatmate – trololo.

autowiring, injectování, anotace…

Popíšu strukturu a pak položím dotaz:

model – BaseConnection.php
model – Homepage.php extends BaseConnection.php

presenter – HomepagePresenter.php


Model- BaseConnection.php

<?php
namespace Nette\Database;

use \Connection;

class BaseConnection
{
    /** @var Nette\Database\Context */
        protected $conn;

        function __contruct(\Context $conn)
        {
            $this->conn = $conn;
        }
}

Model – Homepage.php

<?php

class Article extends BaseConnection
{
    function get__CLASS__ ()
    {
        return $this->conn->table('article')->order('id DESC')->limit(5);
    }
}

Presenter – HomepgePresenter.php

<?php

namespace App\Presenters;

use Nette,
	App\Model;

class HomepagePresenter extends BasePresenter
{

	public function renderDefault()
	{
		$this->template->article = "pole plné článků";
	}

}
Jde o to, že jsem si vytvořil spojení v modelu s db. Tam vyvstává jedna otázka
namespace Nette\Database;
use \Connection;

* Je potřeba volat nad tím use \connection?

Obecně jsem o to, že potřebuju dostat data z databáze do presenteru a následně do šablony. Narážím přitom ale na problém. Nedědí to tí normálním phpéčkářkým způsobem. a pokud by to dědilo, jak potm dostat data z toho modelu do presenteru?

Nevim jak na ten autowiring, ani na ty anotace, injectovat bych zvládl, ale zase si říkám, že bych docela rád ušetřil kód a jestli v každém záhlaví nového presenteru injectovat nebo volat db\context, co na tom sejde?

Mrkám na to od ráána a jsem z toho dost zmatený, pokud možno prosím, zkuste mi poradit v příkladech.

Díky

Oli
Člen | 1215
+
0
-

Zkusím to víceméně naroubovat na to tvoje řešení. Tady je příklad, jak by to mohlo vypadat. Pro Nette 2.1+:

# neon
services:
	- Repository/Article
// presenter

namespace App\Presenters;

class HomepagePresenter extends BasePresenter
{
	/** @var Repository/Article @inject */
	public $article;

    public function renderDefault()
    {
        $this->template->article = $article->getArticle();
    }

}
// Repository/article

namespace Repository;

class Article extends BaseRepository
{

    function get__CLASS__ ()
    {
        return $this->conn->table('article')->order('id DESC')->limit(5);
    }
}
// BaseRepository

namespace Repository;

class BaseRepository
{
	/** @var Nette\Database\Context */
        protected $conn;

        function __contruct(\Nette\Database\Context $conn)
        {
            $this->conn = $conn;
        }
}

Editoval Oli (10. 5. 2014 23:30)

Michal Vyšinský
Člen | 608
+
0
-

V tom neonu ‚services‘ místo ‚service‘

Oli
Člen | 1215
+
0
-

Psal jsem to z hlavy a tohle jsem mel snad vzdycky predpřipravený (nikdy jsem to vlastně nepsal) :-D

Díky, za upozornění

qteck
Člen | 164
+
0
-

díky za pomoc.

jen ještě něják nerozumím těm anotacím.

/** @var Repository/Article @inject */

co tohle v podstatě vykoná?

a tohle /** @var Nette\Database\Context */

setkávám se s tím prvně.

Šaman
Člen | 2666
+
0
-
  1. Jsou to anotace v komentáři, není to PHP kód. Nevykoná to nic.
  2. Ale protože PHP nemá nástroje třeba pro určení typu proměnné, nebo parametru, začaly se tyhle dodatečné informace psát do speciálních komentářů (od obyčejného komentu se liší dvěma hvězdičkama na začátku). PHP je ignoruje, ale umí s tím pracovat například lepší IDEčka a napovídat pak správné metody (třeba v tom tvém druhém případě, když pak v kódu dáš $database->, tak ti napoví metody třídy Nette\Database\Context)
  3. Anotace se dají i načíst a interpretovat v našem kódu. Takže pomocí anotací je možné přidat různé příznaky nějaké třídy/metody/proměnné a pak je zpracovat vlastním kódem. To dělá třeba ten DI container, který, pokud vytváří třídu, tak ji ještě projde a hledá anotaci @inject. Pokud ji najde, snaží se použít autowiring, tedy předat té metodě, nebo proměnné odpovídající službu která už v kontejneru existuje. V tvém prvním případě zjistí, že je potřeba nastavit (@inject) do proměnné službu Article (@var Repository/Article). To @var tu být tentokrát již musí, protože podle toho se daná služba dohledává.

Resume: Komentáře se dvěma hvězdičkama (taky se jim říká PhpDoc bloky) nejsou obyčejné komentáře a není moudré je ignorovat nebo mazat. Anotace (@cokoliv) bývají důležité pro chod aplikace a jsou vpodstatě rozšíření jazyka PHP o další možnosti. Často se třeba používají v některých ORM pro přehledný zápis entitních vazeb.

Editoval Šaman (11. 5. 2014 18:34)

qteck
Člen | 164
+
0
-

pořád to nechce šlapat.

žádné chyby to nevyhazuje, ale když dumpnu obsah té funkce getArticle tak to vypíše:

  • class Repository\Article#208 (1) { protected $conn ⇒ NULL }

což zřejmě zanemná, že spojení nefunguje.

laděnka neukazuje žádné položené dotazy na db.

Šaman
Člen | 2666
+
0
-

Hoď to někam na GitHub, nevím, který kód ti nefunguje. Záleží i na drobnostech, třeba správně zapsaný namespace.

qteck
Člen | 164
+
0
-

tady to je : https://github.com/…GroupKerouac

jinak díky za vysvětlení těch anotací :-).

Šaman
Člen | 2666
+
0
-

Sorry, ale je to uplně naskrz prolezlé taakhle velkými červíky (důlními i močálovými). Jestli chceš, proberem to na Skype. V pátek jedu učit poslední hodinu a z ukázek jsem zjistil, že budu muset vytvořit aktuální quickstart s modelem, tak když chvíli počkáš, bude u mě na GitHubu. Zatím je tam podobná miniaplikace, ale s pár vychytávkama, které bych pro začátek nevysvětloval (automaticky generované továrničky, traity).

qteck
Člen | 164
+
0
-

pátek to je docela dlouhá doba, teď už mi nezbývá než počkat, neboť moji flatmates chrapí.

i když podle těch zvuků co mi tady v pravidelnym intervalu buší do zdi tam spíš užívají benefity lásky.

asi jim tam půjdu vynadat.

:-D

qteck
Člen | 164
+
0
-

ou, jsem každej konstruktor měl zapsanej jako __contructor bez s.....
tak, už to aspoň něco hlásí.

ale netbeans mě trochu nakrknul, protože na to by správnej ide měl upozornit, no že?

qteck
Člen | 164
+
0
-

Nakonec už mám jenom jednoduchou otázku:

class HomepagePresenter extends BasePresenter
{
<?php

namespace App\Presenters;

class HomepagePresenter extends BasePresenter
{
    /** @var Repository\Article @inject */
    public $article;

    public function renderDefault()
    {
        $this->template->article = **$article->getArticle()**;
    }

}

vrací mi to že proměnná article není definovaná. zkusil jsem to zapsat i jinými způsoby, ale vždy nešťastně.

jak tedy zavolt tu funkci? děkuji.

qteck
Člen | 164
+
0
-

oh my gosh, já jsem to rozjel!!!!!!

qteck
Člen | 164
+
0
-

okay tohle téma zavřeme, komunikuje to komunikuje.

Díky za pomoc.


ještě bych doplnil, jak nakonec vypadá ten presenter, aby to mělo nějákou pomoctnou hodnotu v případě že by byl někdo tak inteligentní jako já.

class HomepagePresenter extends BasePresenter
{
        /** @var \Repository\Article @inject */ //běhá to i bez tohodle injectu
        public $article;

        function __construct(\Repository\Article $article) // tohleto nevím co je, ale je to klíčové.
        {
            parent::__construct(); // běhá to i bez volání rodičovského konstruktoru
            $this->article = $article;
        }
	public function renderDefault()
	{
            $this->template->article = $this->article->getArticle();
	}

}

Editoval qteck (12. 5. 2014 0:43)

Šaman
Člen | 2666
+
0
-

V presenteru by se do konstruktoru sahat nemělo. Proto tam je ta anotace @inject (která funguje jen v presenterech!). Ty ji teď skutečně nepotřebuješ (ani @var, určující je teď určení parametru konstruktoru), ale ani nepotřebuješ tu property jako public.
Anebo můžeš vymazat celý konstruktor. Jinak parent konstruct často není potřeba, ale vždy se volá, protože nikdy nevíš, kdy do konstruktoru předka někdo něco důležitého doplní.