[bug] Vlastní PresenterFactory v Nette 2.4

nanuqcz
Člen | 822
+
0
-

Ahoj,
snažim se v Nette 2.4 použít vlastní PresenterFactory, ale to, co fungovalo v 2.3, mi v nové verzi prostě nefunguje.

Postup:
1/ composer create-project nette/sandbox

2/ Do config.neon přidám dle dokumentace toto:

services:
	application.presenterFactory:
		class: App\TestPresenterFactory
		alteration: yes

3/ Implementuju TestPresenterFactory, zatím pro testovací účely s defaultním chováním klasického Nette:

<?php
namespace App;

class TestPresenterFactory extends \Nette\Application\PresenterFactory
{

	public function getPresenterClass(&$name)
	{
		return parent::getPresenterClass($name);
	}

}

Výsledek: Chyba „Call to a member function isSent() on null“.
Plná laděnka zde

Všimněte si, že ve výpisu laděnky není nikde volání funkce „isSent()“ (bug v Tracy, která pravděpodobně nezobrazila některý PHP soubor).

V čem je problém? Proč jen při jednoduchém podědění výchozího PresenterFactory najednou sandbox nefunguje?

Děkuji za odpovědi.

Editoval nanuqcz (26. 6. 2017 18:43)

David Matějka
Moderator | 6445
+
+3
-

Dojde totiz k prepsani (respektive zahozeni) argumentu PresenterFactoryCallback

bohuzel, v configu nejde zmenit trida se zachovanim argumentu, takze bud je musis definovat znova

services:
	application.presenterFactory:
		create: App\TestPresenterFactory(Nette\Bridges\ApplicationDI\PresenterFactoryCallback(
				invalidLinkMode: Nette\Application\UI\Presenter::INVALID_LINK_WARNING,
				touchToRefresh: false
			))
		alteration: yes

tady je teda nevyhoda, ze invalidLinkMode a touchToRefresh detekuje ApplicationExtension dle nastaveni a prostredi, coz tady neudelas

druhou moznosti je pak zmenit tu tridu v compiler extension, kde si muzes sahnout na puvodni argumenty te sluzby a pouzit je znovu

edit: zalozil jsem issue, ktery s tim souvisi: https://github.com/…i/issues/154

matopeto
Člen | 395
+
0
-

Rovnaka chyba sa riesila tu: https://forum.nette.org/…stom-folderi#… a vyzera ze tam to nejako poriesili…

nanuqcz
Člen | 822
+
+1
-

Díky moc, funguje :-)

Nakonec jsem si vytvořil extension, aby mi to nezabíralo místo v configu:

# config.neon
extensions:
	myExtension: TestPresenterFactoryExtension
<?php
class TestPresenterFactoryExtension extends Nette\DI\CompilerExtension
{

	public function loadConfiguration()
	{
		$config = $this->compiler->getConfig();
		$builder = $this->getContainerBuilder();

		$builder->addDefinition('application.presenterFactoryCallback')
			->setFactory(
				'Nette\Bridges\ApplicationDI\PresenterFactoryCallback',
				[
					'@container',
					Nette\Application\UI\Presenter::INVALID_LINK_WARNING,  // invalidLinkMode
					FALSE,                                                 // touchToRefresh
				]
			);

		$builder->removeDefinition('application.presenterFactory');
		$builder->addDefinition('application.presenterFactory')
			->setFactory(
				'TestPresenterFactory',
				['@application.presenterFactoryCallback']
			)
			->addSetup(
				'setMapping',
				[$config['application']['mapping']]
			);
	}

}