Application Events
Application Events Overview
Concrete CMS events let you add functionality to existing processes without altering the core.
Examples
Deleting a Page Type with Extra Information: Instead of modifying
Page::delete()
inConcrete\Core\Page\Page
, use Concrete's delete page event to also remove associated information from an extra database table.Integrating with Third Party Authentication: For actions like adding a user, instead of altering the codebase, hook into Concrete's "Add User" event to trigger custom code in your third-party system through an API.
Use Concrete's Events System to implement such custom functionalities.
Hooking into Application Events
Application-Level
Add custom code to application/bootstrap/app.php
for use on the current website without packaging.
In a Package
In a Package, add event hooking code to the on_start()
method in controller.php
. This integrates the event early in Concrete's bootstrapping and ensures it's active only when the package is installed.
Import the Events Class
In a package controller, import the Events
class:
use Concrete\Core\Support\Facade\Events;
At the application level, importing Events
is not needed.
Code Example
Example to log when a user is added:
Events::addListener('on_user_add', function($event) {
$user = $event->getUserInfoObject();
\Log::info(sprintf('Added user %s', $user->getUserName()));
});
Pass the event and a closure to Events::addListener
. The closure receives an Event object, whose type varies based on the event. For on_user_add
, it works with Concrete\Core\User\Event\UserInfoWithPassword.
Example: Changing a Page's Location Based on its Date
Automatically structure blog post URLs based on date, like /blog/2016/03/hello-world
instead of /blog/hello-world
, using page events.
Create a custom handler class instance to place posts correctly:
$handler = new \Path\To\My\Custom\PageHandler();
Hook into three events:
On Page Type Publish: When a page type is published.
\Concrete\Core\Support\Facade\Events::addListener('on_page_type_publish', function($event) use ($handler) { $page = $event->getPageObject(); if ($page->getPageTypeHandle() == 'blog_entry') { $handler->placePost($page); } });
On Page Version Approve: When a new page version is approved, possibly with a new URL slug.
\Concrete\Core\Support\Facade\Events::addListener('on_page_version_approve', function($event) use ($handler) { $page = $event->getPageObject(); if ($page->getPageTypeHandle() == 'blog_entry' && $page->isPageDraft()) { $handler->placePost($page); } });
On Page Move: To recalculate paths when a blog entry is moved.
\Concrete\Core\Support\Facade\Events::addListener('on_page_move', function($event) use ($handler) { $page = $event->getPageObject(); if ($page->getPageTypeHandle() == 'blog_entry') { $parent = $event->getOldParentPageObject(); $handler->cleanPostParent($parent); } });
Registering and Executing Your Own Events
Create custom events in your add-on to allow extension by other developers. For instance, in an eCommerce add-on, when a product is added:
class Product
{
public static function add($productName)
{
$product = new Product();
$product->setName($productName);
return $product;
}
}
public function add_product()
{
$product = Product::add($this->request->request->get('productName'));
}
public static function add($productName)
{
$product = new Product();
$product->setName($productName);
$event = new \Symfony\Component\EventDispatcher\GenericEvent();
$event->setArgument('product', $product);
\Events::dispatch('on_product_add', $event);
return $product;
}
Hook into the event like this:
Events::addListener('on_product_add', function($event) {
$product = $event->getArgument('product');
// Custom operations with product object
});
Custom Event Objects
You can use the Symfony\Component\EventDispatcher\GenericEvent
for simplicity, but for more specific needs, create a custom event object extending Symfony\Component\EventDispatcher\Event
(use Symfony\Contracts\EventDispatcher\Event
for version 9):
namespace My\Application;
use Symfony\Component\EventDispatcher\Event as AbstractEvent;
class ProductEvent extends AbstractEvent
{
protected $product;
public function getProduct()
{
return $this->product;
}
public function setProduct(Product $product)
{
$this->product = $product;
}
public function __construct(Product $product)
{
$this->setProduct($product);
}
}
Then, use this custom event object:
public static function add($productName)
{
$product = new Product();
$product->setName($productName);
$event = new ProductEvent($product);
\Events::dispatch('on_product_add', $event);
return $product;
}
Events::addListener('on_product_add', function($event) {
$product = $event->getProduct();
// Custom operations with product object
});
Halting Execution Based on Events
You can stop further execution in Concrete CMS using event objects. For instance, the on_before_user_add
event allows you to halt user addition:
Events::addListener('on_before_user_add', function($event) {
$data = $event->getData();
if ($data['uName'] == 'andrew') {
$event->cancelAdd(); // Prevents adding users named 'andrew'
}
});
The cancelAdd()
method in the Concrete\Core\User\Event\AddUser event sets $proceed
to false. If $proceed
is false, Concrete's core code stops the add operation.
Full List of Events
Application Level
Event | Description | Event Class Argument |
---|---|---|
on_start |
Run when a Concrete rendering session is started | Generic Event |
on_before_dispatch |
Runs aofter Concrete starts, but before the current request is dispatched | None |
on_before_render |
Run right before a view is to be rendered | Generic Event |
on_render_complete |
Run when a render is complete | Generic Event |
on_shutdown |
Run when Concrete shuts down | None |
on_cache_flush |
Run when the cache is cleared | None |
on_before_console_run |
Run when Concrete is run from the command line | None |
on_after_console_run |
Run after Concrete is run from the command line | None |
on_entity_manager_configure |
Runs when the entity manager is first created by the database connection | Generic Event |
on_locale_load |
Runs when an active locale is set | Generic Event |
on_locale_add |
Runs when a locale is added | Generic Event |
on_locale_delete |
Runs when a locale is deleted | Generic Event |
on_locale_change |
Runs when a locale is changed | Generic Event |
on_logger_create |
Runs when the logger is created | Concrete\Core\Logging\Event |
on_header_required_ready |
Runs when the header is rendered | Generic Event |
Pages
Event | Description | Event Class Argument |
---|---|---|
on_page_view |
Run when a user visits a page | Concrete\Core\Page\Event |
on_get_page_wrapper_class |
Run when a page is rendered (9.1.2+) | Generic Event |
on_page_output |
Run when a page is output to a visitor | Generic Event |
on_page_add |
Run when a page is added | Concrete\Core\Page\Event |
on_page_get_icon |
Run when an icon is retrieved for a page in the sitemap | Concrete\Core\Page\Event |
on_page_update |
Run when a page is updated | Concrete\Core\Page\Event |
on_page_delete |
Run when a page is about to be deleted | Concrete\Core\Page\DeletePageEvent |
on_page_move |
Run when a page is moved | Concrete\Core\Page\MovePageEvent |
on_page_display_order_update |
Run when the display order of a page changes (8.5.0+) | Concrete\Core\Page\DisplayOrderUpdateEvent |
on_page_duplicate |
Run when a page is duplicated | Concrete\Core\Page\DuplicatePageEvent |
on_page_move_to_trash |
Run when a page is moved to the trash but not yet deleted | Concrete\Core\Page\Event |
on_page_not_found |
Run when a page is not found | None |
on_compute_canonical_page_path |
Run when a page's canonical path is computed | Concrete\Core\Page\PagePathEvent |
on_multilingual_page_relate |
Run when a multilingual page is related to another | Concrete\Core\Multilingual\Page\Section\Event |
Page Types
Event | Description | Event Class Argument |
---|---|---|
on_page_type_publish |
Run when a page of a certain type is published | Concrete\Core\Page\Type\Event |
on_page_type_save_composer_form |
Run when a page type composer form is saved | Concrete\Core\Page\Type\Event |
Page Version
Event | Description | Event Class Argument |
---|---|---|
on_page_version_add |
Run when a new page version is created | Concrete\Core\Page\Collection\Version\Event |
on_page_version_approve |
Run when a particular page version is approved | Concrete\Core\Page\Collection\Version\Event |
on_page_version_submit_approve |
Run when a particular page version is submitted for approval | Concrete\Core\Page\Collection\Version\Event |
on_page_version_deny |
Run when a page version is denied approval | Concrete\Core\Page\Collection\Version\Event |
Files
Event | Description | Event Class Argument |
---|---|---|
on_file_add |
Run when a file is added | Concrete\Core\File\Event\FileVersion |
on_file_set_password |
Run when a file password is set | Concrete\Core\File\Event\FileWithPassword |
on_file_download |
Run when a file is downloaded | Concrete\Core\File\Event\FileAccess |
on_file_delete |
Run when a file is deleted fully | Concrete\Core\File\Event\DeleteFile |
on_file_duplicate |
Run when a file is duplicated | Concrete\Core\File\Event\DuplicateFile |
File Versions
Event | Description | Event Class Argument |
---|---|---|
on_file_version_add |
Run when a file version is added | Concrete\Core\File\Event\FileVersion |
on_file_version_deny |
Run when a file version is denied | Concrete\Core\File\Event\FileVersion |
on_file_version_approve |
Run when a file version is approved | Concrete\Core\File\Event\FileVersion |
on_file_version_duplicate |
Run when a file version is duplicated | Concrete\Core\File\Event\FileVersion |
on_file_version_update_title |
Run when a file version's title is updated | Concrete\Core\File\Event\FileVersion |
on_file_version_update_tags |
Run when a file version's tags are updated | Concrete\Core\File\Event\FileVersion |
on_file_version_update_description |
Run when a file version's description is updated | Concrete\Core\File\Event\FileVersion |
on_file_version_update_contents |
Run when a file version's contents are updated | Concrete\Core\File\Event\FileVersion |
File Sets
Event | Description | Event Class Argument |
---|---|---|
on_file_set_add |
Run when a file set is added | Concrete\Core\File\Event\FileSet |
on_file_set_delete |
Run when a file set is deleted (available from version 8.3.3) | Concrete\Core\File\Event\FileSet |
on_file_added_to_set |
Run when a file is added to a set | Concrete\Core\File\Event\FileSetFile |
on_file_removed_from_set |
Run when a file is removed from a set | Concrete\Core\File\Event\FileSetFile |
Blocks
Event | Description | Event Class Argument |
---|---|---|
on_block_load |
Run when a block is loaded for display | Generic Event |
on_block_add |
Run after a block is added | Concrete\Core\Block\Events\BlockAdd |
on_block_edit |
Run after a block is edited | Concrete\Core\Block\Events\BlockEdit |
on_block_delete |
Run after a block is deleted | Concrete\Core\Block\Events\BlockDelete |
on_block_before_render |
Run before a block is rendered (8.4.0+) | Concrete\Core\Block\Events\BlockBeforeRender |
on_block_duplicate |
Run after a block is duplicated (8.4.0+) | Concrete\Core\Block\Events\BlockDuplicate |
on_block_output |
Run just before a block is outputted (8.4.1+) | Concrete\Core\Block\Events\BlockOutput |
Express
Event | Description | Event Class Argument |
---|---|---|
on_express_entry_saved |
Run when an express entry is saved. | Concrete\Core\Express\Event\Event |
Users
Event | Description | Event Class Argument |
---|---|---|
on_before_user_add |
Run before a user is added | Concrete\Core\User\Event\AddUser |
on_user_add |
Run when a user is added | Concrete\Core\User\Event\UserInfoWithPassword |
on_user_update |
Run when a user is updated | Concrete\Core\User\Event\UserInfo |
on_user_change_password |
Run when a user's password is changed | Concrete\Core\User\Event\UserInfoWithPassword |
on_user_delete |
Run before a user delete. | Concrete\Core\User\Event\DeleteUser |
on_user_deleted |
Run when a user is deleted fully (From v8.3.0 ) |
Concrete\Core\User\Event\UserInfo |
on_user_validate |
Run when a user is validated | Concrete\Core\User\Event\UserInfo |
on_user_activate |
Run when a user is activated | Concrete\Core\User\Event\UserInfo |
on_user_deactivate |
Run when a user is deactivated | Concrete\Core\User\Event\UserInfo |
on_user_login |
Run when a user logs in | Concrete\Core\User\Event\User |
on_user_logout |
Run when a user logs out | None |
on_user_attributes_saved |
Run when a user's attributes are saved | Concrete\Core\User\Event\UserInfoWithAttributes |
Private Messages
Event | Description | Event Class Argument |
---|---|---|
on_private_message_marked_not_new |
Run when new status is removed from a mailbox | Concrete\Core\User\Event\UserInfo |
on_private_message_marked_as_read |
Run when a user has read a private message | Concrete\Core\User\PrivateMessage\Event |
on_private_message_delete |
Run when a user deletes a private message | Concrete\Core\User\PrivateMessage\Event |
on_private_message_over_limit |
Run when a user has tripped private message sending limits | Concrete\Core\User\Event\UserInfo |
User Groups
Event | Description | Event Class Argument |
---|---|---|
on_group_add |
Run when a group is added | Concrete\Core\User\Group\Event |
on_group_update |
Run when a group is updated | Concrete\Core\User\Group\Event |
on_group_delete |
Run when a group is deleted | Concrete\Core\User\Group\DeleteEvent |
on_user_enter_group |
Run when a user enters a group | Concrete\Core\User\Event\UserGroup |
on_user_exit_group |
Run when a user exits a group | Concrete\Core\User\Event\UserGroup |
Conversations
Event | Description | Event Class Argument |
---|---|---|
on_new_conversation_message |
Run when a conversation message is added | Concrete\Core\Conversation\Message\MessageEvent |
Jobs
Event | Description | Event Class Argument |
---|---|---|
on_job_install |
Run when a job is installed | Concrete\Core\Job\Event |
on_job_uninstall |
Run when a job is uninstalled | Concrete\Core\Job\Event |
on_before_job_execute |
Runs before a job is executed | Concrete\Core\Job\Event |
on_job_execute |
Runs when a job is executed | Concrete\Core\Job\Event |
Miscellaneous
Event | Description | Event Class Argument |
---|---|---|
on_get_countries_list |
Runs when the country list is retrieved for use | Generic Event |
on_get_states_provinces_list |
Runs when the states/provinces are retrieved | Generic Event |
on_sitemap_xml_ready |
Runs when the generate sitemap job's XML is ready | Concrete\Core\Page\Sitemap\EventXmlReadyEvent |
on_sitemap_xml_addingpage |
Runs when the generate sitemap job adds a page | Generic Event |
on_page_feed_output |
Runs when an RSS feed is output | Concrete\Core\Page\FeedEvent |
on_form_submission |
Runs when a form block is submitted | Generic Event |