gallery-modern.php

main 186 lines · 8.8 KB Raw
Alex Alex Commit Initial commit 01/10/2026 09:20
1<?php
2$znxGalH = static fn($v): string => htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8');
3$znxGalDesc = static function (?string $desc): string {
4 $desc = str_replace('\\r', '', (string)$desc);
5 return str_replace('\\n', '<br>', $desc);
6};
7?>
8
9<style>
10.znx-gal{--gal-surface:var(--box-inner-bg,var(--box-bg,var(--nz-panel,var(--wc-bg-2,var(--z-panel-2,var(--s-panel,var(--primary,rgb(30,33,40))))))));--gal-surface-2:color-mix(in srgb,var(--gal-surface) 82%,#000);--gal-well:color-mix(in srgb,var(--gal-surface) 65%,#000);--gal-text:var(--font-color,var(--text,var(--nz-text,var(--wc-text,var(--z-text,var(--s-text,rgb(155,162,177)))))));--gal-muted:color-mix(in srgb,var(--gal-text) 58%,transparent);--gal-border:var(--border,var(--box-inner-border,var(--box-border,var(--nz-border-soft,var(--wc-line,var(--z-border,var(--s-border2,rgb(19,20,23))))))));--gal-accent:var(--accent,var(--link,var(--nz-accent,#d1a233)));--gal-radius:6px;margin:0 0 18px;color:var(--gal-text)}
11.znx-gal *{box-sizing:border-box}
12.znx-gal__head{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin:0 0 12px;padding:14px 16px;border:1px solid var(--gal-border);border-radius:var(--gal-radius);background:var(--gal-surface)}
13.znx-gal__head h1{margin:0 0 5px;font-size:24px;line-height:1.1;color:var(--gal-accent)}
14.znx-gal__head p{margin:0;color:var(--gal-muted);font-size:13px}
15.znx-gal__head form{margin:0}
16.znx-gal-btn{display:inline-flex;align-items:center;justify-content:center;min-height:36px;padding:0 16px;border:1px solid var(--gal-accent);border-radius:var(--gal-radius);background:var(--gal-accent);color:#1a1510;font-weight:800;font-size:13px;cursor:pointer}
17.znx-gal-btn:hover{filter:brightness(1.1)}
18.znx-gal-empty{padding:30px 16px;text-align:center;color:var(--gal-muted);border:1px dashed var(--gal-border);border-radius:var(--gal-radius);background:var(--gal-surface-2)}
19.znx-gal-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));align-items:stretch;gap:14px}
20.znx-gal-card{display:flex;height:100%;flex-direction:column;overflow:hidden;border:1px solid var(--gal-border);border-radius:var(--gal-radius);background:var(--gal-surface-2)}
21.znx-gal-card__media{display:block;aspect-ratio:16/10;overflow:hidden;background:var(--gal-well)}
22.znx-gal-card__media img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .2s ease}
23.znx-gal-card__media:hover img{transform:scale(1.03)}
24.znx-gal-card__body{padding:12px 14px 14px}
25.znx-gal-card__title{margin:0 0 6px;font-size:14.5px;font-weight:800;color:var(--gal-text)}
26.znx-gal-card__desc{margin:0;font-size:12.5px;line-height:1.5;color:var(--gal-muted)}
27.znx-gal-panel{max-width:560px;margin:0 0 18px;padding:18px 20px;border:1px solid var(--gal-border);border-radius:var(--gal-radius);background:var(--gal-surface)}
28.znx-gal-panel h1{margin:0 0 4px;font-size:20px;color:var(--gal-accent)}
29.znx-gal-panel > p{margin:0 0 16px;color:var(--gal-muted);font-size:13px}
30.znx-gal-field{margin:0 0 14px}
31.znx-gal-field label{display:block;margin:0 0 6px;font-size:12.5px;font-weight:700;color:var(--gal-muted)}
32.znx-gal-field input[type=file],.znx-gal-field input[type=text],.znx-gal-field textarea{width:100%;padding:8px 10px;border:1px solid var(--gal-border);border-radius:var(--gal-radius);background:var(--gal-well);color:var(--gal-text);font:inherit}
33.znx-gal-field textarea{resize:vertical}
34.znx-gal-notice{max-width:560px;margin:0 0 18px;padding:16px 18px;border:1px solid var(--gal-border);border-radius:var(--gal-radius);background:var(--gal-surface)}
35.znx-gal-notice h1{margin:0 0 6px;font-size:19px;color:var(--gal-accent)}
36.znx-gal-notice p{margin:0;color:var(--gal-muted);font-size:13px}
37.znx-gal-preview{max-width:420px;margin:16px 0 0}
38.znx-gal-preview h2{margin:0 0 10px;font-size:13px;text-transform:uppercase;letter-spacing:.05em;color:var(--gal-muted)}
39</style>
40
41<?php if ($logged_in === true && !empty($_POST['new'])): ?>
42
43 <section class="znx-gal">
44 <div class="znx-gal-panel">
45 <h1><?= $znxGalH(t('gallery.create')) ?></h1>
46 <p><?= $znxGalH(t('gallery.powered')) ?></p>
47 <form action="" method="post" enctype="multipart/form-data">
48 <div class="znx-gal-field">
49 <label for="imagefile"><?= $znxGalH(t('gallery.select')) ?></label>
50 <input type="file" name="imagefile" id="imagefile">
51 </div>
52 <div class="znx-gal-field">
53 <label for="galleryTitle"><?= $znxGalH(t('gallery.image_title')) ?></label>
54 <input type="text" name="title" id="galleryTitle" size="70">
55 </div>
56 <div class="znx-gal-field">
57 <label for="galleryDesc"><?= $znxGalH(t('gallery.image_desc')) ?></label>
58 <textarea name="desc" id="galleryDesc" cols="55" rows="8"></textarea>
59 </div>
60 <button type="submit" class="znx-gal-btn" name="submit"><?= $znxGalH(t('gallery.upload')) ?></button>
61 </form>
62 </div>
63 </section>
64
65<?php endif; ?>
66
67<?php if ($logged_in === true && isset($_FILES['imagefile']) && !empty($_FILES['imagefile'])): ?>
68 <?php
69 $upload = $_FILES['imagefile'];
70 if (($upload['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK
71 || !is_uploaded_file((string)$upload['tmp_name'])
72 || (int)$upload['size'] > 5 * 1024 * 1024
73 || !getimagesize($upload['tmp_name'])
74 ): ?>
75 <section class="znx-gal">
76 <div class="znx-gal-notice">
77 <h1><?= $znxGalH(t('gallery.failed')) ?></h1>
78 <p><?= $znxGalH(t('gallery.failed_text')) ?></p>
79 </div>
80 </section>
81 <?php else:
82 $image = file_get_contents($upload['tmp_name']);
83 $imgurClientID = $config['gallery']['Client ID'];
84
85 $ch = curl_init();
86 curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image/');
87 curl_setopt($ch, CURLOPT_HEADER, false);
88 curl_setopt($ch, CURLOPT_POST, true);
89 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
90 curl_setopt($ch, CURLOPT_POSTFIELDS, array(
91 'type' => 'file',
92 'name' => $upload['name'],
93 'image' => $image,
94 ));
95 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
96 "Authorization: Client-ID {$imgurClientID}",
97 ));
98 $response = json_decode(curl_exec($ch));
99 $image_url = $response->data->link ?? false;
100 $image_delete = $response->data->deletehash ?? '';
101 $title = $_POST['title'] ?? '';
102 $desc = $_POST['desc'] ?? '';
103
104 if ($image_url !== false):
105 $inserted = insertImage((int)$session_user_id, $title, $desc, $image_url, $image_delete);
106 if ($inserted === true):
107 $safeTitle = $znxGalH($title);
108 ?>
109 <section class="znx-gal">
110 <div class="znx-gal-notice">
111 <h1><?= $znxGalH(t('gallery.posted')) ?></h1>
112 <p><?= $znxGalH(t('gallery.posted_text')) ?></p>
113 <div class="znx-gal-preview">
114 <h2><?= $znxGalH(t('gallery.preview')) ?></h2>
115 <div class="znx-gal-card">
116 <a class="znx-gal-card__media" href="<?= $znxGalH($image_url) ?>" target="_blank">
117 <img src="<?= $znxGalH($image_url) ?>" alt="<?= $safeTitle ?>">
118 </a>
119 <div class="znx-gal-card__body">
120 <h3 class="znx-gal-card__title"><?= $safeTitle ?></h3>
121 <p class="znx-gal-card__desc"><?= $znxGalDesc($znxGalH($desc)) ?></p>
122 </div>
123 </div>
124 </div>
125 </div>
126 </section>
127 <?php
128 else: ?>
129 <section class="znx-gal">
130 <div class="znx-gal-notice">
131 <h1><?= $znxGalH(t('gallery.exists')) ?></h1>
132 <p><?= $znxGalH(t('gallery.exists_text')) ?></p>
133 </div>
134 </section>
135 <?php endif;
136 else: ?>
137 <section class="znx-gal">
138 <div class="znx-gal-notice">
139 <h1><?= $znxGalH(t('gallery.failed')) ?></h1>
140 <p><?= $znxGalH(t('gallery.failed_text')) ?></p>
141 </div>
142 </section>
143 <?php endif;
144 endif; ?>
145<?php endif; ?>
146
147<?php if (empty($_POST)): ?>
148
149 <section class="znx-gal">
150 <header class="znx-gal__head">
151 <div>
152 <h1><?= $znxGalH(t('gallery.title')) ?></h1>
153 <?php if ($logged_in === true): ?><p><?= $znxGalH(t('gallery.invite')) ?></p><?php endif; ?>
154 </div>
155 <?php if ($logged_in === true): ?>
156 <form action="" method="post">
157 <button type="submit" class="znx-gal-btn" name="new" value="1"><?= $znxGalH(t('gallery.add')) ?></button>
158 </form>
159 <?php endif; ?>
160 </header>
161
162 <?php if (is_array($images) && !empty($images)): ?>
163 <div class="znx-gal-grid">
164 <?php foreach ($images as $image): ?>
165 <article class="znx-gal-card">
166 <a class="znx-gal-card__media" href="<?= $znxGalH($image['image']) ?>" target="_blank">
167 <img src="<?= $znxGalH($image['image']) ?>" alt="<?= $znxGalH($image['title']) ?>" loading="lazy">
168 </a>
169 <div class="znx-gal-card__body">
170 <h3 class="znx-gal-card__title"><?= $znxGalH($image['title']) ?></h3>
171 <p class="znx-gal-card__desc"><?= $znxGalDesc($znxGalH($image['desc'])) ?></p>
172 </div>
173 </article>
174 <?php endforeach; ?>
175 </div>
176 <?php else: ?>
177 <div class="znx-gal-empty"><?= $znxGalH(t('gallery.empty')) ?></div>
178 <?php endif; ?>
179
180 <?php if ($logged_in === false): ?>
181 <p style="margin-top:14px;color:var(--gal-muted,var(--color-default,#968452));"><?= $znxGalH(t('gallery.need_login')) ?></p>
182 <?php endif; ?>
183 </section>
184
185<?php endif; ?>
186
Top