0 && $text !== '') { $u = commenterByToken($token); if ($u) { commentAdd($photoId, (int)$u['id'], limitText($text, 1000)); } } $redirect = './?photo_id=' . $photoId; if ($sectionId > 0) { $redirect .= '§ion_id=' . $sectionId; } if ($topicId > 0) { $redirect .= '&topic_id=' . $topicId; } if ($token !== '') { $redirect .= '&viewer=' . urlencode($token); } header('Location: ' . $redirect); exit; } $sections = sectionsAll(); $activeSectionId = (int)($_GET['section_id'] ?? 0); $activePhotoId = (int)($_GET['photo_id'] ?? 0); $activeTopicId = (int)($_GET['topic_id'] ?? 0); $welcomeText = settingGet('welcome_text', 'Добро пожаловать в галерею. Выберите раздел слева, чтобы посмотреть фотографии.'); $hasVisibleSections = false; foreach ($sections as $s) { if ((int)($s['photos_count'] ?? 0) > 0) { $hasVisibleSections = true; break; } } $photo = $activePhotoId > 0 ? photoById($activePhotoId) : null; if ($photo && $activeSectionId < 1) { $activeSectionId = (int)$photo['section_id']; } $filterMode = $activeTopicId > 0 ? 'topic' : ($activeSectionId > 0 ? 'section' : 'none'); $comments = $photo ? commentsByPhoto($activePhotoId) : []; $topics = []; $topicCounts = []; $topicTree = []; $hasVisibleTopics = false; try { $topics = topicsAllForSelect(); if ($activeTopicId > 0) { if (!topicById($activeTopicId)) { $activeTopicId = 0; $filterMode = $activeSectionId > 0 ? 'section' : 'none'; } } $topicCounts = topicPhotoCounts(null); $topicTree = buildTopicTreePublic($topics); foreach ($topics as $topicItem) { if ((int)($topicCounts[(int)$topicItem['id']] ?? 0) > 0) { $hasVisibleTopics = true; break; } } } catch (Throwable) { $topics = []; $topicCounts = []; $topicTree = []; $activeTopicId = 0; $filterMode = $activeSectionId > 0 ? 'section' : 'none'; $hasVisibleTopics = false; } $photos = ($activeSectionId > 0 || $activeTopicId > 0) ? photosForPublic($filterMode === 'section' ? $activeSectionId : null, $filterMode === 'topic' ? $activeTopicId : null) : []; $photoCommentCounts = photoCommentCountsByPhotoIds(array_map(static fn(array $p): int => (int)$p['id'], $photos)); $isHomePage = $activeSectionId < 1 && $activePhotoId < 1; $isTopicMode = $filterMode === 'topic'; $isSectionMode = $filterMode === 'section'; $sectionNames = []; foreach ($sections as $s) { $sectionNames[(int)$s['id']] = (string)$s['name']; } $activeTopicName = ''; $activeTopicShortName = ''; foreach ($topics as $t) { if ((int)$t['id'] === $activeTopicId) { $activeTopicName = (string)$t['full_name']; $activeTopicShortName = (string)$t['name']; break; } } $detailTotal = 0; $detailIndex = 0; $prevPhotoId = 0; $nextPhotoId = 0; $detailSectionId = 0; $photoTopics = []; if ($photo) { $detailSectionId = (int)$photo['section_id']; try { $photoTopics = photoTopicsByPhotoId($activePhotoId); } catch (Throwable) { $photoTopics = []; } if ($isTopicMode) { $detailPhotos = photosForPublic(null, $activeTopicId); } else { $detailPhotos = photosForPublic($detailSectionId, null); } if ($activeTopicId > 0 && $detailPhotos !== []) { $foundInTopic = false; foreach ($detailPhotos as $d) { if ((int)$d['id'] === $activePhotoId) { $foundInTopic = true; break; } } if (!$foundInTopic) { $detailPhotos = photosForPublic($detailSectionId, null); $activeTopicId = 0; $isTopicMode = false; $isSectionMode = true; } } $detailTotal = count($detailPhotos); foreach ($detailPhotos as $i => $p) { if ((int)$p['id'] !== $activePhotoId) { continue; } $detailIndex = $i + 1; if ($i > 0) { $prevPhotoId = (int)$detailPhotos[$i - 1]['id']; } if ($i < $detailTotal - 1) { $nextPhotoId = (int)$detailPhotos[$i + 1]['id']; } break; } } $hasMobilePhotoNav = $activePhotoId > 0 && $photo && $detailTotal > 0; $hasMobileCatalogNav = !$photo && ($isTopicMode || $isSectionMode); $bodyClasses = [$isHomePage ? 'is-home' : 'is-inner']; if ($hasMobilePhotoNav || $hasMobileCatalogNav) { $bodyClasses[] = 'has-mobile-nav'; } $detailLocationLabel = ''; if ($activeTopicId > 0 && $activeTopicName !== '') { $detailLocationLabel = 'в тематике «' . $activeTopicName . '»'; } elseif ($detailSectionId > 0 && isset($sectionNames[$detailSectionId])) { $detailLocationLabel = 'в разделе «' . $sectionNames[$detailSectionId] . '»'; } $pageHeading = ''; if ($isTopicMode && $activeTopicShortName !== '') { $pageHeading = $activeTopicShortName; } elseif ($isSectionMode && isset($sectionNames[$activeSectionId])) { $pageHeading = $sectionNames[$activeSectionId]; } elseif ($photo && isset($sectionNames[$detailSectionId])) { $pageHeading = $sectionNames[$detailSectionId]; } $catalogLocationLabel = ''; if ($isTopicMode && $activeTopicName !== '') { $catalogLocationLabel = 'Тема: ' . $activeTopicName; } elseif ($isSectionMode && isset($sectionNames[$activeSectionId])) { $catalogLocationLabel = 'Раздел: ' . $sectionNames[$activeSectionId]; } function h(string $v): string { return htmlspecialchars($v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } function assetUrl(string $path): string { $f=__DIR__ . '/' . ltrim($path,'/'); $v=is_file($f)?(string)filemtime($f):(string)time(); return $path . '?v=' . rawurlencode($v); } function limitText(string $text, int $len): string { return function_exists('mb_substr') ? mb_substr($text, 0, $len) : substr($text, 0, $len); } function buildTopicTreePublic(array $topics): array { $roots = []; $children = []; foreach ($topics as $topic) { $parentId = isset($topic['parent_id']) && $topic['parent_id'] !== null ? (int)$topic['parent_id'] : 0; if ($parentId === 0) { $roots[] = $topic; continue; } if (!isset($children[$parentId])) { $children[$parentId] = []; } $children[$parentId][] = $topic; } foreach ($roots as &$root) { $root['children'] = $children[(int)$root['id']] ?? []; } unset($root); return $roots; } function serveImage(): never { $fileId = (int)($_GET['file_id'] ?? 0); if ($fileId < 1) { http_response_code(404); exit; } $f = photoFileById($fileId); if (!$f) { http_response_code(404); exit; } $abs = __DIR__ . '/' . ltrim((string)$f['file_path'], '/'); if (!is_file($abs)) { http_response_code(404); exit; } if ((string)$f['kind'] !== 'after') { header('Content-Type: ' . ((string)$f['mime_type'] ?: 'application/octet-stream')); header('Content-Length: ' . (string)filesize($abs)); header('Cache-Control: private, max-age=60'); header('X-Robots-Tag: noindex, nofollow'); readfile($abs); exit; } outputWatermarked($abs, (string)$f['mime_type']); } function outputWatermarked(string $path, string $mime): never { $text = 'photo.andr33v.ru'; if (extension_loaded('imagick')) { $im = new Imagick($path); $w = max(1, (int)$im->getImageWidth()); $h = max(1, (int)$im->getImageHeight()); $draw = new ImagickDraw(); $draw->setFillColor(new ImagickPixel('rgba(255,255,255,0.16)')); $draw->setFontSize(max(12, (int)($w / 46))); $draw->setTextAntialias(true); $lineText = $text . ' ' . $text . ' ' . $text; $stepY = max(28, (int)($h / 10)); $stepX = max(120, (int)($w / 3)); for ($y = -$h; $y < $h * 2; $y += $stepY) { for ($x = -$w; $x < $w * 2; $x += $stepX) { $im->annotateImage($draw, $x, $y, -28, $lineText); } } header('Content-Type: ' . ($mime !== '' ? $mime : 'image/jpeg')); $im->setImageCompressionQuality(88); echo $im; $im->clear(); $im->destroy(); exit; } [$w, $h, $type] = @getimagesize($path) ?: [0,0,0]; $img = match ($type) { IMAGETYPE_JPEG => @imagecreatefromjpeg($path), IMAGETYPE_PNG => @imagecreatefrompng($path), IMAGETYPE_GIF => @imagecreatefromgif($path), IMAGETYPE_WEBP => function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($path) : null, default => null, }; if (!$img) { readfile($path); exit; } $font = 2; $color = imagecolorallocatealpha($img, 255, 255, 255, 96); $lineText = $text . ' ' . $text . ' ' . $text; $stepY = max(16, imagefontheight($font) + 8); $stepX = max(120, (int)($w / 3)); $row = 0; for ($y = -$h; $y < $h * 2; $y += $stepY) { $offset = ($row * 22) % $stepX; for ($x = -$w - $offset; $x < $w * 2; $x += $stepX) { imagestring($img, $font, $x, $y, $lineText, $color); } $row++; } header('Content-Type: image/jpeg'); imagejpeg($img, null, 88); imagedestroy($img); exit; } ?> Фотогалерея

0 && $photo): ?>

До обработки
После обработки (watermark)

Комментарии

Комментарии может оставлять только пользователь с персональной ссылкой.

·
0): ?>

В разделе пока нет фотографий.