LemonStand Documentation

Handling LemonStand events

Handling LemonStand events allows you to override or extend standard functionality of the application in many ways. For example, you can extend existing LemonStand models (customers, products etc), customize visitors shopping experience, execute some code before a front-store page is displayed and do other things. The list of events is growing constantly. Please contact us if you need to handle some event which is not listed below.

Handling events

To handle LemonStand events you need to develop a simple module. The process of developing LemonStand modules is described in this article. A simplest module can have only two files - the module information class and the module version information file. Event handlers can be defined in the module information class. To subscribe to system events use the subscribeEvents() method of the module information class. For example:

public function subscribeEvents()
{
  Backend::$events->addEvent('shop:onNewOrder', $this, 'on_new_order');
}

The code subscribes a module information class to the shop:onNewOrder event. When it is triggered the on_new_order method (specified in the third parameter) will be called. This method (event handler) must be defined in the module information class. There are no special rules for event handler function names. Below is an example of the event handler code:

public function on_new_order($order_id)
{
  // Find the order
  $order = Shop_Order::create()->find_by_id($order_id);
  if ($order)
  {
    // Do something with the order object
  }
}

Invoking custom module events from standard LemonStand pages

In some cases you will need to call an event handler in your module from a standard LemonStand page. The custom event solution allows you to trigger any event on some LemonStand pages in order to handle them in your custom module. The feature is supported in all back-end controllers, but implementation for the Products and Orders controllers differs from implementation in other controllers. 

To call an event from your module, trigger a standard AJAX request to the onCustomEvent handler. In the extra POST fields specify the event name you want to be invoked on the server. The event handler should accept 2 parameters - the controller object and the record identifier, which you can use for loading the object from the database. For the Products and Orders controllers the second parameter is the product and order object. Thus, on the Edit Order page the second parameter will be the Shop_Order object, and on the Edit Product page the second parameter will be the Shop_Product object. Example:

