Services

Services are plain PHP classes that contain business logic. They sit between the controller and the model, keeping models as pure data-access objects and controllers thin.

Location and Namespace

plugins/MyPlugin/Services/ItemService.php
namespace: PluginsMyPluginServices

When to Use a Service

Use a service class when logic spans multiple models, involves external API calls, email, or file I/O, or is called from multiple controllers or a CLI command. Do not put this logic in a controller or model.

Basic Service Example

<?php

namespace PluginsMyPluginServices;

use PluginsMyPluginModelsItemModel;

class ItemService
{
    protected ItemModel $itemModel;

    public function __construct()
    {
        $this->itemModel = model('PluginsMyPluginModelsItemModel');
    }

    public function create(array $data): int|false
    {
        $data['slug'] = $this->generateSlug($data['title']);

        if (! $this->itemModel->save($data)) {
            return false;
        }

        return $this->itemModel->getInsertID();
    }

    public function publish(int $id): bool
    {
        $item = $this->itemModel->find($id);
        if ($item === null) {
            return false;
        }

        $result = $this->itemModel->update($id, [
            'status'       => 'published',
            'published_at' => date('Y-m-d H:i:s'),
        ]);

        if ($result) {
            CodeIgniterEventsEvents::trigger('myplugin_item_published', $item);
        }

        return $result;
    }

    protected function generateSlug(string $title): string
    {
        $base = trim(strtolower(preg_replace('/[^a-zA-Z0-9]+/', '-', $title)), '-');
        $slug = $base;
        $i    = 1;

        while ($this->itemModel->where('slug', $slug)->countAllResults() > 0) {
            $slug = $base . '-' . $i++;
        }

        return $slug;
    }
}

Instantiation

Services are not registered in CI4's service container by default. Instantiate them directly in controllers:

$service = new PluginsMyPluginServicesItemService();
$id = $service->create($this->request->getPost());

Using CI4 Services

$emailService = ConfigServices::email();
$cache        = ConfigServices::cache();
log_message('info', '[MyPlugin] ' . $message);

Services vs Models

ResponsibilityModelService
CRUD queriesYesNo
Validation rulesYesNo
Multi-model operationsNoYes
External API callsNoYes
Email / notificationsNoYes
Business rules / logicNoYes
File I/ONoYes