From 4161c9739f723cccb96ee3904421782e01ac6839 Mon Sep 17 00:00:00 2001 From: Edwin Date: Wed, 12 Nov 2025 16:29:45 +0000 Subject: [PATCH] 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 --- collections.sqlite | Bin 20480 -> 20480 bytes src/Controllers/ItemController.php | 20 ++++++++++---------- src/Database.php | 15 +++++++++++++++ src/Models/Item.php | 17 +++++++++++++---- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/collections.sqlite b/collections.sqlite index 348bd4b5b82afbaec35a4aeeca648bc192ce281b..95bd1351f2134cb45b191d5c92bb42e9eed0debf 100755 GIT binary patch literal 20480 zcmeI4&2QT_6u>E4`LbhcMOt`4V3YwCG+E` z+ey=-JM6H3VTYZD{v+#uFreoF+YUPn*kKrY*kP2M*jAgO8?Y5f@n}mXAH~P_eta}6 znbPjPO{Z_;db`^+`A!nY~Dou^rz5zhvZ}~yX76`udSJVyV34Gu8uoi$BtF4wXLC6UTT_+ z^ZZepHyCNcwXV(ETUGwcKhOQD6t|3ZeB7~K5&A4HY?qDVM#*z*b;5u(Ts8_u*(l|V zU3?~Y?B1$lt&Q5RJrSm6mTt#pzr5Y=I*o?i9d=jsU{=R{d*yT7<>H1*^fia#k#=_= zGKC61bZ^IX2yd5$qvSh++mDS*?k+BG@B1pU#zwK^leh}cR1HUa*QiVax`T6jW$tmM z>ayFdWVUwj{$0+1j{&}eOUC{!$GYuPX_WHP3xU4&u^8aDVKPhxF_+M+w*t1b_e#00KY&2mk>f00e*l5C8%|;9VvV5k+(z z^{l$ptMh$W5YeL0G&`LKc7Xdm=lMPt5YaWEZ}f00e-*yG0-pye^Ec2Z*!5Yl3^W&rke^R{#QY z!Ns}Z1%e27JRtpoq~G}t5)c3aKmZ5;0U!VbfB+Bx0zd!=00AIyc?rw~f-%9nfh8Ih zg3H4AJ^(Qi{t1P{NoQml1b_e#00KY&2mk>f z00jOk0v|?0D1KdtqeXWRy+2oebh@d&2HaJwAzhh+v%DKRZq#3rZhD{G@_EE zlDzex)8N`D<1d+VIY|(TiJDfFw4z78bq&2B4Q@<_(F&Q14;F4Pw)?o%H&1cFIkl|{ zUncCd8n`!<)tys0S&$2b6!jTu>Xg>%soJ@r-L}PV>Tf67UH()8GeKoVp+ru}N`j_H zl4z8=mb%LE=Gl`7{Pt2gO*OwrC0u09hR~G-A-=o7*dyD1)D7k+RTZixefAvcvSq8X zUM+5IR9Q+UygR$`$nN@8UeJr8re$Ry&4tmDJ5~$4pI*IT^&0M)>IPp`-4KbYD!QJR zeLbpnDrr-FG*thLfK_k2(IQIHghd@RjZi5ZLdz>cd?St!Q5YR=geiWQ71UiC$l6~AuYcsH?c&)m_dMnk&(ecL4kpRK?#Uiffxo@C+ZlBDlzDl zb@KB6U|``bVc`40f0%C>Z^>do0bZ^qeHM0cadE~L+sSg=_a>|Hcx_(B7strO%zv4Q z|1$qe{x6#a6^`;xzASGD6nnzJ|AhY=|J%)i23Po*7#KD`(dQPBXXRsLR%A?0EJ;nz zFUm|UX66N2&cvSsMEooHb2bYK#PJJQvv4p-N;As3^QNa|XQX9JUhOX}V{C4aoNAJ0 zWS$!D67QmyRgfOc%E6$h$|;*DJh|UbQ^nXUCD9_))Y8x_-ZiB>GcVpfF$rizPEION MacX*TN(uu50Nm6@-T(jq diff --git a/src/Controllers/ItemController.php b/src/Controllers/ItemController.php index aa38d24..7cf6834 100755 --- a/src/Controllers/ItemController.php +++ b/src/Controllers/ItemController.php @@ -136,13 +136,8 @@ class ItemController $description = trim($data['item_description'] ?? ''); $categoryId = !empty($data['category_id']) ? (int)$data['category_id'] : null; $location = trim($data['location'] ?? ''); - - if (empty($name)) { - http_response_code(400); - global $translator; - echo json_encode(['error' => $translator->trans('Part name is required')]); - return; - } + $idCode = strtoupper(substr(md5(uniqid()), 0, 8)); + $imagePath = null; // Generate unique id_code $idCode = self::generateUniqueIdCode($db); @@ -201,7 +196,7 @@ class ItemController mkdir($qrDir, 0755, true); } $options = new QROptions([ - 'outputType' => QRCode::OUTPUT_SVG, + 'outputType' => QRCode::OUTPUT_MARKUP_SVG, 'eccLevel' => QRCode::ECC_L, ]); $qrCode = new QRCode($options); @@ -248,8 +243,13 @@ class ItemController // Handle image upload if new file if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { - $imagePath = self::handleImageUpload($_FILES['image']); - error_log("Image updated: " . $imagePath); + $newImagePath = self::handleImageUpload($_FILES['image']); + if ($newImagePath) { + $imagePath = $newImagePath; + error_log("Image updated: " . $imagePath); + } else { + error_log("Image upload failed, keeping existing image"); + } } else { error_log("No image update or error: " . ($_FILES['image']['error'] ?? 'no file')); } diff --git a/src/Database.php b/src/Database.php index 117ab86..17e301a 100755 --- a/src/Database.php +++ b/src/Database.php @@ -14,6 +14,8 @@ class Database { if (self::$instance === null) { try { 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::createTables(); } catch (PDOException $e) { @@ -40,7 +42,20 @@ class Database { name TEXT NOT NULL, description TEXT, 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) )'); + + // 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'); } } diff --git a/src/Models/Item.php b/src/Models/Item.php index b374951..29e94bc 100755 --- a/src/Models/Item.php +++ b/src/Models/Item.php @@ -15,8 +15,10 @@ class Item { private ?string $idCode; private ?string $image; 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->id = $id; $this->name = $name; @@ -26,6 +28,8 @@ class Item { $this->idCode = $idCode; $this->image = $image; $this->location = $location; + $this->createdAt = $createdAt; + $this->updatedAt = $updatedAt; } public function getId(): ?int { @@ -90,7 +94,7 @@ class Item { public static function getAllFiltered(PDO $db, string $search, ?int $categoryId): array { 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 LEFT JOIN categories c ON i.category_id = c.id WHERE 1=1'; @@ -120,7 +124,7 @@ class Item { public static function getById(PDO $db, int $id): ?array { try { $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 LEFT JOIN categories c ON i.category_id = c.id WHERE i.id = :id' @@ -198,7 +202,12 @@ class Item { 'name' => $this->name, 'description' => $this->description, '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 ]; } }