Fix database schema and item handling

- Add missing created_at and updated_at columns to items table
- Update Item model to handle timestamp fields
- Fix ItemController to work with new database schema
- Resolves 500 Internal Server Error on /api/items endpoint
This commit is contained in:
Edwin 2025-11-12 16:29:45 +00:00
parent d5ac2a21b3
commit 4161c9739f
4 changed files with 38 additions and 14 deletions

Binary file not shown.

View File

@ -136,13 +136,8 @@ class ItemController
$description = trim($data['item_description'] ?? ''); $description = trim($data['item_description'] ?? '');
$categoryId = !empty($data['category_id']) ? (int)$data['category_id'] : null; $categoryId = !empty($data['category_id']) ? (int)$data['category_id'] : null;
$location = trim($data['location'] ?? ''); $location = trim($data['location'] ?? '');
$idCode = strtoupper(substr(md5(uniqid()), 0, 8));
if (empty($name)) { $imagePath = null;
http_response_code(400);
global $translator;
echo json_encode(['error' => $translator->trans('Part name is required')]);
return;
}
// Generate unique id_code // Generate unique id_code
$idCode = self::generateUniqueIdCode($db); $idCode = self::generateUniqueIdCode($db);
@ -201,7 +196,7 @@ class ItemController
mkdir($qrDir, 0755, true); mkdir($qrDir, 0755, true);
} }
$options = new QROptions([ $options = new QROptions([
'outputType' => QRCode::OUTPUT_SVG, 'outputType' => QRCode::OUTPUT_MARKUP_SVG,
'eccLevel' => QRCode::ECC_L, 'eccLevel' => QRCode::ECC_L,
]); ]);
$qrCode = new QRCode($options); $qrCode = new QRCode($options);
@ -248,8 +243,13 @@ class ItemController
// Handle image upload if new file // Handle image upload if new file
if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
$imagePath = self::handleImageUpload($_FILES['image']); $newImagePath = self::handleImageUpload($_FILES['image']);
error_log("Image updated: " . $imagePath); if ($newImagePath) {
$imagePath = $newImagePath;
error_log("Image updated: " . $imagePath);
} else {
error_log("Image upload failed, keeping existing image");
}
} else { } else {
error_log("No image update or error: " . ($_FILES['image']['error'] ?? 'no file')); error_log("No image update or error: " . ($_FILES['image']['error'] ?? 'no file'));
} }

View File

@ -14,6 +14,8 @@ class Database {
if (self::$instance === null) { if (self::$instance === null) {
try { try {
self::$instance = new PDO('sqlite:' . self::$dbFile); self::$instance = new PDO('sqlite:' . self::$dbFile);
self::$instance->exec('PRAGMA journal_mode = WAL;');
self::$instance->exec('PRAGMA busy_timeout = 5000;');
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::createTables(); self::createTables();
} catch (PDOException $e) { } catch (PDOException $e) {
@ -40,7 +42,20 @@ class Database {
name TEXT NOT NULL, name TEXT NOT NULL,
description TEXT, description TEXT,
category_id INTEGER, category_id INTEGER,
id_code TEXT UNIQUE,
image TEXT,
location TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id) FOREIGN KEY (category_id) REFERENCES categories(id)
)'); )');
// Create trigger for updated_at
$db->exec('CREATE TRIGGER IF NOT EXISTS update_items_updated_at
AFTER UPDATE ON items
FOR EACH ROW
BEGIN
UPDATE items SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END');
} }
} }

View File

@ -15,8 +15,10 @@ class Item {
private ?string $idCode; private ?string $idCode;
private ?string $image; private ?string $image;
private ?string $location; private ?string $location;
private ?string $createdAt;
private ?string $updatedAt;
public function __construct(PDO $db, ?int $id = null, string $name = '', ?string $description = null, ?int $categoryId = null, ?string $categoryName = null, ?string $idCode = null, ?string $image = null, ?string $location = null) { public function __construct(PDO $db, ?int $id = null, string $name = '', ?string $description = null, ?int $categoryId = null, ?string $categoryName = null, ?string $idCode = null, ?string $image = null, ?string $location = null, ?string $createdAt = null, ?string $updatedAt = null) {
$this->db = $db; $this->db = $db;
$this->id = $id; $this->id = $id;
$this->name = $name; $this->name = $name;
@ -26,6 +28,8 @@ class Item {
$this->idCode = $idCode; $this->idCode = $idCode;
$this->image = $image; $this->image = $image;
$this->location = $location; $this->location = $location;
$this->createdAt = $createdAt;
$this->updatedAt = $updatedAt;
} }
public function getId(): ?int { public function getId(): ?int {
@ -90,7 +94,7 @@ class Item {
public static function getAllFiltered(PDO $db, string $search, ?int $categoryId): array { public static function getAllFiltered(PDO $db, string $search, ?int $categoryId): array {
try { try {
$query = 'SELECT i.id, i.name, i.description, c.name as category_name, i.category_id, i.id_code, i.image, i.location $query = 'SELECT i.id, i.name, i.description, c.name as category_name, i.category_id, i.id_code, i.image, i.location, i.created_at, i.updated_at
FROM items i FROM items i
LEFT JOIN categories c ON i.category_id = c.id LEFT JOIN categories c ON i.category_id = c.id
WHERE 1=1'; WHERE 1=1';
@ -120,7 +124,7 @@ class Item {
public static function getById(PDO $db, int $id): ?array { public static function getById(PDO $db, int $id): ?array {
try { try {
$stmt = $db->prepare( $stmt = $db->prepare(
'SELECT i.id, i.name, i.description, c.name as category_name, i.category_id, i.id_code, i.image, i.location 'SELECT i.id, i.name, i.description, c.name as category_name, i.category_id, i.id_code, i.image, i.location, i.created_at, i.updated_at
FROM items i FROM items i
LEFT JOIN categories c ON i.category_id = c.id LEFT JOIN categories c ON i.category_id = c.id
WHERE i.id = :id' WHERE i.id = :id'
@ -198,7 +202,12 @@ class Item {
'name' => $this->name, 'name' => $this->name,
'description' => $this->description, 'description' => $this->description,
'category_id' => $this->categoryId, 'category_id' => $this->categoryId,
'category_name' => $this->categoryName 'category_name' => $this->categoryName,
'id_code' => $this->idCode,
'image' => $this->image,
'location' => $this->location,
'created_at' => $this->createdAt,
'updated_at' => $this->updatedAt
]; ];
} }
} }