| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- <?php
- /**
- * Per-gallery editor: settings, share link, proxied bulk uploader
- * (browser → webhost → S3), and image removal.
- */
- require dirname(__DIR__) . '/app/bootstrap.php';
- auth_require();
- $gallery = gallery_load((string)($_GET['g'] ?? ''));
- if ($gallery === null) {
- flash_set('Gallery not found.', 'error');
- redirect('galleries.php');
- }
- $slug = $gallery['slug'];
- if ($_SERVER['REQUEST_METHOD'] === 'POST') {
- csrf_verify();
- $action = $_POST['action'] ?? '';
- if ($action === 'settings') {
- $gallery['title'] = trim((string)($_POST['title'] ?? '')) ?: $gallery['title'];
- $gallery['expires_at'] = trim((string)($_POST['expires_at'] ?? '')) ?: null;
- if (!empty($_POST['remove_password'])) {
- $gallery['password_hash'] = null;
- } elseif (($pw = (string)($_POST['password'] ?? '')) !== '') {
- $gallery['password_hash'] = password_hash($pw, PASSWORD_DEFAULT);
- }
- gallery_save($gallery);
- flash_set('Gallery settings saved.');
- redirect('gallery-edit.php?g=' . rawurlencode($slug));
- }
- if ($action === 'uploads') {
- $mode = (string)($_POST['mode'] ?? '');
- if ($mode === 'enable' && empty($gallery['upload_key'])) {
- $gallery['upload_key'] = random_token(24);
- gallery_save($gallery);
- flash_set('Guest uploads enabled.');
- } elseif ($mode === 'regenerate') {
- $gallery['upload_key'] = random_token(24);
- gallery_save($gallery);
- flash_set('New upload link generated; the old link no longer works.');
- } elseif ($mode === 'disable') {
- $gallery['upload_key'] = null;
- gallery_save($gallery);
- flash_set('Guest uploads disabled.');
- }
- redirect('gallery-edit.php?g=' . rawurlencode($slug));
- }
- if ($action === 'delete-image') {
- $key = (string)($_POST['key'] ?? '');
- foreach ($gallery['images'] ?? [] as $i => $img) {
- if (($img['key'] ?? '') === $key) {
- s3_delete($img['key']);
- if (!empty($img['thumb'])) {
- s3_delete($img['thumb']);
- }
- array_splice($gallery['images'], $i, 1);
- gallery_save($gallery);
- flash_set('Image deleted.');
- break;
- }
- }
- redirect('gallery-edit.php?g=' . rawurlencode($slug));
- }
- }
- // Build the share link from the page the admin is currently on, not from config,
- // so it matches whatever host/path this app is actually served under.
- $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
- $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
- // gallery.php lives one directory up from admin/ (cf. the "../gallery.php" link below).
- $basePath = str_replace('\\', '/', dirname(dirname($_SERVER['SCRIPT_NAME'] ?? '/admin/gallery-edit.php')));
- $basePath = rtrim($basePath, '/');
- $shareUrl = $scheme . '://' . $host . $basePath . '/gallery.php?g=' . rawurlencode($slug);
- // Guest upload link (only when a key is set). Same host/path derivation as above.
- $uploadUrl = !empty($gallery['upload_key'])
- ? $scheme . '://' . $host . $basePath . '/upload.php?g=' . rawurlencode($slug)
- . '&k=' . rawurlencode($gallery['upload_key'])
- : '';
- admin_header($gallery['title'], 'galleries');
- flash_render();
- ?>
- <h1><?= e($gallery['title']) ?></h1>
- <p class="help" style="margin-bottom:1.5rem">
- Share link: <a href="../gallery.php?g=<?= e(rawurlencode($slug)) ?>" target="_blank" rel="noopener"><?= e($shareUrl) ?></a>
- </p>
- <div class="card">
- <h2 style="margin-top:0">Upload images</h2>
- <div class="dropzone" id="dropzone"
- data-api="api.php"
- data-slug="<?= e($slug) ?>"
- data-csrf="<?= e(csrf_token()) ?>"
- data-thumb-size="<?= (int)config('uploads.thumb_size', 600) ?>"
- data-thumb-quality="<?= e((string)config('uploads.thumb_quality', 0.8)) ?>">
- Drop images here or click to select.<br>
- <small>Uploaded through the site to S3, in full resolution, unmodified. One file at a time.</small>
- </div>
- <input type="file" id="file-input" accept="image/*" multiple style="display:none">
- <div class="upload-list" id="upload-list"></div>
- </div>
- <div class="card">
- <h2 style="margin-top:0">Guest uploads</h2>
- <?php if ($uploadUrl !== ''): ?>
- <p class="help" style="margin-bottom:1rem">
- Share this link so guests can upload into this gallery without an admin
- account. It is key-protected and honors the gallery's password and
- expiry, if set.
- </p>
- <p style="margin-bottom:1rem">
- <a href="<?= e($uploadUrl) ?>" target="_blank" rel="noopener"><?= e($uploadUrl) ?></a>
- </p>
- <form method="post" style="display:inline"
- onsubmit="return confirm('Generate a new link? The current link will stop working.')">
- <?= csrf_field() ?>
- <input type="hidden" name="action" value="uploads">
- <input type="hidden" name="mode" value="regenerate">
- <button style="margin:0">Regenerate link</button>
- </form>
- <form method="post" style="display:inline"
- onsubmit="return confirm('Disable guest uploads? The link will stop working.')">
- <?= csrf_field() ?>
- <input type="hidden" name="action" value="uploads">
- <input type="hidden" name="mode" value="disable">
- <button class="btn-danger" style="margin:0">Disable</button>
- </form>
- <?php else: ?>
- <p class="help" style="margin-bottom:1rem">
- Guest uploads are disabled. Enable them to get a shareable link that
- lets people upload into this gallery without an admin account.
- </p>
- <form method="post">
- <?= csrf_field() ?>
- <input type="hidden" name="action" value="uploads">
- <input type="hidden" name="mode" value="enable">
- <button style="margin:0">Enable guest uploads</button>
- </form>
- <?php endif; ?>
- </div>
- <form method="post" class="card">
- <?= csrf_field() ?>
- <input type="hidden" name="action" value="settings">
- <h2 style="margin-top:0">Settings</h2>
- <label for="t">Title</label>
- <input type="text" id="t" name="title" value="<?= e($gallery['title']) ?>">
- <label for="ex">Expiry date (blank = never)</label>
- <input type="date" id="ex" name="expires_at" value="<?= e($gallery['expires_at'] ?? '') ?>">
- <label for="p">Set new password (blank = keep current)</label>
- <input type="text" id="p" name="password" autocomplete="off">
- <?php if (!empty($gallery['password_hash'])): ?>
- <p class="help"><label style="display:inline;text-transform:none;letter-spacing:0">
- <input type="checkbox" name="remove_password" value="1"> Remove password protection
- </label></p>
- <?php endif; ?>
- <button type="submit">Save settings</button>
- </form>
- <h2>Images (<span id="img-count"><?= count($gallery['images'] ?? []) ?></span>)</h2>
- <div class="thumb-row">
- <?php foreach ($gallery['images'] ?? [] as $img): ?>
- <figure>
- <img src="<?= e(s3_presign_get($img['thumb'] ?? $img['key'])) ?>" alt="" loading="lazy">
- <figcaption title="<?= e($img['name'] ?? '') ?>"><?= e($img['name'] ?? '') ?></figcaption>
- <form method="post" onsubmit="return confirm('Delete this image from S3?')">
- <?= csrf_field() ?>
- <input type="hidden" name="action" value="delete-image">
- <input type="hidden" name="key" value="<?= e($img['key']) ?>">
- <button>✕</button>
- </form>
- </figure>
- <?php endforeach; ?>
- </div>
- <script src="../assets/admin.js"></script>
- <?php admin_footer(); ?>
|