Simplification

This commit is contained in:
julien
2026-03-30 15:05:13 +02:00
parent b4a80013d5
commit b4593840a8
30 changed files with 526 additions and 781 deletions

View File

@@ -29,9 +29,10 @@ class Media extends DB\SQL\Mapper
public function page(int $page, int $perPage): array
{
$result = $this->paginate(max(0, $page - 1), $perPage, null, ['order' => 'created_at DESC, id DESC']);
$items = array_map(fn(self $row): array => $this->decorate($row->cast()), $result['subset'] ?: []);
return [
'items' => array_map(fn(self $row): array => $this->decorate($row->cast()), $result['subset'] ?: []),
'items' => $items,
'pagination' => [
'page' => max(1, min($page, $result['count'] ?: 1)),
'pages' => max(1, (int) ($result['count'] ?: 1)),
@@ -39,14 +40,6 @@ class Media extends DB\SQL\Mapper
];
}
public function recent(int $limit): array
{
return array_map(
fn(self $row): array => $this->decorate($row->cast()),
$this->find(null, ['order' => 'created_at DESC, id DESC', 'limit' => $limit]) ?: []
);
}
public function findById(int $id): ?array
{
if ($id <= 0) {
@@ -63,18 +56,22 @@ class Media extends DB\SQL\Mapper
return $this->dry() ? null : $this->decorate($this->cast());
}
public function upload(string $path, string $originalName = ''): int
public function upload(string $temporaryPath, string $originalName = ''): int
{
if (!is_file($path)) {
$f3 = Base::instance();
if (!is_file($temporaryPath)) {
throw new RuntimeException('Fichier image introuvable.');
}
$info = @getimagesize($path);
if (!is_array($info)) {
@unlink($path);
$binary = $f3->read($temporaryPath);
$image = new Image();
if ($binary === '' || $image->load($binary) === false) {
@unlink($temporaryPath);
throw new RuntimeException('Fichier image invalide.');
}
$info = @getimagesizefromstring($binary);
$mime = strtolower((string) ($info['mime'] ?? ''));
$extension = match ($mime) {
'image/jpeg' => 'jpg',
@@ -83,28 +80,39 @@ class Media extends DB\SQL\Mapper
};
if ($extension === null) {
@unlink($path);
@unlink($temporaryPath);
throw new RuntimeException('Format non supporté. Utilise JPG ou PNG.');
}
$fileName = bin2hex(random_bytes(16)) . '.' . $extension;
$target = rtrim((string) Base::instance()->get('paths.media_dir'), '/\\') . DIRECTORY_SEPARATOR . $fileName;
$encoded = match ($extension) {
'jpg' => $image->dump('jpeg', 90),
'png' => $image->dump('png'),
};
if (!@rename($path, $target)) {
if (!@copy($path, $target)) {
@unlink($path);
throw new RuntimeException('Impossible denregistrer cette image.');
}
@unlink($path);
$fileName = bin2hex(random_bytes(16)) . '.' . $extension;
$target = $this->storagePath($fileName);
try {
$f3->write($target, $encoded);
} catch (Throwable $e) {
@unlink($temporaryPath);
throw new RuntimeException('Impossible denregistrer cette image.', 0, $e);
}
$this->reset();
$this->file_name = $fileName;
$this->alt = $this->altFromName($originalName);
$this->width = (int) $info[0];
$this->height = (int) $info[1];
$this->created_at = app_now();
$this->save();
@unlink($temporaryPath);
try {
$this->reset();
$this->file_name = $fileName;
$this->alt = $this->guessAlt($originalName);
$this->width = $image->width();
$this->height = $image->height();
$this->created_at = app_now();
$this->save();
} catch (Throwable $e) {
@unlink($target);
throw new RuntimeException('Impossible de finaliser cette image.', 0, $e);
}
return (int) $this->id;
}
@@ -127,34 +135,41 @@ class Media extends DB\SQL\Mapper
throw new RuntimeException('Image introuvable.');
}
$path = rtrim((string) Base::instance()->get('paths.media_dir'), '/\\') . DIRECTORY_SEPARATOR . $this->file_name;
$this->erase();
if (is_file($path)) {
@unlink($path);
try {
$this->erase();
} catch (Throwable $e) {
throw new RuntimeException('Impossible de supprimer cette image.', 0, $e);
}
}
private function decorate(array $row): array
{
$file = (string) $row['file_name'];
$fileName = (string) $row['file_name'];
$alt = (string) $row['alt'];
$base = rtrim((string) Base::instance()->get('BASE'), '/');
$mediaBase = rtrim((string) Base::instance()->get('paths.media_base'), '/');
return [
'id' => (int) $row['id'],
'file_name' => $file,
'file_name' => $fileName,
'alt' => $alt,
'width' => (int) $row['width'],
'height' => (int) $row['height'],
'created_at' => (string) $row['created_at'],
'url' => rtrim((string) Base::instance()->get('BASE'), '/') . rtrim((string) Base::instance()->get('paths.media_base'), '/') . '/' . rawurlencode($file),
'markdown' => '![' . $alt . '](media:' . $file . ')',
'url' => $base . $mediaBase . '/' . rawurlencode($fileName),
'markdown' => '![' . $alt . '](media:' . $fileName . ')',
];
}
private function altFromName(string $name): string
private function storagePath(string $fileName): string
{
$name = trim(pathinfo($name, PATHINFO_FILENAME));
$name = preg_replace('/[-_]+/', ' ', $name) ?: '';
return trim($name);
return rtrim((string) Base::instance()->get('paths.media_dir'), '/\\') . DIRECTORY_SEPARATOR . $fileName;
}
private function guessAlt(string $originalName): string
{
$label = trim(pathinfo($originalName, PATHINFO_FILENAME));
$label = preg_replace('/[-_]+/', ' ', $label) ?: '';
return trim($label);
}
}