gallery-edit.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. /**
  3. * Per-gallery editor: settings, share link, direct-to-S3 bulk uploader,
  4. * and image removal.
  5. */
  6. require dirname(__DIR__) . '/app/bootstrap.php';
  7. auth_require();
  8. $gallery = gallery_load((string)($_GET['g'] ?? ''));
  9. if ($gallery === null) {
  10. flash_set('Gallery not found.', 'error');
  11. redirect('galleries.php');
  12. }
  13. $slug = $gallery['slug'];
  14. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  15. csrf_verify();
  16. $action = $_POST['action'] ?? '';
  17. if ($action === 'settings') {
  18. $gallery['title'] = trim((string)($_POST['title'] ?? '')) ?: $gallery['title'];
  19. $gallery['expires_at'] = trim((string)($_POST['expires_at'] ?? '')) ?: null;
  20. if (!empty($_POST['remove_password'])) {
  21. $gallery['password_hash'] = null;
  22. } elseif (($pw = (string)($_POST['password'] ?? '')) !== '') {
  23. $gallery['password_hash'] = password_hash($pw, PASSWORD_DEFAULT);
  24. }
  25. gallery_save($gallery);
  26. flash_set('Gallery settings saved.');
  27. redirect('gallery-edit.php?g=' . rawurlencode($slug));
  28. }
  29. if ($action === 'delete-image') {
  30. $key = (string)($_POST['key'] ?? '');
  31. foreach ($gallery['images'] ?? [] as $i => $img) {
  32. if (($img['key'] ?? '') === $key) {
  33. s3_delete($img['key']);
  34. if (!empty($img['thumb'])) {
  35. s3_delete($img['thumb']);
  36. }
  37. array_splice($gallery['images'], $i, 1);
  38. gallery_save($gallery);
  39. flash_set('Image deleted.');
  40. break;
  41. }
  42. }
  43. redirect('gallery-edit.php?g=' . rawurlencode($slug));
  44. }
  45. }
  46. $shareUrl = rtrim(config('site.base_url', ''), '/') . '/gallery.php?g=' . rawurlencode($slug);
  47. admin_header($gallery['title'], 'galleries');
  48. flash_render();
  49. ?>
  50. <h1><?= e($gallery['title']) ?></h1>
  51. <p class="help" style="margin-bottom:1.5rem">
  52. Share link: <a href="../gallery.php?g=<?= e(rawurlencode($slug)) ?>" target="_blank" rel="noopener"><?= e($shareUrl) ?></a>
  53. </p>
  54. <div class="card">
  55. <h2 style="margin-top:0">Upload images</h2>
  56. <div class="dropzone" id="dropzone"
  57. data-api="api.php"
  58. data-slug="<?= e($slug) ?>"
  59. data-csrf="<?= e(csrf_token()) ?>"
  60. data-thumb-size="<?= (int)config('uploads.thumb_size', 600) ?>"
  61. data-thumb-quality="<?= e((string)config('uploads.thumb_quality', 0.8)) ?>">
  62. Drop images here or click to select.<br>
  63. <small>Files go directly from your browser to S3, in full resolution, unmodified.</small>
  64. </div>
  65. <input type="file" id="file-input" accept="image/*" multiple style="display:none">
  66. <div class="upload-list" id="upload-list"></div>
  67. </div>
  68. <form method="post" class="card">
  69. <?= csrf_field() ?>
  70. <input type="hidden" name="action" value="settings">
  71. <h2 style="margin-top:0">Settings</h2>
  72. <label for="t">Title</label>
  73. <input type="text" id="t" name="title" value="<?= e($gallery['title']) ?>">
  74. <label for="ex">Expiry date (blank = never)</label>
  75. <input type="date" id="ex" name="expires_at" value="<?= e($gallery['expires_at'] ?? '') ?>">
  76. <label for="p">Set new password (blank = keep current)</label>
  77. <input type="text" id="p" name="password" autocomplete="off">
  78. <?php if (!empty($gallery['password_hash'])): ?>
  79. <p class="help"><label style="display:inline;text-transform:none;letter-spacing:0">
  80. <input type="checkbox" name="remove_password" value="1"> Remove password protection
  81. </label></p>
  82. <?php endif; ?>
  83. <button type="submit">Save settings</button>
  84. </form>
  85. <h2>Images (<span id="img-count"><?= count($gallery['images'] ?? []) ?></span>)</h2>
  86. <div class="thumb-row">
  87. <?php foreach ($gallery['images'] ?? [] as $img): ?>
  88. <figure>
  89. <img src="<?= e(s3_presign_get($img['thumb'] ?? $img['key'])) ?>" alt="" loading="lazy">
  90. <figcaption title="<?= e($img['name'] ?? '') ?>"><?= e($img['name'] ?? '') ?></figcaption>
  91. <form method="post" onsubmit="return confirm('Delete this image from S3?')">
  92. <?= csrf_field() ?>
  93. <input type="hidden" name="action" value="delete-image">
  94. <input type="hidden" name="key" value="<?= e($img['key']) ?>">
  95. <button>✕</button>
  96. </form>
  97. </figure>
  98. <?php endforeach; ?>
  99. </div>
  100. <script src="../assets/admin.js"></script>
  101. <?php admin_footer(); ?>