Primo rilascio
This commit is contained in:
224
backend/src/Controllers/ShiftDefinitionController.php
Normal file
224
backend/src/Controllers/ShiftDefinitionController.php
Normal file
@@ -0,0 +1,224 @@
|
||||
<?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.']);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user