továrnička na komponenty v configu

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

Ahoj, začíná se mi projekt trochu rozrůstat a začínám mít problém se zakázkovými úpravami.
Konkrétně mám pro různé zákazníky různé komponenty, např. kontaktní formulář.
Normální továrnička v presenteru vypadá:

protected function createComponentContactForm() {
	return = new \ContactForm($this->context->database);
}

Jenže teď mám najednou kontaktní formuláře 3, např Firma2ContactForm a Firma3ContactForm (pokaždé trochu jiný, nejde to sloučit).
Redakční systém (dovolím si přehánět :) je u všech tří firem stejný, jediné co je jiné je config v neonu, obsah databáze a na základě nastavené šablony také adresář ze kterého se tahají šablony.

Jde pomocí neonu nějak zaregistrovat továrnička pro tyto komponenty? (zkrátka nechci v tomhle případě žádný zákaznický vývoj dávat do presenteru).
Případně jak jste se s tímhle problémem poprali?

Díky.

Filip Procházka
Moderator | 4668
+
0
-

Co takhle mít třídy, které jsou pro všechny stejné (to co by se dalo považovat za framework, nebo cms) v jedné složce/repozitáři a specifické věci v druhém. Díky tomu ti tyhle problémy odpadnou :)

Filip111
Člen | 244
+
0
-

S tím samozřejmě souhlasim, ale nechápu jak mi to pomůže v mém případě továrničky v base presenteru?
Myslíš nějak ještě podědit base presenter nebo do něj nacpat include, kde bude nějaký zákaznický vývoj?

Příklad: mám BasePresenter, ten je poděděný ve FrontBasePresenteru a právě v něm potřebuji mít ty továrničky pro inicializaci komponent. FrontBasePresenter je pak ještě dále poděděný.

Prosím ještě trochu popostrčit, díky.

Filip Procházka
Moderator | 4668
+
0
-

Udělej z továrničky tohle

protected function createComponentContactForm()
{
	return new Company1\ContactForm();
}

A celou továrničku přesuň do třídy.

Filip111
Člen | 244
+
0
-

Jenže ve tvým příkladu je stejně použitý název konkrétního klienta „Company1“ v obecném presenteru. To přece nic neřeší – leda že by se dala namísto namespace použít proměnná, např.

return new $client\ContactForm();

kde $client by byl název konkrétního klienta nastavený někde v konfiguraci. Potom by to řešilo přesně co potřebuji, ale dost pochybuji, že jde něco takového použít.

Filip Procházka
Moderator | 4668
+
0
-

Ale řeší

app/
	libs/
		Company1/
			ContactForm.php
	presenters/
		SomePresenter.php

libs/
	MyFw/
		NejakaSdilenaTrida.php

MyFw, je knihovna, která bude pro všechny projekty společná. app/ je složka, která bude pro každý projekt jiná. Komplet všechny specifické věci, včetně presenterů.

Chápeš kam tím mířím? žádné společné BaseFrontPresenter.php nebudou, protože každý projekt bude mít svůj. Tolik toho kódu tam nemáš, aby jsi ho nemohl vyčlenit do samostatných tříd. A sestavit z něj presentery, místo aby jsi dědil Base, Base, Base, ....

A k tvé otázce ohledně změny třídy podle proměnné. Tohle PHP umí.

$class = 'Client1\ContactForm';
return new $class();

Ale rozhodně to není řešení tvého problému.

Filip111
Člen | 244
+
0
-

Teď už konečně chápu – zatim ale nevim jak to uchopit. Zkrátka to co navrhuješ je předělání webu do podoby pokročilého FW. Zkusim si projít kódy Kdyby a podobných projektů a něco z toho pochytit.

Znamenalo by to pro mě vše úplně překopat – mám tam dohromady asi 15 presenterů, vše různě poděděné z base, base, base :) a netušim kde začít.

Naivně jsem si myslel, že už mám solidní funkční základ cms a teď si budu jen válet šunky. Dík za nasměrování.

