mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 11:09:18 +02:00
Add comprehensive thesis management system with database migration
This commit introduces a complete thesis management interface and migrates the system from YAML-based storage to SQLite: Core Changes: - Add Database.php helper class with PDO connection and entity management - Add list.php for viewing all theses with filtering and sorting - Add edit.php for modifying existing thesis records - Add import.php for migrating legacy YAML data to SQLite - Add justfile with development tasks (serve, init-test-db, etc.) Documentation: - Add MIGRATION.md with complete migration guide and architecture docs - Update README.md with database setup and Just recipe instructions - Update .gitignore to exclude test databases and error logs Modified Forms: - Enhanced formulaire.php with transaction-based SQLite processing - Updated index.php with database-driven form options - Improved thanks.php to read from database views The new architecture provides: - Normalized database schema (19 tables, 2 views) - Transaction safety and referential integrity - CRUD operations for thesis management - Filtering by year, orientation, AP program, publication status - Secure file handling with metadata tracking 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
111
front-backend/Database.php
Normal file
111
front-backend/Database.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Database connection class for SQLite
|
||||
*/
|
||||
class Database {
|
||||
private static $instance = null;
|
||||
private $pdo;
|
||||
|
||||
/**
|
||||
* Private constructor to prevent multiple instances
|
||||
*/
|
||||
private function __construct() {
|
||||
$dbPath = __DIR__ . '/../formulaire/test.db';
|
||||
|
||||
if (!file_exists($dbPath)) {
|
||||
throw new Exception("Database file not found: " . $dbPath);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->pdo = new PDO('sqlite:' . $dbPath);
|
||||
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
error_log("Database connection failed: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get singleton instance
|
||||
*/
|
||||
public static function getInstance() {
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PDO connection
|
||||
*/
|
||||
public function getConnection() {
|
||||
return $this->pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all published theses with pagination
|
||||
*/
|
||||
public function getPublishedTheses($limit = 10, $offset = 0) {
|
||||
$sql = "SELECT * FROM v_theses_public ORDER BY year DESC, title ASC LIMIT :limit OFFSET :offset";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count all published theses
|
||||
*/
|
||||
public function countPublishedTheses() {
|
||||
$sql = "SELECT COUNT(*) as count FROM theses WHERE is_published = 1";
|
||||
$stmt = $this->pdo->query($sql);
|
||||
$result = $stmt->fetch();
|
||||
return $result['count'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get thesis by ID with all related data
|
||||
*/
|
||||
public function getThesisById($id) {
|
||||
$sql = "SELECT * FROM v_theses_full WHERE id = :id AND is_published = 1";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$thesis = $stmt->fetch();
|
||||
|
||||
if (!$thesis) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get associated files
|
||||
$thesis['files'] = $this->getThesisFiles($id);
|
||||
|
||||
return $thesis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get files associated with a thesis
|
||||
*/
|
||||
public function getThesisFiles($thesisId) {
|
||||
$sql = "SELECT * FROM thesis_files WHERE thesis_id = :thesis_id ORDER BY file_type, uploaded_at";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->bindValue(':thesis_id', $thesisId, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
return $stmt->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent cloning
|
||||
*/
|
||||
private function __clone() {}
|
||||
|
||||
/**
|
||||
* Prevent unserialization
|
||||
*/
|
||||
public function __wakeup() {
|
||||
throw new Exception("Cannot unserialize singleton");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user