requireAuth(); $this->f3->expire(0); $this->render('admin/media.html', [ 'pageTitle' => 'Médiathèque', 'items' => (new Media($this->db))->all(), ]); } public function upload(): void { $this->requireAuth(); $this->verifyCsrf(); try { // Lire le nom d'origine avant que Web::receive() déplace le fichier. $originalName = (string) ($this->f3->get('FILES.image.name') ?? ''); $received = Web::instance()->receive( fn(array $file): bool => $file['size'] <= self::UPLOAD_MAX_BYTES, overwrite: false, slug: true ); // UPLOADS étant absolu (bootstrap.php), les chemins retournés le sont aussi. $accepted = array_keys(array_filter($received)); if ($accepted === []) { throw new RuntimeException('Choisis une image valide à envoyer (JPG, PNG, WebP ≤ ' . (int)(self::UPLOAD_MAX_BYTES / 1024 / 1024) . ' Mo).'); } foreach ($accepted as $destPath) { (new Media($this->db))->upload($destPath, $originalName); } $this->flash('success', 'Image ajoutée.'); } catch (RuntimeException $e) { $this->flash('error', $e->getMessage()); } $this->f3->reroute($this->f3->alias('media_index')); } public function updateAlt(): void { $this->requireAuth(); $this->verifyCsrf(); try { $alt = trim((string) ($this->f3->get('POST.alt') ?? '')); (new Media($this->db))->updateAlt((int) $this->f3->get('PARAMS.id'), $alt); $this->flash('success', 'Texte alternatif mis à jour.'); } catch (RuntimeException $e) { $this->flash('error', $e->getMessage()); } $this->f3->reroute($this->f3->alias('media_index')); } public function delete(): void { $this->requireAuth(); $this->verifyCsrf(); try { (new Media($this->db))->delete((int) $this->f3->get('PARAMS.id')); $this->flash('success', 'Image supprimée.'); } catch (RuntimeException $e) { $this->flash('error', $e->getMessage()); } $this->f3->reroute($this->f3->alias('media_index')); } }