Kdyby\Events proč se nezavolá listener?

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

Nechce se mi zavolat listener při použití kdyby\events.

neon:

services:
	- AccountModule\FrontModule\Components\Account\Login\ILoginFormFactory
	-
		class: BasketModule\FrontModule\Events\Subscribers\ChangeBasketOwnerFromCookieListener
		tags: [kdyby.subscriber]

ILoginFormFactory – je továrnička s create pro LoginForm, který vypadá zzkráceně takhle:

final class LoginForm extends UI\Control
{
	public $onLogged = [];

	public function processForm(UI\Form $form)
	{
		$values = $form->getValues(TRUE);

		$account = $this->accountAuthenticator->login($values['email'], $values['password'], $values['permanent']);
		$this->onLogged($account);
}

a listener:

class ChangeBasketOwnerFromCookieListener extends Object implements Subscriber
{

	private $request;
	private $response;
	private $em;
	private $basketDao;

	public function __construct(Request $request, Response $response, EntityManager $em)
	{
		$this->request = $request;
		$this->response = $response;
		$this->em = $em;
		$this->basketDao = $em->getDao(Basket::getClassName());
	}

	public function getSubscribedEvents()
	{
		return [
			'AccountModule\FrontModule\Components\Account\Login\LoginForm::onLogged',
		];
	}

	public function onLogged(Account $account)
	{
		\Tracy\Debugger::dump('a');
		exit;
	}

}

ten dump jsem tam dal schvalne, a nezavola se, error zadny, nic

v debugbaru dole mam:

0x AccountModule\FrontModule\Components\Account\Login\LoginForm::onLogged
Listener
BasketModule\FrontModule\Events\Subscribers\ChangeBasketOwnerFromCookieListener #1206

0x onLogged
Listener
BasketModule\FrontModule\Events\Subscribers\ChangeBasketOwnerFromCookieListener #1206
Tomáš Votruba
Moderator | 1114
+
0
-

Pokud vím, tak se eventy volají pouze na registrovaných službách. V tvém případě máš jako služby dostupný authenticator a továrničku. Komponentu samotnou ne.

Editoval Tomáš Votruba (20. 9. 2014 15:49)

enumag
Člen | 2118
+
+1
-

Zkus EventManager::dispatchEvent().

Jiří Nápravník
Člen | 710
+
0
-

Aha, myslel jsem, že když registruju tovarnicku, tak se to bere automaticky i na samotnou komponentu. Nebudu to kmplikovat dat ten event tedy na Authenticator

David Matějka
Moderator | 6445
+
0
-

vypada to na bug v kdyby/events. funguje to, pokud ma definice sluzby uvedenou i tridu, kterou vytvari. Kdyz je tam jen implement, tak to nefunguje.

Filip Procházka
Moderator | 4668
+
0
-

Přímo na generovaných továrničkách eventy nejdou, ale mělo by se to wirovat na třídy které těmi továrničkami vytváříš. Asi bug, nejspíš na to chybí test :)

enumag
Člen | 2118
+
0
-

@FilipProcházka Dneska jsem to taky potřeboval tak jsem trochu šťoural v čem to vězí. Problém je v tom že EventsExtension::autowireEvents se volá během beforeCompile a tehdy ještě v $def->class nemusí být název vytvářené třídy, protože se z @return anotace přečte až později. Když vytvářenou třídu uvedu v neonu tak to funguje.

Nejsem si jistý jak to vyřešit / zda je přesun autowireEvents do afterCompile v pořádku.

Editoval enumag (22. 9. 2014 19:22)

David Matějka
Moderator | 6445
+
0
-

@enumag v librette/setup to resim takhle osklive: https://github.com/…xtension.php#…, ale jinak to imho udelat nepude :\

v afterCompile to byt nemuze, pridava se tam setup atd.

Editoval matej21 (22. 9. 2014 19:51)

enumag
Člen | 2118
+
0
-

Další zjištění, v Nette 2.3-dev to funguje protože tam se prepareClassList volá dříve než beforeCompile. Myslím tedy že je zbytečné to v Kdyby řešit (jen možná přidat test). Kdo to potřebuje v Nette 2.2 nechť použije workaround s definicí v neonu.

Editoval enumag (22. 9. 2014 21:24)

Filip Procházka
Moderator | 4668
+
0
-

Nevidím problém v přidání toho kódu co posílal @matej21, měl jsem za to že jsem ho tam taky někde měl, možná jsem si to spletl s AOP. Každopádně test by to chtělo.

Oli
Člen | 1215
+
0
-

enumag napsal(a):

Zkus EventManager::dispatchEvent().

Mám stejnej problém, akorát se mě to stejně nedaří vyřešit. Dělám s Kdby/Events poprvé, tak vubec netuším, co dělám blbě. Mám to takhle:

extension

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

	$builder->addDefinition($this->prefix('signUpEmailListener'))
		->setClass('\UserModule\Component\SignUpEmailListener')
		->setTags(['kdyby.subscriber']);

	$builder->addDefinition($this->prefix('signUp'))
		->setImplement('\UserModule\Component\ISignUp')
		->setFactory('\UserModule\Component\SignUp');
}

listener

	private $mailer;
	private $appSettings;

	public function __construct(\Component\Mailer $mailer, \AppSettings $appSettings)
	{
		$this->mailer = $mailer;
		$this->appSettings = $appSettings;
	}

	public function getSubscribedEvents()
	{
		return array('\UserModule\Component\SignUp::onRegistered' => 'onRegistered');
	}


	public function onRegistered(SignUp $signUp, \User\Entity\User $userEntity)
	{
		dump('registered');
	}

SignUp

public $onRegistered = [];

public function process($form)
{
	// ...
	$this->em->dispatchEvent(
		get_class($this) . '::onRegistered',
		new \Kdyby\Events\EventArgsList([$this, $this->userEntity])
	);
}

Event v debug buru vidět je a obsahuje i objekty, který obsahovat má, ale Listener vrací no system listeners
Prosím, co dělám špatně?