Les controllers contiennent la logique métier de l'API.
<?php // smartmaker-api/Controllers/ItemController.php namespace MonModule\Api; class ItemController { public function __construct() {} /** * Liste des items * @param array|null $payload * @return array [data, httpCode] */ public function index($payload = null) { global $db, $user; // Logique ici return [['items' => $items], 200]; } }
Dans les routes protégées :
$db : connexion base de données Dolibarr$user : utilisateur Dolibarr connecté (via JWT)$conf : configuration Dolibarr$langs : traductions<?php namespace MonModule\Api; use MonModule\Api\Mappers\dmProduct; class ProductController { /** * Liste des produits */ public function index($payload = null) { global $db, $user; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; // Paramètres de pagination $limit = $payload['limit'] ?? 50; $offset = $payload['offset'] ?? 0; // Requête SQL $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "product"; $sql .= " WHERE entity IN (" . getEntity('product') . ")"; $sql .= " ORDER BY label ASC"; $sql .= " LIMIT " . (int) $limit; $sql .= " OFFSET " . (int) $offset; $resql = $db->query($sql); $products = []; if ($resql) { $mapper = new dmProduct(); while ($obj = $db->fetch_object($resql)) { $product = new \Product($db); $product->fetch($obj->rowid); $products[] = $mapper->exportMappedData($product); } } return [['products' => $products], 200]; } /** * Détail d'un produit */ public function show($payload = null) { global $db; $id = $payload['id'] ?? null; if (!$id) { return ['ID required', 400]; } require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $product = new \Product($db); $res = $product->fetch($id); if ($res <= 0) { return ['Product not found', 404]; } // Charger les extrafields $product->fetch_optionals(); $mapper = new dmProduct(); $data = $mapper->exportMappedData($product); return [$data, 200]; } /** * Créer un produit */ public function create($payload = null) { global $db, $user; // Validation if (empty($payload['label'])) { return ['Label required', 400]; } require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $product = new \Product($db); $product->ref = $payload['ref'] ?? ''; $product->label = $payload['label']; $product->description = $payload['description'] ?? ''; $product->price = $payload['price'] ?? 0; $product->status = $payload['status'] ?? 1; // Créer en base $res = $product->create($user); if ($res < 0) { return ['Error creating product: ' . $product->error, 500]; } // Sauvegarder les extrafields if (!empty($payload['extrafields'])) { foreach ($payload['extrafields'] as $key => $value) { $product->array_options['options_' . $key] = $value; } $product->insertExtraFields(); } return [['id' => $res], 201]; } /** * Mettre à jour un produit */ public function update($payload = null) { global $db, $user; $id = $payload['id'] ?? null; if (!$id) { return ['ID required', 400]; } require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $product = new \Product($db); $res = $product->fetch($id); if ($res <= 0) { return ['Product not found', 404]; } // Mettre à jour les champs fournis if (isset($payload['label'])) { $product->label = $payload['label']; } if (isset($payload['description'])) { $product->description = $payload['description']; } if (isset($payload['price'])) { $product->price = $payload['price']; } if (isset($payload['status'])) { $product->status = $payload['status']; } $res = $product->update($product->id, $user); if ($res < 0) { return ['Error updating product: ' . $product->error, 500]; } // Mettre à jour les extrafields if (!empty($payload['extrafields'])) { $product->fetch_optionals(); foreach ($payload['extrafields'] as $key => $value) { $product->array_options['options_' . $key] = $value; } $product->updateExtraFields(); } return ['Updated', 200]; } /** * Supprimer un produit */ public function delete($payload = null) { global $db, $user; $id = $payload['id'] ?? null; if (!$id) { return ['ID required', 400]; } require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $product = new \Product($db); $res = $product->fetch($id); if ($res <= 0) { return ['Product not found', 404]; } // Vérifier les droits if (!$user->hasRight('produit', 'supprimer')) { return ['Permission denied', 403]; } $res = $product->delete($user); if ($res < 0) { return ['Error deleting product: ' . $product->error, 500]; } return ['Deleted', 200]; } }
/** * Recherche avancée */ public function search($payload = null) { global $db; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; // Filtres $search = $payload['search'] ?? ''; $category = $payload['category'] ?? null; $status = $payload['status'] ?? null; $minPrice = $payload['minPrice'] ?? null; $maxPrice = $payload['maxPrice'] ?? null; // Pagination $limit = min($payload['limit'] ?? 50, 100); // Max 100 $offset = $payload['offset'] ?? 0; // Construction de la requête $sql = "SELECT p.rowid FROM " . MAIN_DB_PREFIX . "product as p"; // Jointure catégorie si nécessaire if ($category) { $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "categorie_product as cp"; $sql .= " ON p.rowid = cp.fk_product"; } $sql .= " WHERE p.entity IN (" . getEntity('product') . ")"; // Filtres if ($search) { $sql .= " AND (p.label LIKE '%" . $db->escape($search) . "%'"; $sql .= " OR p.ref LIKE '%" . $db->escape($search) . "%')"; } if ($category) { $sql .= " AND cp.fk_categorie = " . (int) $category; } if ($status !== null) { $sql .= " AND p.tosell = " . (int) $status; } if ($minPrice !== null) { $sql .= " AND p.price >= " . (float) $minPrice; } if ($maxPrice !== null) { $sql .= " AND p.price <= " . (float) $maxPrice; } $sql .= " ORDER BY p.label ASC"; $sql .= " LIMIT " . (int) $limit; $sql .= " OFFSET " . (int) $offset; $resql = $db->query($sql); $products = []; $mapper = new dmProduct(); while ($obj = $db->fetch_object($resql)) { $product = new \Product($db); $product->fetch($obj->rowid); $products[] = $mapper->exportMappedData($product); } return [['products' => $products], 200]; }
/** * Télécharger un fichier */ public function download($payload = null) { global $conf, $db; $element = $payload['element']; // ex: 'product' $parentId = $payload['parentId']; $ref = $payload['ref']; // nom du fichier // Construire le chemin $dir = $conf->$element->dir_output; $filepath = $dir . '/' . $parentId . '/' . $ref; if (!file_exists($filepath)) { return ['File not found', 404]; } // Retourner le fichier en base64 $content = file_get_contents($filepath); $mime = mime_content_type($filepath); $base64 = base64_encode($content); return [[ 'filename' => $ref, 'mime' => $mime, 'content' => 'data:' . $mime . ';base64,' . $base64 ], 200]; } /** * Uploader un fichier */ public function upload($payload = null) { global $conf, $user; $element = $payload['element']; $parentId = $payload['parentId']; $filename = $payload['filename']; $content = $payload['content']; // base64 // Décoder le contenu $data = base64_decode(preg_replace('#^data:.+;base64,#', '', $content)); // Chemin de destination $dir = $conf->$element->dir_output . '/' . $parentId; // Créer le dossier si nécessaire if (!is_dir($dir)) { dol_mkdir($dir); } $filepath = $dir . '/' . $filename; // Sauvegarder if (file_put_contents($filepath, $data) === false) { return ['Error saving file', 500]; } return [['path' => $filepath], 201]; }
public function delete($payload = null) { global $db, $user; // Vérifier un droit spécifique if (!$user->hasRight('monmodule', 'delete')) { return ['Permission denied', 403]; } // Vérifier si admin if (!$user->admin) { return ['Admin required', 403]; } // Suite du code... }
public function create($payload = null) { global $db, $user; // Log pour debug dol_syslog("ProductController::create by " . $user->login, LOG_DEBUG); // En cas d'erreur dol_syslog("ProductController::create error: " . $product->error, LOG_ERR); // ... }
← Chapitre précédent | Retour au module | Chapitre suivant : Mappers →