How To Get Data From A Custom Event In Magento - magento

I have an observer module that I have written for Magento. It simply monitors an event called mgd_order_prep which is triggered by a custom dispatcher like this:
Mage::dispatchEvent("mgd_order_prep", array('orderdata' => $order));
$order is simply a magento sales/order object.
My event fires and my function in the proper class executes:
function updateOrderPrepPDF($observer)
{
Mage::log("Update Order Prep",null,'orderprep.log');
Mage::log($observer->getOrderdata(),null,'orderprep.log');
}
I see what I should after the first log event, but I dont see ANYTHING for when I try to output the order data (it outputs blank - or null).
How do I get the data I pass in at the dispatch event out at the execution point?

You can directly get Data using getData() method :
function updateOrderPrepPDF($observer)
{
Mage::log(print_r($observer->getData(),true),null,'orderprep.log');
}
Check this log inside var/log directory.
Try this code and let me know if you still have any query.

Related

Calling of afterSave method in application.php file slowing down complete platform and showing memory_limit exceed error

I am calling afterSave method in application.php to perform action on all models saving event. Issue is whenever I using SAVE method inside afterSave method application showing fatal error:
SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
Point is same method working fine in specific model, without any memory exhausted error, I think there is something that need to be fixed over database connection. Below is the code which one I am trying.
//Application.php file
namespace App;
...
...
\Cake\Event\EventManager::instance()->on(
'Model.afterSave',
function (
\Cake\Event\EventInterface $event,
\Cake\Datasource\EntityInterface $entity,
\ArrayObject $options
) {
$auth_data = isset($_SESSION['Auth'])?$_SESSION['Auth']:[];
$ActionLogs = TableRegistry::get('ActionLogs');
$ActionLogsEntity = $ActionLogs->newEmptyEntity();
$ActionLogsEntity->change_log = $change_log;
$ActionLogsEntity->action_taken_by = $auth_data->username;
$ActionLogs->save($ActionLogsEntity); //This statement working fine in specific modelTable
class Application extends BaseApplication
implements AuthenticationServiceProviderInterface
{
...
...
}
Aside from the fact that the code should go into the Application class' bootstrap() method as mentioned in the comments, when you save inside of an afterSave event that listens to all models, then you naturally create a recursion, as saving the log will trigger an afterSave event too.
You have to put a safeguard in place that prevents the logging logic from running when the afterSave event belongs to the logging model, for example:
if ($event->getSubject() instanceof \App\Model\Table\ActionLogsTable) {
return;
}
// ...

How to create custom event for updating Query state?

I am trying to create a custom event for Query to reload and refresh the query state when the event happens.
I need a custom event similar to Spartacus' OrderPlacedEvent. My custom event actually works, but the time when
HTTP call for reloading query state is triggered is not right. Instead of firing an HTTP call when I visit the quotes page,
it happens immediately when the event is dispatched on the second step during the checkout process.
Creating event class QuotePlacedEvent:
export abstract class QuoteEvent extends CxEvent {
userId?: string;
activeCartId?: string;
}
export class QuotePlacedEvent extends QuoteEvent {
static readonly type = 'QuotePlacedEvent';
quote: any;
}
Dispatching the event during the checkout process when a quote is created for example on the second step:
this.eventService.dispatch(
{
userId: payload.userId,
activeCartId: payload.cartId,
quote: cart,
},
QuotePlacedEvent);
Quote query called when Quotes page is visited:
protected quotesQuery: Query<any> = this.query.create(() =>
this.userIdService
.getUserId()
.pipe(switchMap(userId => this.quoteConnector.getQuotes(userId))),
{
reloadOn: [LanguageSetEvent, QuotePlacedEvent],
resetOn: [LogoutEvent, LoginEvent],
}
);
getQuotesAndApplication(): Observable<any> {
return this.quotesQuery.get();
}
I saw method in ProfileTagPushEventsService orderConfirmationPageVisited() which listens to OrderPlacedEvent. Do I need that implementation too:
/**
* Listens to QuotePlacedEvent events
*
* #returns observable emitting events that describe order confirmation page visits in a profiltag compliant way
* #see QuotePlacedEvent
* #see QuoteConfirmationPushEvent
*/
quoteConfirmationPageVisited(): Observable<ProfileTagPushEvent> {
return this.eventService
.get(QuotePlacedEvent)
.pipe(map(item => new QuoteConfirmationPushEvent(item)));
}
I wanted to add my custom event by calling the method addPushEvent from ProfileTagPushEventsService, but I can't import it, since it is not exported.
Any idea what am I missing and why the custom event doesn't behave in an expected way?
The query is always "listening" for the events you tell it to listen to, and if you fire the event in the 2nd checkout step, query will react to it. This is by design.
If you need the query to react to an event which happens when you visit the quotes page, you can try to create the QuotesPageEvent, make the query listen to it, and dispatch it once the user actually navigates to the quotes page. You can see an example of a page event here.
Maybe one improvement you can do, is to make sure the that quotes have been placed before dispatching the page event. For this, you can use the power of rxjs to listen to your QuotePlacedEvent and the page visited event, and fire a final event. The quire should be listening to this final event.

Magento - catalog_product_save_after: Check if product has been saved

I am currently trying to save a product with attributes that I have built, and it's working fine. I have also set up my code to call the catalog_product_save_after function on my observer, as shown below:
class Package_MyModule_Model_Observer
{
public function catalog_product_save_after($observer)
{
$product = $observer->getProduct();
//Do stuff here
}
}
In this line of code here, is there a way to detect whether the product has already been saved (i.e. no error messages were shown)? Because I need to update some values in the database when the product is saved successfully.
Mostly this gets called after product is saved successfully, but to be sure you can hook into
catalog_product_save_commit_after

symfony2 my own event

I made the authorization and authentication via facebook like here:
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
and it works
Now I want to make my own event, this event will do something when the user authenticates using facebook. For example-will redirect the user to the home page.
I did it like this
http://symfony.com/doc/current/components/event_dispatcher/introduction.html
So I have this class
http://pastebin.com/2FTndtL4
I do not know how to implement it, what am I supposed to pass as an argument to the constructor
It's really simple. Symfony 2 event system is powerful, and service tags will do the job.
Inject the dispatcher into the class where you want to fire the event. The service id is event_dispatcher;
Fire the event with $this->dispatcher->dispatch('facebook.post_auth', new FilterFacebookEvent($args)) when needed;
Make a service that implements EventSubscriberInterface, defining a static getSubscribedEvents() method. Of course you want to listen to facebook.post_auth event.
So your static method will look like:
static public function getSubscribedEvents()
{
return array(
'facebook.post_auth' => 'onPostAuthentication'
);
}
public function onPostAuthentication(FilterFacebookEvent $event)
{
// Do something, get the event args, etc
}
Finally register this service as a subscriber for the dispatcher: give it a tag (eg. facebook.event_subscriber), then make a RegisterFacebookEventsSubscribersPass (see this tutorial). You compiler pass should retrieve all tagged services and inside the loop should call:
$dispatcher = $container->getDefinition('event_dispatcher');
$subscribers = $container->findTaggedServiceIds('facebook.event_subscriber');
foreach($subscribers as $id => $attributes) {
$definition->addMethodCall('addSubscriber', array(new Reference($id)));
}
This way you can quick make a subscriber (for logging, for example) simply tagging your service.
Event object is just some kind of state/data storage. It keeps data that can be useful for dispatching some kind of events via Subscribers and/or Listeners. So, for example, if you wanna pass facebook id to your Listener(s) - Event is the right way of storing it. Also event is the return value of dispatcher. If you want to return some data from your Listener/Subscriber - you can also store it in Event object.

Magento: Obtain Id for order, listening to the event checkout_onepage_controller_success_action

When I look at the event checkout_onepage_controller_success_action and works, but I can not get the Id of the newly created order.
Anyone have any idea??
Use magento-1.4.1.0
Thanks
The event is dispatched like this:
Mage::dispatchEvent('checkout_onepage_controller_success_action', array('order_ids' => array($lastOrderId)));
So to get the last orderId, simply make your observer method like this:
public function orderSuccessEvent($observer)
{
$observer->getData('order_ids'));
}
This is an answer provided by Branko Ajzele and I've just successfully tested:
$order = new Mage_Sales_Model_Order();
$incrementId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$order->loadByIncrementId($incrementId);
Thanks to him and hope it'll work.
That event probably gets called before the action itself executes. Can you use sales_order_save_after instead?
EDIT: Here's your ID code. In your observer:
public function setLinkStatus($observer) {
$order = $observer->getEvent()->getOrder();
$id = $order->getId();
// do something useful
}
The Onepage Checkout controller in the Magento version 1.4.1 is not updated to have functions that can obtain the Order ID and thus you cant have the order object and data from the event observer. To have this working in Magento 1.4.1 simply update your OnepageController with the necessary functions.
The best approach would be to create your own module and override the core controller.
Add this in the config xml of your module so that your controller is called before the core OnepageController.
<frontend><routers><checkout><use>standard</use><args><modules><MyCompany_MyModule before="Mage_Checkout">MyCompany_MyModule</MyCompany_MyModule></modules></args></checkout></routers></frontend>
Hope this helps

Resources