Ricard's code gists


PHP Image Gallery

Uses PHP to create an image gallery with the given file and folder structure. No need for metadata or database, just reads the disk and builds the gallery

<?php
/**
======================================
General
======================================
- Requirements: php 7
======================================
Settings
======================================
- RANDOMIZE (default: true) // Order in main view
- ALBUMS (default: uploads) // Path to the folder
======================================
Content structure
======================================
- index.php (this file, or any other file name)
The galleries are regular folders with images files:
"./uploads/folder_name/image.jpg"
======================================
?>

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Gallery</title>
</head>

<body>
  <main>
    <header>
      <div class="navbar navbar-dark bg-dark shadow-sm">
        <div class="container">
          <div class="navbar-brand d-flex align-items-center">
            <a href="?" class="text-white text-decoration-none"><strong>Gallery</strong></a>
          </div>
        </div>
      </div>
    </header>

    <section class="container pt-2">
      <div class="row">
        <?php
          define('RANDOMIZE', true);
          define('ALBUMS', 'uploads');
          $extensions = "jpg,jpeg,png,webp";
          $isAlbum = isset($_GET["album"]) ? true : false;

          function getFilePath($fileName) {
            return ALBUMS . "/" . $_GET["album"]. "/" . $fileName;
          }

          $folder = ALBUMS;
          if ($isAlbum) {
            $folder = $folder . "/" . $_GET["album"];
          }

          // Create recursive dir iterator which skips dot folders
          $dir = new RecursiveDirectoryIterator($folder,
          FilesystemIterator::SKIP_DOTS);

          // Flatten the recursive iterator, folders come before their files
          $it  = new RecursiveIteratorIterator($dir,
          RecursiveIteratorIterator::SELF_FIRST);

          // Maximum depth is 1 level deeper than the base folder
          $it->setMaxDepth(1);

          $images = [];
          $albums = [];

          // Basic loop displaying different messages based on file or folder

          if ($isAlbum) {

            foreach ($it as $fileinfo) {
              if ($fileinfo->isFile()) {
                array_push($images, getFilePath($it->getFilename()));
              }
            }
          } else {
            foreach ($it as $fileinfo) {
              if ($fileinfo->isDir()) {
                array_push($albums, $fileinfo->getFilename());
              }
            }
          }

          if ($isAlbum) {
            natsort($images);
            foreach ($images as $image) {
              echo "<div>";
              echo "<img class='img-fluid img-thumbnail mb-2 mx-auto d-block' src='" . $image . "' alt='" . $image . "' />";
              echo "</div>";
            }
          } else {
            // List all directories
            if (RANDOMIZE) {
              shuffle($albums);
            } else {
              sort($albums);
            }
            foreach ($albums as $key => $album) {
              $files = glob("./" . ALBUMS . "/" . $album . "/*.{" . $extensions . "}", GLOB_BRACE);

              $featuredImageSrc = $files[shuffle($files)];

              $image = "<img class='img-thumbnail mb-2' src='" . $featuredImageSrc . "'>";
              $content = $image . "<small>".$album."</small>";

              echo "<div class='col-6 col-sm-4 col-lg-2 mb-4'>";
              printf("<a href='?album=%s'>%s</a>", $album, $content);
              echo "</div>";
            }
          }
        ?>
      </div>
    </section>

   <footer class="container mt-4 mb-4">
      <div class="row">
        <div class="col-12">
          <hr>
        </div>
        <div class="col d-grid gap-2">
          <?php if ($isAlbum) { ?>
            <a href="?" class="btn btn-primary btn-block">Go back</a>
          <?php } ?>
        </div>
      </div>
   </footer>
  </main>
</body>

</html>