&$images) { $categoryThumbDir = $thumbsDir . '/' . $categoryName; if (!is_dir($categoryThumbDir)) { mkdir($categoryThumbDir, 0775, true); } foreach ($images as &$image) { $sourcePath = $image['abs_path']; $sourceMtime = (int) filemtime($sourcePath); $maxTimestamp = max($maxTimestamp, $sourceMtime); $thumbExt = 'jpg'; $thumbName = pathinfo($image['filename'], PATHINFO_FILENAME) . '.jpg'; $thumbAbsPath = $categoryThumbDir . '/' . $thumbName; $thumbWebPath = 'thumbs/' . rawurlencode($categoryName) . '/' . rawurlencode($thumbName); $needsThumb = !file_exists($thumbAbsPath) || filemtime($thumbAbsPath) < $sourceMtime || $sourceMtime > $lastIndexedTimestamp; if ($needsThumb) { createThumbnail($sourcePath, $thumbAbsPath, THUMB_WIDTH, THUMB_HEIGHT); } $image['thumb_path'] = $thumbWebPath; $image['full_path'] = '?action=image&category=' . rawurlencode($categoryName) . '&file=' . rawurlencode($image['filename']); $image['mtime'] = $sourceMtime; } usort($images, static function (array $a, array $b): int { return $b['mtime'] <=> $a['mtime']; }); } unset($images, $image); if ($maxTimestamp > $lastIndexedTimestamp) { file_put_contents($lastIndexedFile, (string)$maxTimestamp); } $selectedCategory = isset($_GET['category']) ? trim((string)$_GET['category']) : null; if ($selectedCategory !== null && $selectedCategory !== '' && !isset($categories[$selectedCategory])) { http_response_code(404); $selectedCategory = null; } ?> Фотогалерея

Фотогалерея

Категории и превью обновляются автоматически при каждом открытии страницы

Категории

Пока нет папок с фото. Загрузите файлы в photos/<категория>/ через FTP.

$images): ?> фото

В этой категории пока нет изображений.

$filename, 'abs_path' => $absPath, ]; } $result[$entry] = $images; } ksort($result, SORT_NATURAL | SORT_FLAG_CASE); return $result; } function isImage(string $path): bool { $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION)); return in_array($ext, ['jpg', 'jpeg', 'png', 'webp', 'gif'], true); } function createThumbnail(string $srcPath, string $thumbPath, int $targetWidth, int $targetHeight): void { if (extension_loaded('imagick')) { createThumbnailWithImagick($srcPath, $thumbPath, $targetWidth, $targetHeight); return; } createThumbnailWithGd($srcPath, $thumbPath, $targetWidth, $targetHeight); } function createThumbnailWithImagick(string $srcPath, string $thumbPath, int $targetWidth, int $targetHeight): void { $imagick = new Imagick($srcPath); $imagick->setIteratorIndex(0); $imagick->setImageOrientation(Imagick::ORIENTATION_UNDEFINED); $imagick->thumbnailImage($targetWidth, $targetHeight, true, true); $imagick->setImageFormat('jpeg'); $imagick->setImageCompressionQuality(82); $imagick->writeImage($thumbPath); $imagick->clear(); $imagick->destroy(); } function createThumbnailWithGd(string $srcPath, string $thumbPath, int $targetWidth, int $targetHeight): void { [$srcW, $srcH, $type] = @getimagesize($srcPath) ?: [0, 0, 0]; if ($srcW < 1 || $srcH < 1) { return; } $src = match ($type) { IMAGETYPE_JPEG => @imagecreatefromjpeg($srcPath), IMAGETYPE_PNG => @imagecreatefrompng($srcPath), IMAGETYPE_GIF => @imagecreatefromgif($srcPath), IMAGETYPE_WEBP => function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($srcPath) : null, default => null, }; if (!$src) { return; } $scale = min($targetWidth / $srcW, $targetHeight / $srcH); $dstW = max(1, (int) floor($srcW * $scale)); $dstH = max(1, (int) floor($srcH * $scale)); $dst = imagecreatetruecolor($dstW, $dstH); imagecopyresampled($dst, $src, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH); imagejpeg($dst, $thumbPath, 82); imagedestroy($src); imagedestroy($dst); }