Easystore XTD Plugin Group
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.
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 |
|
|
Before payment display |
|
|
|
On successful payment |
|
|
|
When payment is complete |
|
|
|
On payment cancellation |
|
|
|
On payment error |
|
|
|
After payment display |
|
|
|
Update cart data before cart view render |
|
|
|
Update checkout data before checkout view render |
|
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);
}
}