224 lines
9.2 KiB
PHP
224 lines
9.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controllers;
|
|
|
|
use App\Database;
|
|
use Doctrine\DBAL\Connection;
|
|
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
|
|
|
class ShiftDefinitionController
|
|
{
|
|
private Connection $db;
|
|
|
|
public function __construct()
|
|
{
|
|
try {
|
|
$this->db = Database::getConnection();
|
|
} catch (\Throwable $e) {
|
|
error_log("Failed to get DB connection in ShiftDefinitionController: " . $e->getMessage());
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'Internal Server Error - DB Connection']);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mostra un elenco di definizioni di turno.
|
|
* GET /api/shift-definitions
|
|
*/
|
|
public function index(): void
|
|
{
|
|
try {
|
|
$queryBuilder = $this->db->createQueryBuilder();
|
|
$shifts = $queryBuilder
|
|
->select('*')
|
|
->from('shift_definitions')
|
|
->orderBy('start_time', 'ASC') // Ordina per orario inizio
|
|
->fetchAllAssociative();
|
|
|
|
echo json_encode($shifts);
|
|
} catch (\Throwable $e) {
|
|
http_response_code(500);
|
|
error_log("Error fetching shift definitions: " . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to fetch shift definitions']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mostra una definizione di turno specifica.
|
|
* GET /api/shift-definitions/{id}
|
|
*/
|
|
public function show(array $vars): void
|
|
{
|
|
$id = $vars['id'] ?? null;
|
|
if ($id === null) { http_response_code(400); echo json_encode(['error' => 'Missing shift definition ID']); return; }
|
|
|
|
try {
|
|
$shift = $this->db->fetchAssociative('SELECT * FROM shift_definitions WHERE id = ?', [$id]);
|
|
|
|
if ($shift === false) {
|
|
http_response_code(404);
|
|
echo json_encode(['error' => "Shift definition with ID {$id} not found"]);
|
|
} else {
|
|
echo json_encode($shift);
|
|
}
|
|
} catch (\Throwable $e) {
|
|
http_response_code(500);
|
|
error_log("Error fetching shift definition {$id}: " . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to fetch shift definition']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Crea una nuova definizione di turno.
|
|
* POST /api/shift-definitions
|
|
*/
|
|
public function store(): void
|
|
{
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
if (json_last_error() !== JSON_ERROR_NONE || !is_array($input)) {
|
|
http_response_code(400); echo json_encode(['error' => 'Invalid JSON input']); return;
|
|
}
|
|
|
|
// Validazione campi obbligatori
|
|
if (empty($input['name']) || empty($input['start_time']) || empty($input['end_time'])) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Missing required fields: name, start_time, end_time']);
|
|
return;
|
|
}
|
|
// Validazione formato orario (HH:MM o HH:MM:SS)
|
|
$timeRegex = '/^([01]\d|2[0-3]):([0-5]\d)(:([0-5]\d))?$/';
|
|
if (!preg_match($timeRegex, $input['start_time']) || !preg_match($timeRegex, $input['end_time'])) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'Invalid time format. Use HH:MM or HH:MM:SS.']);
|
|
return;
|
|
}
|
|
// Validazione logica orari (opzionale, ma utile)
|
|
if (strtotime($input['end_time']) <= strtotime($input['start_time'])) {
|
|
http_response_code(400);
|
|
echo json_encode(['error' => 'End time must be after start time.']);
|
|
return;
|
|
}
|
|
|
|
|
|
$dataToInsert = [
|
|
'name' => $input['name'],
|
|
'start_time' => $input['start_time'],
|
|
'end_time' => $input['end_time'],
|
|
'notes' => $input['notes'] ?? null,
|
|
];
|
|
|
|
try {
|
|
$result = $this->db->insert('shift_definitions', $dataToInsert);
|
|
if ($result === false || $result === 0) { throw new \Exception("Failed to insert shift definition."); }
|
|
|
|
$newId = $this->db->lastInsertId();
|
|
http_response_code(201);
|
|
$this->show(['id' => $newId]);
|
|
|
|
} catch (UniqueConstraintViolationException $e) {
|
|
http_response_code(409);
|
|
error_log("Error creating shift definition (duplicate name?): " . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to create shift definition. Name might already exist.']);
|
|
} catch (\Throwable $e) {
|
|
http_response_code(500);
|
|
error_log("Error creating shift definition: " . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to create shift definition']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Aggiorna una definizione di turno esistente.
|
|
* PUT /api/shift-definitions/{id}
|
|
*/
|
|
public function update(array $vars): void
|
|
{
|
|
$id = $vars['id'] ?? null;
|
|
if ($id === null) { http_response_code(400); echo json_encode(['error' => 'Missing shift definition ID']); return; }
|
|
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
if (json_last_error() !== JSON_ERROR_NONE || !is_array($input)) {
|
|
http_response_code(400); echo json_encode(['error' => 'Invalid JSON input']); return;
|
|
}
|
|
if (empty($input)) { http_response_code(400); echo json_encode(['error' => 'Missing update data']); return; }
|
|
|
|
// Validazione formato orario se presenti
|
|
$timeRegex = '/^([01]\d|2[0-3]):([0-5]\d)(:([0-5]\d))?$/';
|
|
if (isset($input['start_time']) && !preg_match($timeRegex, $input['start_time'])) {
|
|
http_response_code(400); echo json_encode(['error' => 'Invalid start_time format.']); return;
|
|
}
|
|
if (isset($input['end_time']) && !preg_match($timeRegex, $input['end_time'])) {
|
|
http_response_code(400); echo json_encode(['error' => 'Invalid end_time format.']); return;
|
|
}
|
|
// Validazione logica orari se entrambi presenti
|
|
$startTime = $input['start_time'] ?? null;
|
|
$endTime = $input['end_time'] ?? null;
|
|
if ($startTime && $endTime && strtotime($endTime) <= strtotime($startTime)) {
|
|
http_response_code(400); echo json_encode(['error' => 'End time must be after start time.']); return;
|
|
}
|
|
// Validazione con orari esistenti se solo uno viene fornito (più complessa, omessa per brevità)
|
|
|
|
|
|
$dataToUpdate = [];
|
|
$allowedFields = ['name', 'start_time', 'end_time', 'notes'];
|
|
foreach ($allowedFields as $field) {
|
|
if (array_key_exists($field, $input)) {
|
|
$dataToUpdate[$field] = ($input[$field] === '') ? null : $input[$field];
|
|
}
|
|
}
|
|
|
|
if (empty($dataToUpdate)) { http_response_code(400); echo json_encode(['error' => 'No valid fields provided for update']); return; }
|
|
|
|
try {
|
|
$existing = $this->db->fetchOne('SELECT 1 FROM shift_definitions WHERE id = ?', [$id]);
|
|
if ($existing === false) { http_response_code(404); echo json_encode(['error' => "Shift definition with ID {$id} not found"]); return; }
|
|
|
|
$this->db->update('shift_definitions', $dataToUpdate, ['id' => $id]);
|
|
$this->show(['id' => $id]);
|
|
|
|
} catch (UniqueConstraintViolationException $e) {
|
|
http_response_code(409);
|
|
error_log("Error updating shift definition {$id} (duplicate name?): " . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to update shift definition. Name might already exist.']);
|
|
} catch (\Throwable $e) {
|
|
http_response_code(500);
|
|
error_log("Error updating shift definition {$id}: " . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to update shift definition']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Elimina una definizione di turno.
|
|
* DELETE /api/shift-definitions/{id}
|
|
*/
|
|
public function delete(array $vars): void
|
|
{
|
|
$id = $vars['id'] ?? null;
|
|
if ($id === null) { http_response_code(400); echo json_encode(['error' => 'Missing shift definition ID']); return; }
|
|
|
|
try {
|
|
// Aggiungere qui controlli se la definizione è usata in turni effettivi?
|
|
|
|
$existing = $this->db->fetchOne('SELECT 1 FROM shift_definitions WHERE id = ?', [$id]);
|
|
if ($existing === false) { http_response_code(404); echo json_encode(['error' => "Shift definition with ID {$id} not found"]); return; }
|
|
|
|
$deletedRows = $this->db->delete('shift_definitions', ['id' => $id]);
|
|
|
|
if ($deletedRows > 0) {
|
|
http_response_code(204); // No Content
|
|
} else {
|
|
http_response_code(500);
|
|
error_log("Failed to delete shift definition {$id}, delete returned 0 rows affected.");
|
|
echo json_encode(['error' => 'Failed to delete shift definition']);
|
|
}
|
|
|
|
} catch (\Throwable $e) {
|
|
// Gestire ForeignKeyConstraintViolationException se la definizione è usata altrove
|
|
http_response_code(500);
|
|
error_log("Error deleting shift definition {$id}: " . $e->getMessage());
|
|
echo json_encode(['error' => 'Failed to delete shift definition. It might be in use.']);
|
|
}
|
|
}
|
|
} |