# Adding Custom Services MokoJoomCross uses a plugin-based architecture. Any developer can create a new service plugin. ## Plugin Structure Create a Joomla plugin in the `mokojoomcross` group: ``` plg_mokojoomcross_myservice/ ├── myservice.xml # Plugin manifest (group="mokojoomcross") ├── myservice.php # Legacy stub (empty) ├── src/ │ └── Extension/ │ └── MyserviceService.php # Implements MokoJoomCrossServiceInterface ├── services/ │ └── provider.php # DI container registration └── language/ └── en-GB/ ├── plg_mokojoomcross_myservice.ini └── plg_mokojoomcross_myservice.sys.ini ``` ## Implement the Interface Your Extension class must implement `MokoJoomCrossServiceInterface`: ```php namespace Joomla\Plugin\MokoJoomCross\Myservice\Extension; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Component\MokoJoomCross\Administrator\Service\MokoJoomCrossServiceInterface; use Joomla\Event\SubscriberInterface; class MyserviceService extends CMSPlugin implements SubscriberInterface, MokoJoomCrossServiceInterface { public static function getSubscribedEvents(): array { return ['onMokoJoomCrossGetServices' => 'onMokoJoomCrossGetServices']; } public function onMokoJoomCrossGetServices(&$services): void { $services[] = $this; } public function getServiceType(): string { return 'myservice'; } public function getServiceName(): string { return 'My Service'; } public function getMaxLength(): int { return 500; } public function supportsMedia(): bool { return true; } public function publish(string $message, array $media, array $credentials, array $params): array { // Your API integration here return ['success' => true, 'platform_post_id' => '...', 'response' => [...]]; } public function validateCredentials(array $credentials): array { return ['valid' => true, 'message' => 'OK', 'account_name' => '...']; } } ``` ## Required Methods | Method | Returns | Purpose | |--------|---------|---------| | `getServiceType()` | string | Unique identifier (lowercase, no spaces) | | `getServiceName()` | string | Display name in admin UI | | `publish()` | array | Send content to the platform | | `validateCredentials()` | array | Test if credentials work | | `getMaxLength()` | int | Character limit (0 = no limit) | | `supportsMedia()` | bool | Whether images can be attached |