events concept in yii2 - events

I have gone throught the guide from :
http://www.yiiframework.com/doc-2.0/guide-concept-events.html
but I have simple confusion here is that:
// this handler is a static class method
$foo->on(Foo::EVENT_HELLO, ['app\components\Bar', 'methodName']);
the above event will be fired on the execution of method : 'methodName' of class 'app\components\Bar' ?
OR
method : 'methodName' of class 'app\components\Bar' will be fired on the call of above event ?

method : 'methodName' of class 'app\components\Bar' will be fired on the call of above event.
To fire event on execution of method you must triggering event - http://www.yiiframework.com/doc-2.0/guide-concept-events.html#triggering-events

Related

Finding or creating a mehod with the opposite of the handleMessage method behavior which it is triggered when a message is sent

The handleMessage() function is triggered when a message is received.
How to have a function when a message is sent, it is triggered?
Thanks
First of all, in your simple module define a method that will be triggered, for example:
void MyModule::handleSending() {
// do something
}
Then in the every place of your module where a message is sending add this method, for example:
...
send(packet, "out");
handleSending();
...

How can I override laravel logout core event?

I'm trying to broadcast Illuminate\Auth\Events\Logout. Is it possible to override or extend this core event so as to include BroadcastOn method?
You cannot override the core logout event. There are two ways about this problem. Either way, you will have to fire your custom event.
Override loggedOut() method in AuthenticatesUsers:
You will have to create your custom event and override loggedOut() method in AuthenticatesUsers to fire it manually like so:
protected function loggedOut(Request $request)
{
event(new CustomLogoutEvent());
}
This will fire the core event and your custom one.
Override SessionGuard to override logout() (lengthy and not suggested):
logout() in SessionGuard is where the core logout event is triggered. Override it to only fire your custom event. This way only one logout event is fired.
Here is how to override guards: https://laravel.com/docs/7.x/authentication#adding-custom-guards

Reset spyOnEvent on document

I'm trying to track a custom event based on some data, for this I'm spying on my custom event and expecting the event to get trigger or not. Here am trying to reset my spyevent all I get is undefined error
TypeError: undefined is not an object (evaluating 'spyOnEvent(document, 'product.trackVariantChanged').calls.reset')
it('selects a variant without triggering the product.trackVariantChanged event on document', function() {
spyOnEvent(document, 'variantChanged');
spyOnEvent(document, 'product.trackVariantChanged').calls.reset();
App.ColorSelector.init(); // this function automatically calls custom triggers when it calls
App.ColorSelector.selectVariant($colorSelector, 'wms_III_black'); //this function has a depedency on init()
expect('variantChanged').toHaveBeenTriggeredOn(document);
expect('product.trackVariantChanged').not.toHaveBeenTriggeredOn(document);
App.ColorSelector.selectVariant($colorSelector, 'wms_III_white');
expect('variantChanged').toHaveBeenTriggeredOn(document);
expect('product.trackVariantChanged').not.toHaveBeenTriggeredOn(document);
});
from above case App.ColorSelector.init(); this function automatically calls/ should get call fisr and triggers custom event and App.ColorSelector.selectVariant($colorSelector, 'wms_III_black'); this function has a dependency on init() function
So I want to reset the spy before the selectVariant function get called.
For spyOnEvent instead of calls.reset() use spyOnEvent(document, 'customEvent').reset(); it will work.

Mockery: Method does not exist on mock object

So I have an object which I am mocking and it has methods that are used for sending emails. I have gone from a static class over to a concrete class because I was having issues testing the static class with Mockery.
However I am now finding that when an eloquent model is saved it throws an event which fires off a listener. This listener is what is responsible for kicking off the call to the mock objects method.
I have found that when I do something like the following it works.
$model = factory(MyClass::class)->make();
$model->property = 'value';
$model->save()
$this->mailer->shouldHaveReceived('methodName')->with($arg1, $arg2, $arg3);
It will fail every time complaining that the method does not exist on the mock object, the worst part is if I go into my listener where the mock object method is called and I do something like this
echo '<pre>'.print_r(get_class_methods($this->mailer), true).'</pre>'; exit;
it shows that the method is in-fact in the array of methods returned from get_class_methods.
Now here is the kicker. Everything works perfectly and the test passes without any errors if I do the following:
$this->mailer->shouldReceive('methodName');
$model = factory(MyClass::class)->make();
$model->property = 'value';
$model->save()
Now I have been reading the Mockery Gotchas and it would appear that if my class was calling a method that truly didn't exist on the object via ___call then this error would be expected.
However my mailer class is NOT extending any other class that would have a __call method nor does it have that method defined on the class.
However as you may or may not know Eloquent Models do in-fact use the magic ___call method. However I am NOT mocking the model with Mockery, I am using factory models in Laravel but I am also not checking the model object for the method call, I am checking my concrete mailer class for the method call.
Anyone know why I might be getting this behavior from Mockery?
I am creating my mock object in Laravel 5.2 with the following code
public function mock($class)
{
$mock = Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock;
}
$this->mailer = $this->mock('Namespace\Classname');
How are you creating $this->mailer? In order to be able to use the spy functionality ->shouldHaveReceived, you need to have invoked Mockery::spy($className) or called the shouldIgnoreMissing method after creating the test double with Mockery::mock($className).

ZF2: Attach event to another Controller's Action and get Service Locator

I am new to Zend Framework 2. I have two modules 'A' and 'B'. I trigger an event in LoginController's LoginAction of "A" module. I want to attach LoginController's LoginAction or LoginController's testMe() method.
In "A" module's LoginController's LoginAction, I have written
$this->getEventManager()->trigger('checkme.post', null, array('user_id' => $userData->usydstudentid));
In Module.php of "B" module, in on Bootstrap method, I have given
$loginController = new B\Controller\LoginController();
$sharedEventManager->attach('A\Controller\LoginController', 'checkme.post', array($loginController, 'LoginAction'), 100);
In LoginController's LoginAction of "B" module, I can access data but I can not access service manager in order to get module' config. When I try to use
$this->getServiceLocator()->get('Config');
I get error
Call to a member function get() on a non-object
In other words, I want to trigger an event from one controller's method and attach to another controller's method. After listening, getting data from that event, I want to get module's config. Please help in this regard.
First of all, you shouldn't use events and controllers this way. Your controller from B isn't a controller, but you should put that one rather in a service layer.
Then, the service locator must be injected. If you do $controller = new SomeController this service locator is not injected. Thus, fetching any object from it will fail. What you should do is using the controller loader to get the controller.
So instead of this:
$loginController = new B\Controller\LoginController();
$sharedEventManager->attach('A\Controller\LoginController',
'checkme.post',
array($loginController, 'LoginAction'),
100);
You should write this:
// $sl is instance of Service Locator
// E.g. $sl = $e->getApplication()->getServiceManager();
// Where $e is the event from the onBootstrap() method
$loader = $sl->get('ControllerLoader');
$loginController = $loader->get('B\Controller\LoginController');
$sharedEventManager->attach('A\Controller\LoginController',
'checkme.post',
array($loginController, 'LoginAction'),
100);
But as said, triggering an action in a controller this way with events isn't realy a good way to do it. You better dispatch it with for example the controller plugin Forward or (as I said it before), remove the logic from the controller's LoginAction and locate it in a service class or something.

Resources