Custom Joomla Plugin Development
Imagine: your client asks to add article synchronization with CRM upon publication. Or you need to integrate an external OAuth provider for user login. Basic Joomla tools cannot do that — a custom plugin is needed. Experience shows that ready-made extensions do not cover specific integrations, and a custom plugin solves the task 3 times faster than adapting a ready-made component. We develop plugins for any events: from content processing to authentication. Over 7 years we have implemented 30+ plugins for Joomla 3, 4, and 5, using modern APIs and Joomla! Documentation: Plugin Development.
What problems we solve
Standard Joomla extensions are limited. For example, when saving an article, you cannot automatically send data to an external system. Or when a user logs in, you cannot verify them through corporate LDAP. Plugins intercept lifecycle events of the CMS and execute their logic without core modifications.
We have encountered typical difficulties:
- N+1 queries when synchronizing large volumes of content. Solution: aggregate data into a single query, use batch processing.
- Conflicts with Joomla caching. A plugin that calls an external API on every page load can slow down the site. Solution: cache responses in Redis or move heavy operations to background tasks (Joomla Task Scheduler).
- Errors when updating Joomla. Deprecated APIs cause 500 errors. Solution: support only Joomla 4 and 5, use modern events and DI.
How we do it?
Stack: PHP 8.1+, MySQL 8, Redis (optional). For authentication — OpenID Connect, OAuth 2.0. For integrations — REST, SOAP, GraphQL.
Approach: we use SubscriberInterface and Joomla DI container. Code is covered with unit tests (PHPUnit). Result — a stable plugin ready for production.
Workflow diagram
Architecture design, coding, testing on Joomla 4 and 5, deployment. More details in the steps below.Case study: we recently implemented a plugin for a pharmacy chain on Joomla 5. It synchronizes prices and stock with 1C via REST API. Processing 2000 products in 10 minutes, 0 errors over a month of operation.
Plugin structure
Joomla plugins react to system events. They intercept lifecycle moments: before/after article save, during authentication, search, form submission. This is the most correct way to extend system behavior without core modification.
Plugin groups
| Group | Event | Application |
|---|---|---|
| content | onContentBeforeSave, onContentAfterSave | Content processing |
| user | onUserLogin, onUserAfterSave | Authentication, synchronization |
| system | onAfterRoute, onBeforeRender | Global intercepts |
| authentication | onUserAuthenticate | External login providers |
| finder | onFinderIndexItem | Smart Search index |
| task | onExecuteTask | Task scheduler (Joomla 4+) |
Plugin file structure
plg_content_synccrm/
└── plg_content_synccrm.php # Entry point (legacy)
└── plg_content_synccrm.xml # Manifest
└── services/
└── provider.php # DI Provider
└── src/
└── Extension/
└── SyncCrmPlugin.php # Main class
Manifest
<?xml version="1.0" encoding="utf-8"?>
<extension version="4.0" type="plugin" group="content">
<name>plg_content_synccrm</name>
<author>Your Company</author>
<version>1.0.0</version>
<description>Синхронизация контента с CRM при публикации</description>
<namespace path="src">MyCompany\Plugin\Content\SyncCrm</namespace>
<files>
<filename plugin="plg_content_synccrm">plg_content_synccrm.php</filename>
<folder>services</folder>
<folder>src</folder>
</files>
<config>
<fields name="params">
<fieldset name="basic">
<field name="crm_api_url" type="text" label="URL CRM API" />
<field name="crm_api_key" type="password" label="API Key CRM" />
<field name="sync_types" type="checkboxes" label="Синхронизировать типы">
<option value="article">Статьи</option>
<option value="product">Товары</option>
</field>
</fieldset>
</fields>
</config>
</extension>
How to create a Joomla plugin for a task?
Development steps:
- Determine the event group (content, user, system, or other).
- Create the manifest, DI provider, and main class with event subscription.
- Implement the event handling logic — send to CRM, token verification, external API call.
- Configure plugin parameters via XML form (URL, keys, flags).
- Test on Joomla 4 and 5, cover with unit tests.
Example of the main class code:
// src/Extension/SyncCrmPlugin.php
namespace MyCompany\Plugin\Content\SyncCrm\Extension;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\Event;
use Joomla\Event\SubscriberInterface;
class SyncCrmPlugin extends CMSPlugin implements SubscriberInterface {
public static function getSubscribedEvents(): array {
return [
'onContentAfterSave' => 'syncToCrm',
];
}
public function syncToCrm(Event $event): void {
[$context, $article, $isNew] = array_values($event->getArguments());
if ($context !== 'com_content.article') return;
if ((int) $article->state !== 1) return;
$syncTypes = $this->params->get('sync_types', []);
if (!in_array('article', (array) $syncTypes)) return;
try {
$this->sendToCrm([
'type' => 'article',
'external_id'=> $article->id,
'title' => $article->title,
'url' => \Joomla\CMS\Router\Route::link('site', 'index.php?option=com_content&view=article&id=' . $article->id),
'published' => (bool) $article->state,
'updated_at' => $article->modified,
]);
} catch (\Exception $e) {
$this->getApplication()->getLogger()->error('CRM sync failed: ' . $e->getMessage());
}
}
private function sendToCrm(array $data): void {
$apiUrl = rtrim($this->params->get('crm_api_url'), '/') . '/articles';
$apiKey = $this->params->get('crm_api_key');
$http = \Joomla\CMS\Factory::getContainer()
->get(\Joomla\Http\HttpFactory::class)
->getHttp();
$response = $http->post($apiUrl, json_encode($data), [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $apiKey,
]);
if ($response->code >= 400) {
throw new \RuntimeException('CRM API error: ' . $response->code);
}
}
}
What is included in the work?
| Stage | Result |
|---|---|
| Analysis | Event description, integration requirements |
| Design | Architecture, configuration, error handling |
| Implementation | Plugin code, manifest, configuration parameters |
| Testing | Unit tests, Joomla integration |
| Documentation | Installation, configuration, and API instructions |
| Support | 1-year warranty, assistance with Joomla updates |
Additionally, we can set up CI/CD, add caching, implement background tasks.
Timeline and cost
Development of a plugin for one event group — from 2 to 5 days. Examples:
- Synchronization with external API (authorization, batch sending) — 3 days.
- Authentication plugin via SSO (OAuth, LDAP) — 5 days.
- Simple content handler (filtering, modification) — 2 days.
We provide an accurate estimate after analyzing your task. Cost is calculated individually.
Typical mistakes in Joomla plugin development
- Using deprecated classes (JFactory, JDatabase instead of DI).
- Improper caching handling — plugin executes on every request, slowing the site.
- Lack of exception handling — critical error crashes the entire site.
- Tight coupling to a single Joomla version without considering compatibility.
We account for these risks at the design stage.
Why choose us?
- 7+ years of experience in Joomla development.
- 30+ implemented plugins for different versions.
- Certified Joomla developers.
- 12-month code warranty.
- Full support: from idea to production.
Get a consultation on your project. We will assess the task and offer the optimal solution in the shortest possible time.







