createComponent a automatické načítání tříd

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

Zdravím,
mám cca 10 stránek na kterých načítám komponenty v jednom presenteru. A abych ušetřil místo, tak mě napadlo napsat něco takovéhodle

public function createComponent($name)
{
	$class = ucfirst($name);
	return new $class;
}

v latte mam {control defnicePracovnichSkupin} a tím jsem předpokládal, že se mi budou načítat komponenty, které se mi předají ve $class. Bohužel po refreshi dostanu chybu, že zadaná třída neexistuje. Pritom, když napíšu třeba

public function createComponentDefnicePracovnichSkupin($name)
{
	return new DefnicePracovnichSkupin();
}

tak to normálně funguje. Pokusil jsem se googlit, ale asi problém neumím problém správně pojmenovat, protože moje snahy jsou liché :(

enumag
Člen | 2118
+
0
-

Metoda createComponent v Nette už je a dělá docela podstatnou věc – připojuje komponentu k presenteru. Když ji podědíš a nevoláš parent, musíš to udělat sám, jinak presenter nezjistí že komponenta existuje.

Mimochodem něco podobného jsem kdysi dávno používal také. A zase jsem se vrátil k Nettí cestě. :-)

Editoval enumag (6. 2. 2013 11:04)

redhead
Člen | 1313
+
0
-

Mimochodem, je tu bezpečnostní riziko. Člověk pak může vytvořit jakoukoliv komponentu, která ani nemá být zobrazena na dané stránce (nebo nemá oprávnění ji vytvořit), jen tím, že vytvoří URL s názvem té komponenty a nějakou akcí.

Většinou to umře na nějaké nepředané závislosti nebo neexistujícímu handleru, ale myslím, že to není dobrý nápad.

Editoval redhead (6. 2. 2013 12:29)

enumag
Člen | 2118
+
0
-

@redhead: To je druhá věc. Bohužel tenhle problém vzniká i při použití továren byť jen v rámci jednoho presenteru pokud si to člověk neošetří.

TOMeek
Člen | 64
+
0
-

Nechám to tedy být. Myslel jsem, že to takto půjde, ale bylo by stím více starostí, než radostí. Raději se budu držet toho jak se to má.

Rampus
Člen | 39
+
0
-

Řešil jsem před časem něco podobného, protože jsem byl línej psát X createComponent fcí a vyřešil jsem to následovně:
komponenty mám definované v configu jako service:

<?php
                adminModel: \AdminModule\Model(@database)
                acl: \ACL(@database)
                adminMenu: \AdminModule\AdminMenuComponent
                languageSwitcher : \LanguageSwitcherComponent
                doorsAdminControl:   \AdminModule\DoorsComponent
                frontDoors: \FrontDoorsComponent
                basket: \Modulus\BasketComponent
                userWidget: \Modulus\UserComponent
                orderView: \OrderViewComponent
                rightFlash: \RightFlashComponent

?>

a v BasePresenteru mám mám fci na tvorbu komponent:

<?php
    public function createComponent($name) {
        $method = 'createComponent' . $name;
        if ($this->getReflection()->hasMethod($method)) {
            $this->addComponent($this->$method($this, $name), $name);
            return;
        }
        if ($this->context->hasService($name)) {
            $this->addComponent($this->context->getService($name), $name);
            return;
        }
        parent::createComponent($name);
    }
?>

a šlape to do dneška :)

Editoval Rampus (8. 2. 2013 10:39)

Felix
Nette Core | 1247
+
0
-

Řešil jsem před časem něco podobného, protože jsem byl línej psát X createComponent fcí a vyřešil jsem to následovně: komponenty mám definované v configu jako service:

Nebylo by vhodnejsi mit ty komponenty jako factories?