mirror of
https://github.com/mivodev/mivo.git
synced 2026-01-26 05:25:42 +07:00
146 lines
4.8 KiB
PHP
146 lines
4.8 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use PDO;
|
|
use Exception;
|
|
|
|
class Logo {
|
|
protected $db;
|
|
protected $table = 'logos';
|
|
|
|
public function __construct() {
|
|
$this->db = \App\Core\Database::getInstance();
|
|
$this->initTable();
|
|
}
|
|
|
|
// Connect method removed as we use shared instance
|
|
private function initTable() {
|
|
$query = "CREATE TABLE IF NOT EXISTS {$this->table} (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
path TEXT NOT NULL,
|
|
type TEXT,
|
|
size INTEGER,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)";
|
|
$this->db->query($query);
|
|
}
|
|
|
|
public function generateId($length = 6) {
|
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
$charactersLength = strlen($characters);
|
|
$randomString = '';
|
|
for ($i = 0; $i < $length; $i++) {
|
|
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
|
}
|
|
return $randomString;
|
|
}
|
|
|
|
public function getAll() {
|
|
$stmt = $this->db->query("SELECT * FROM {$this->table} ORDER BY created_at DESC");
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
public function getById($id) {
|
|
$stmt = $this->db->query("SELECT * FROM {$this->table} WHERE id = :id", ['id' => $id]);
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
public function add($file) {
|
|
// Security: Strict MIME Type Check
|
|
$finfo = new \finfo(FILEINFO_MIME_TYPE);
|
|
$mimeType = $finfo->file($file['tmp_name']);
|
|
|
|
$allowedMimes = [
|
|
'image/jpeg' => 'jpg',
|
|
'image/png' => 'png',
|
|
'image/gif' => 'gif',
|
|
'image/svg+xml' => 'svg',
|
|
'image/webp' => 'webp'
|
|
];
|
|
|
|
if (!array_key_exists($mimeType, $allowedMimes)) {
|
|
throw new Exception("Invalid file type: " . $mimeType);
|
|
}
|
|
|
|
// Use extension mapped from MIME type or sanitize original
|
|
// Better to trust MIME mapping for extensions to avoid double extension attacks
|
|
$extension = $allowedMimes[$mimeType];
|
|
|
|
// Generate Unique Short ID
|
|
do {
|
|
$id = $this->generateId();
|
|
$exists = $this->getById($id);
|
|
} while ($exists);
|
|
|
|
$uploadDir = ROOT . '/public/assets/img/logos/';
|
|
if (!file_exists($uploadDir)) {
|
|
mkdir($uploadDir, 0777, true);
|
|
}
|
|
|
|
$filename = $id . '.' . $extension;
|
|
$targetPath = $uploadDir . $filename;
|
|
|
|
if (move_uploaded_file($file['tmp_name'], $targetPath)) {
|
|
$this->db->query("INSERT INTO {$this->table} (id, name, path, type, size) VALUES (:id, :name, :path, :type, :size)", [
|
|
'id' => $id,
|
|
'name' => $file['name'],
|
|
'path' => '/assets/img/logos/' . $filename,
|
|
'type' => $extension,
|
|
'size' => $file['size']
|
|
]);
|
|
return $id;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function syncFiles() {
|
|
// One-time sync: scan folder, if file not in DB, add it.
|
|
$logoDir = ROOT . '/public/assets/img/logos/';
|
|
if (!file_exists($logoDir)) return;
|
|
|
|
$files = glob($logoDir . '*.{jpg,jpeg,png,gif,svg}', GLOB_BRACE);
|
|
|
|
foreach ($files as $file) {
|
|
$filename = basename($file);
|
|
$extension = pathinfo($filename, PATHINFO_EXTENSION);
|
|
|
|
// Check if file is registered (maybe by path match)
|
|
$webPath = '/assets/img/logos/' . $filename;
|
|
$stmt = $this->db->query("SELECT COUNT(*) FROM {$this->table} WHERE path = :path", ['path' => $webPath]);
|
|
|
|
if ($stmt->fetchColumn() == 0) {
|
|
// Not in DB, register it.
|
|
// Ideally we'd rename it to a hashID, but since it's existing, let's generate an ID and map it.
|
|
do {
|
|
$id = $this->generateId();
|
|
$exists = $this->getById($id);
|
|
} while ($exists);
|
|
|
|
$this->db->query("INSERT INTO {$this->table} (id, name, path, type, size) VALUES (:id, :name, :path, :type, :size)", [
|
|
'id' => $id,
|
|
'name' => $filename,
|
|
'path' => $webPath,
|
|
'type' => $extension,
|
|
'size' => filesize($file)
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function delete($id) {
|
|
$logo = $this->getById($id);
|
|
if ($logo) {
|
|
$filePath = ROOT . '/public' . $logo['path'];
|
|
if (file_exists($filePath)) {
|
|
unlink($filePath);
|
|
}
|
|
$this->db->query("DELETE FROM {$this->table} WHERE id = :id", ['id' => $id]);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|