David Matějka
Moderator | 6445
+
0
-

a co takhle upravit robot loader, aby rozlisoval priority adresaru? mel bys teda nejakej contactform spolecnej, pak bys ale potreboval pro konkretni instanci cms jinej contactform, tak bys ho dal do adresare s tou instanci. robot loader by ho normalne nasel a vyhodil vyjimku, ze je to zdvojena trida. tak to upravit, aby zjistil prioritu adresare a podle toho includnul spravnej soubor. v tovarnicce by teda mohlo porad byt return new ContactForm; robot loader by si pak zjistil, kterej contactform ma pouzit :)

Editoval matej21 (11. 12. 2011 16:34)

Filip Procházka
Moderator | 4668
+
0
-

To je naprosto otřesný nápad :)

Filip111
Člen | 244
+
0
-

@matej: radši ne :)
V okamžiku kdy budu pro jednu firmu dělat 20 různých formulářů a budu potřebovat 20 továrniček, tak to stejně musím cpát do nějakýho BasePresenteru, který tím hrozně zasvinim.

To co navrhuje HosipLan považuju za profi řešení, ale vůbec nevim jestli se do toho pustim. To můžu rovnou začít všechno od začátku a na to teď nemam čas a po několika měsících vývoje ani chuť.

Nevim jak z toho vybruslit.

Filip Procházka
Moderator | 4668
+
0
-

Nejlepší bude, až budeš dělat další projekt, tak ho zkus udělat takto. Ty co máš teď už nepředělávej :)

Filip111
Člen | 244
+
0
-

Myslel jsem si, že předělat to bude skoro nemožný – ale nedalo mi to a zkusil jsem to. Nedokázal jsem si pořádně představit co dát do libs a jak to má vypadat, jak bude vypadat app a jak budu volat jednotlivé presentery…zpočátku nepředstavitelný.

Hodně mi pomohl sandbox pro Nellu (hledal jsem i Kdyby :), ale nenašel).

Asi hodinu jsem kopíroval jednotlivé složky do nové struktury cms v libs, upravil cesty v formatLayoutTemplateFiles a formatTemplateFiles a světe div se, funguje to!!!

Pořád tomu nemůžu uvěřit – prostě jsem totálně překopal umístění jednotlivých souborů, všechno rozvrtal, v samotném adresáři app zůstal jen config, bootstrap, šablony konkrétního webu a pár komponent.

Neni to všechno na 100%, ještě budu muset pár věcí doladit, ale základ funguje jako dřív. Nette Loader má ode mě +++1.

duke
Člen | 650
+
0
-

Ponovu jsi to ještě mohl řešit továrničkou přímo v configu (database by to mělo dodat autowiringem):

factories:
    contactForm:
        class: Company1\ContactForm

A pak mít něco jako:

protected function createComponentContactForm() {
        return $this->context->createContactForm();
}
Filip111
Člen | 244
+
0
-

@duke:
To mi pomůže jen částečně – pokud budu uvažovat, že mám komponentu na jeden kontaktní formulář, a její podobu budu pro různé klienty měnit, pak je to ok.

Pokud si ale klient vymyslí víc kontaktních formulářů nebo obecně jakýchkoliv komponent, musel bych stejně do nějakého obecného base presenteru psát další továrničky (což je nežádoucí, protože stejný base presenter je určen pro všechny klienty používající cms).

V tomhle je opravdu struktura, kterou poradil HosipLan lepší a dovoluje mi jakékoliv modifikace a rozšíření, aniž bych musel řešit podobné problémy. Pomohlo mi to vyřešit celou řadu problémů z minulosti.

duke
Člen | 650
+
0
-

Jasně. Neodpovídal jsem v tom smyslu, že mnou navrhované řešení je vhodnější, ale prostě jsem odpovídal na původně položenou otázku, kde si přímo ptáš: „Jde pomocí neonu nějak zaregistrovat továrnička pro tyto komponenty?“