// Button on the Order Preview page, which opens a popup window 
// with a content provided by the Subscriptions module
<?= backend_ctr_button('Generate subscription invoice', 'generate_subscription_invoice',
  array('href'=>'#', 'onclick'=>"new PopupForm(
    'onCustomEvent', {
        ajaxFields: {custom_event_handler: 'subscriptions:onGenerateInvoice'}
     }); return false;
")) ?>
  
// Event subscription in the Subscriptions module
public function subscribeEvents()
{
  Backend::$events->addEvent('subscriptions:onGenerateInvoice', $this, 'generate_order_invoice');
}
  
function generate_order_invoice($controller, $order)
{
  $controller->renderPartial(PATH_APP.'/modules/subscriptions/partials/_generate_invoice.htm');
}

List of LemonStand events

Below you will find list of events triggered by different LemonStand modules.

Core module events

Events provided by the LemonStand Core module.

CMS module events

Events provided by the LemonStand CMS module.

Shop module events

Events provided by the LemonStand Shop module. Some events listed below are described in the Extending existing models article.

Order events - extending order model, handling order status change, handling order information change, extending order-related user interface in the Administration Area

Order item events - extending order items, processing order item updates

Customer events - extending the customer model and customer-related user interface in the Administration Area

Product events - extending the product model, product-related user interface in the Administration Area, handling file uploads on the Product Details page on the front-end website.

Product group events  - extending the product group model, product group related user interface in the Administration Area.

Extra option events - extending the product extra option model, extra option-related user interface in the Administration Area.

Product option events - extending the product option model, option-related user interface in the Administration Area.

Product review events -extending the product review model, product review related user interface in the Administration Area .

Category events - extending the product category model and the category-related user interface in the Administration Area

Manufacturer events - extending the manufacturer model and manufacturer-related user interface in the Administration Area

Shopping cart item events - extending the shopping cart item model, handling shopping cart updates

Invoice events - enabling the invoice support, processing invoice items

Shipping method events - altering the shipping cost, etc.

Product search events - extending the product search

Reporting events - extending the reports

List of undocumented events

Documentation for the following events will be added later.

Shop module

  • shop:onBeforeOrdersRssExport
  • shop:onExtendCustomerGroupForm
  • shop:onExtendCustomerGroupModel
  • shop:onExtendCustomerPreviewTabs
  • shop:onExtendOrderPaymentTransactionsToolbar
  • shop:onExtendOrderPreviewHeader
  • shop:onExtendOrderPreviewTabs
  • shop:onExtendOrderStatusForm
  • shop:onExtendOrderStatusModel
  • shop:onExtendProductPreviewHeader
  • shop:onExtendProductPreviewTabs
  • shop:onExtendProductPreviewToolbar
  • shop:onExtendProductTypeForm
  • shop:onExtendProductTypeModel
  • shop:onGetCategoryProductSortingQuery
  • shop:onGetCustomerGroupFieldOptions
  • shop:onGetOrderFieldState
  • shop:onGetProductFieldState
  • shop:onGetProductSortColumns
  • shop:onGetProductTypeFieldOptions
  • shop:onOrderCopyBillingAddress
  • shop:onPrepareProductListData

Core module

  • core:onAfterSoftwareUpdate
  • core:onAfterSoftwareUpdateRequest
  • core:onBeforeArchiveCreate
  • core:onBeforeArchiveRestore
  • core:onBeforeDatabaseConnect
  • core:onBeforeFormRecordCreate
  • core:onBeforeFormRecordDelete
  • core:onBeforeFormRecordUpdate
  • core:onBeforeFormRender
  • core:onBeforeFormRenderPreview
  • core:onBeforeListExport
  • core:onBeforeListRecordDisplay
  • core:onBeforeSoftwareUpdate
  • core:onBeforeSoftwareUpdateRequest
  • core:onExtendUserForm
  • core:onExtendUserModel
  • core:onFileBeforeCreate
  • onFrontEndLogin
  • onLogin

CMS module

  • cms:onEvaluateCode
  • cms:onGetPageContent
  • cms:onGetPageBlockContent
  • cms:onGetPartialContent
  • cms:onGetTemplateContent
  • cms:onAfterRenderPartial
  • cms:onBeforeDataExport
  • cms:onBeforeDataImport
  • cms:onBeforeRenderPartial
  • cms:onExtendPartialForm
  • cms:onExtendPartialModel
  • cms:onExtendTemplateForm
  • cms:onExtendTemplateModel
  • cms:onGetPartialFieldOptions
  • cms:onGetTemplateFieldOptions
  • cms:onListPageEditorSidebarTabs
  • cms:onPreparePageListData
  • cms:onPreparePartialListData
  • cms:onPrepareTemplateListData

Backend module

  • backend:onBeforeRemoteEvent
  • backend:onBeforeRenderPage
  • backend:onBeforeRenderPartial
  • backend:onControllerReady

Next: shop:onExtendCustomerModel event
Previous: Using module access points
Return to Developing LemonStand modules

Comments

Ben

Monday, March 21, 2011

If I wanted to keep my module information file a bit tidy and wanted to move event handler to a separate class file that I initiate on demand, what's the lemonstand way to load and instantiate a separate class?
(sort of like the $this->load->library in codeigniter )

Aleksey Bobkov

Monday, March 21, 2011

@Ben - there is no way to load a class automatically. We usually use a singleton class which is loaded in the subscribeEvents() function. For example:

public function subscribeEvents()
{
$engine = Subscriptions_Engine::get();
Backend::$events->addEvent('cms:onApplyPageSecurity', $engine, 'apply_page_security');
}

In the subscriptions_engine.php:

class Subscriptions_Engine
{
protected static $instance = null;

protected function __construct()
{
}

public static function get()
{
if (self::$instance)
return self::$instance;

return self::$instance = new self();
}
...

Ben

Monday, March 21, 2011

@Aleksey

Thanks.

Does Lemonstand automatically load that Subscriptions_Engine class on demand when it's needed or do I need to specify somewhere that I want to load it?

Aleksey Bobkov

Monday, March 21, 2011

@Ben - it creates the module instance in this line, in the subscribeEvents() method:

$engine = Subscriptions_Engine::get();

The class object is created here and its reference is passed to the addEvent() call. After that the system always uses the same object reference for all subsequent event calls.

Ben

Monday, March 21, 2011

@Aleksey.

Yes, I understand the static call, my question was when is the class itself loaded (ie. source file include) by Lemonstand?

Does lemonstand automatically load up every class that's available in the module's classes folder at initialisation time?

Aleksey Bobkov

Monday, March 21, 2011

@Ben - yes, LemonStand loads class files automatically. You should follow the naming convention explained in the Developing LemonStand modules article (http://lemonstandapp.com/docs/developing_lemonstand_modules/)

Ken

Tuesday, October 25, 2011

Is there any event that gets fired when a product is edited, not sure if i misunderstood one up there but I didn't see it. Basically when an admin updates a product i want to call a function in one of my other controllers.

Thanks,
Ken

Aleksey Bobkov

Tuesday, October 25, 2011

@Ken - there is a couple of non-docummented events which are triggered when a back-end form is saved: core:onAfterFormRecordCreate, core:onAfterFormRecordUpdate. You can find a short description in this forum post:
http://forum.lemonstandapp.com/topic/1456-fireevent-shoponafterproductfileadded-for-backend/page__view__findpost__p__7310

Add your comment

Loading form...