1. Overview
The Easystore XTD plugin group extends EasyStore functionality with custom content integration and enhancements. These plugins utilize Joomla’s modern plugin architecture, service providers, and event-driven patterns to create flexible and maintainable extensions.
Download Sample Plugin
Prerequisites
Before proceeding, ensure that you have the following:
- Basic knowledge of PHP and Joomla CMS.
- EasyStore is installed and configured on your Joomla site.
Getting Started
- Download the provided sample plugin from the documentation.
- Extract the downloaded file and open it in your preferred code editor.
- Familiarize yourself with the structure of the plugin files.
2. Plugin Group Structure
When creating a new plugin, follow the directory structure below. It ensures consistency and seamless integration with EasyStore.

1. [plugin-name].xml
- Defines the plugin metadata (name, version, author).
- Lists all files used in the plugin.
- Declares language files and parameters.
2. services/provider.php
- Registers your plugin's service provider.
- Ensures event handling is properly hooked into EasyStore.
3. src/Extension/[PluginName].php
- Main plugin class file.
- Implements event subscriptions and logic.
4. language/[lang-tag]/
- Stores language files for localization.
plg_easystore-xtd_[plugin-name].ini: Main translation strings.
plg_easystore-xtd_[plugin-name].sys.ini: Backend system messages.
3. Event System
3.1 Supported Events
Easystore XTD plugins respond to the following events:
|
Event Name
|
Description
|
Parameters
|
|
onEasystorePaymentBeforeDisplay
|
Before payment display
|
subject, view
|
|
onEasystorePaymentSuccessRender
|
On successful payment
|
subject, paymentType, orderId
|
|
onEasystorePaymentComplete
|
When payment is complete
|
subject, paymentType, orderId
|
|
onEasystorePaymentCancel
|
On payment cancellation
|
subject, orderId
|
|
onEasystorePaymentError
|
On payment error
|
subject, orderId
|
|
onEasystorePaymentAfterDisplay
|
After payment display
|
subject, view
|
3.2 Event Handler Implementation
Each plugin must implement SubscriberInterface and define the subscribed events:
public static function getSubscribedEvents(): array
{
return [
'onEasystoreCartBeforeRender' => 'onEasystoreCartBeforeRender',
// Add additional events here
];
}
4. Plugin Development
Step 1: Create Plugin Directory
mkdir -p plugins/easystore-xtd/[plugin-name]
- Create the folder structure for your plugin under
plugins/easystore-xtd/.
[plugin-name] is your actual plugin name.
Step 2: Create Plugin Manifest ([plugin-name].xml)
<?xml version="1.0" encoding="utf-8"?>
<extension method="upgrade" type="plugin" group="easystore-xtd">
<name>PLG_EASYSTOREXTD_[PLUGINNAME]</name>
<version>1.0.0</version>
<description>PLG_EASYSTOREXTD_[PLUGINNAME]_DESCRIPTION</description>
<author>Your Name</author>
<namespace path="src">YourVendor\Plugin\EasyStoreXtd\[PluginName]</namespace>
<files>
<folder plugin="[plugin-name]">services</folder>
<folder>src</folder>
<folder>language</folder>
</files>
</extension>
- This XML file tells Joomla about your plugin.
- It includes:
- Name and description
- Version number
- Author information
- Namespace location for your code
- Files and folders that belong to the plugin
- Joomla reads this file during installation or upgrade.
Step 3: Create Service Provider (services/provider.php)
<?php
namespace YourVendor\Plugin\EasyStoreXtd\[PluginName]\Service;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use YourVendor\Plugin\EasyStoreXtd\[PluginName]\Extension\[PluginName];
return new class () implements ServiceProviderInterface
{
public function register(Container $container)
{
$container->set(
PluginInterface::class,
function (Container $container) {
$dispatcher = $container->get(DispatcherInterface::class);
$plugin = new [PluginName](
$dispatcher,
(array) PluginHelper::getPlugin('easystore-xtd', '[plugin-name]')
);
return $plugin;
}
);
}
};
Step 4: Create Main Plugin Class (src/Extension/[PluginName].php)
<?php
namespace YourVendor\Plugin\EasyStoreXtd\[PluginName]\Extension;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\DispatcherInterface;
use Joomla\Event\Event;
use Joomla\Event\SubscriberInterface;
class [PluginName] extends CMSPlugin implements SubscriberInterface
{
protected $autoloadLanguage = true;
public static function getSubscribedEvents(): array
{
return [
'onEasystorePaymentComplete' => 'onPaymentComplete',
// Add other events as needed
];
}
public function onPaymentComplete(Event $event)
{
$subject = $event->getArgument('subject');
$paymentType = $event->getArgument('paymentType');
$orderId = $event->getArgument('orderId');
// Your custom logic here
$event->setArgument('subject', $subject);
}
}
5. Configuration and Parameters
Access plugin parameters in your plugin class:
$enableLogging = $this->params->get('enable_logging', 1);
$customMessage = $this->params->get('custom_message', 'Default message');
6. Debugging and Logging
6.1 Built-in Logging (Example Custom Plugin)
$this->logPaymentActivity('custom_action', [
'order_id' => $orderId,
'data' => $customData
]);
6.2 Debug Mode
- Go to System > Global Configuration > System
- Set Debug System to Yes
- Check the debug console for detailed event information
7. Best Practices
1. Event Naming
- Use descriptive names
- Prefix with plugin name
- Follow onEasystore[Action][When] pattern
2. Error Handling
try {
// Your code
} catch (\Exception $e) {
$this->logPaymentActivity('error', [
'message' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
}
3. Performance Optimization
- Cache expensive operations
- Minimize database queries
4. Security
- Validate inputs
- Sanitize outputs
- Use Joomla input filtering
- Follow Joomla security guidelines
8. Testing
8.1 Unit Testing
class [PluginName]Test extends \PHPUnit\Framework\TestCase
{
public function testEventHandler()
{
// Test your event handlers
}
}
8.2 Integration Testing
- Install the plugin
- Trigger EasyStore events
- Verify expected behavior
9. Deployment
9.1 Installation
- Package plugin as a ZIP file
- Install via Joomla Extension Manager
- Enable the plugin
9.2 Updates
- Follow semantic versioning
- Include update SQL if required
- Test in a staging environment
10. Resources
11. Example: Custom Payment Gateway Integration
public function onEasystorePaymentComplete(Event $event)
{
$subject = $event->getArgument('subject');
$paymentType = $event->getArgument('paymentType');
$orderId = $event->getArgument('orderId');
if ($paymentType === 'custom_gateway') {
$this->processCustomGateway($orderId, $subject);
}
}