---
title: "SmartMaker - Back (PHP)"
weight: 20
description: "La partie backoffice de SmartMaker s'intègre dans un module Dolibarr standard."
category: "Briques techniques"
type: "librairie"
---

# SmartMaker - Back (PHP)

La partie backoffice de SmartMaker s'intègre dans un module Dolibarr standard.

## Structure des dossiers

Lorsque vous déployez SmartMaker dans votre module Dolibarr, les dossiers suivants sont créés :

| Dossier | Description |
| --- | --- |
| `mobile/` | Code source React de l'application mobile |
| `pwa/` | Application compilée + point d'entrée `api.php` |
| `smartmaker-api/` | Contrôleurs et mappeurs PHP |

Et un fichier `smartmaker-api-prepend.php` pour factoriser les includes.

## Le routeur PHP

### Syntaxe

```
Route::action(path, Controller::class, method, protected);
```

| Paramètre | Description |
| --- | --- |
| `action` | `get`, `post`, `put`, `delete` |
| `path` | Chemin de l'API (ex: `items`, `items/{id}`) |
| `Controller::class` | Classe PHP à appeler |
| `method` | Méthode de la classe |
| `protected` | `true` = route authentifiée, `false` = publique |

### Exemple complet (api.php)

```
<?php
require_once '../smartmaker-api-prepend.php';

use SmartAuth\Api\AuthController;
use SmartAuth\Api\RouteController as Route;
use MyModule\Api\ItemController;

// Routes publiques (authentification)
Route::get('login',     AuthController::class, 'index');
Route::post('login',    AuthController::class, 'login');
Route::get('refresh',   AuthController::class, 'refresh');

// Routes protégées (nécessitent un token JWT)
Route::post('logout',   AuthController::class, 'logout', true);
Route::post('device',   AuthController::class, 'device', true);

// CRUD sur les items
Route::get('items',         ItemController::class, 'index', true);
Route::get('items/{id}',    ItemController::class, 'show', true);
Route::post('items',        ItemController::class, 'create', true);
Route::put('items/{id}',    ItemController::class, 'update', true);
Route::delete('items/{id}', ItemController::class, 'delete', true);

// Routes avec filtres
Route::post('items/{filter}', ItemController::class, 'search', true);

// Fichiers
Route::get('file/{element}/{parentid}/{ref}', FileController::class, 'download', true);

// Fallback
json_reply('Access denied', 403);
```

### Paramètres dynamiques

Les paramètres entre accolades sont passés dans le payload :

```
// Route: GET /items/123
Route::get('items/{id}', ItemController::class, 'show', true);

// Dans le controller:
public function show($payload)
{
    $id = $payload['id']; // 123
}
```

## Créer un Controller

### Structure de base

```
<?php
namespace MyModule\Api;

class ItemController
{
    public function __construct() {}

    /**
     * Liste des items
     * @param array|null $payload Données de la requête
     * @return array [data, httpCode]
     */
    public function index($payload = null)
    {
        global $db, $user;

        // Votre logique ici
        $items = [];

        return [$items, 200];
    }

    /**
     * Récupérer un item
     */
    public function show($payload = null)
    {
        global $db;

        $id = $payload['id'] ?? null;

        if ($id === null) {
            return ['Not Found', 404];
        }

        // Fetch l'objet
        $item = new \MyObject($db);
        $res = $item->fetch($id);

        if ($res <= 0) {
            return ['Not Found', 404];
        }

        // Mapper pour le front
        $mapping = new dmMyObject();
        $data = $mapping->exportMappedData($item);

        return [$data, 200];
    }

    /**
     * Créer un item
     */
    public function create($payload = null)
    {
        global $db, $user;

        $item = new \MyObject($db);
        $item->label = $payload['label'];
        $item->description = $payload['description'];

        $res = $item->create($user);

        if ($res < 0) {
            return ['Error creating item', 500];
        }

        return [['id' => $res], 201];
    }

    /**
     * Mettre à jour un item
     */
    public function update($payload = null)
    {
        global $db, $user;

        $id = $payload['id'] ?? null;

        $item = new \MyObject($db);
        $res = $item->fetch($id);

        if ($res <= 0) {
            return ['Not Found', 404];
        }

        // Mettre à jour les champs
        if (isset($payload['label'])) {
            $item->label = $payload['label'];
        }

        $res = $item->update($user);

        if ($res < 0) {
            return ['Error updating item', 500];
        }

        return ['Updated', 200];
    }

    /**
     * Supprimer un item
     */
    public function delete($payload = null)
    {
        global $db, $user;

        $id = $payload['id'] ?? null;

        $item = new \MyObject($db);
        $res = $item->fetch($id);

        if ($res <= 0) {
            return ['Not Found', 404];
        }

        $res = $item->delete($user);

        if ($res < 0) {
            return ['Error deleting item', 500];
        }

        return ['Deleted', 200];
    }

    /**
     * Recherche avec filtres
     */
    public function search($payload = null)
    {
        global $db;

        $filter = $payload['filter'] ?? 'all';
        $limit = $payload['limit'] ?? 10;

        // Construire la requête SQL
        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "myobject";
        $sql .= " WHERE 1=1";

        if ($filter === 'active') {
            $sql .= " AND status = 1";
        }

        $sql .= " LIMIT " . (int) $limit;

        $resql = $db->query($sql);
        $items = [];

        while ($obj = $db->fetch_object($resql)) {
            $item = new \MyObject($db);
            $item->fetch($obj->rowid);

            $mapping = new dmMyObject();
            $items[] = $mapping->exportMappedData($item);
        }

        return [$items, 200];
    }
}
```

### Accès à l'utilisateur connecté

L'utilisateur JWT est disponible dans le payload :

```
public function update($payload = null)
{
    $user = $payload['user']; // Objet User Dolibarr

    dol_syslog("Action par: " . $user->login);
}
```

## Voir aussi
- [Mapping Dolibarr - React](/back/mapping-dolibarr-react) - Classes dm*
- Exemple complet de Controller
- [SmartAuth](/smartauth) - Authentification JWT
