view mgallery.php @ 332:ffcd1225e85c

Rename PID variable.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 21 Nov 2022 12:20:35 +0200
parents 782c1520984e
children 9dece4d00e30
line wrap: on
line source

<?php
//
// Yet Another Image Gallery
// -- Main PHP file
// Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org>
// (C) Copyright 2015-2022 Tecnic Software productions (TNSP)
//
require "mgallery.inc.php";

$pageLang = "fi";
$pageLanguages =
[
  "fi" => "FIN",
  "en" => "ENG",
];


$pageTranslations =
[
  "gallery_error" => [
    "fi" => "Tapahtui virhe",
    "en" => "An error occured",
  ],

  "invalid_gallery_path" => [
    "fi" => "Gallerian tiedostopolkua <b>%1</b> ei ole olemassa.",
    "en" => "Gallery path <b>%1</b> does not exist or is invalid.",
  ],

  "view_best_quality" => [
    "fi" => "Näytä paremmalla laadulla",
    "en" => "View better quality version",
  ],

  "gallery_nimages" => [
    "fi" => "kuvaa",
    "en" => "images",
  ],

  "gallery_nsubalbums" => [
    "fi" => "albumia",
    "en" => "albums",
  ],

  "page_info_button_title" => [
    "fi" => "Näytä gallerian navigointi.",
    "en" => "Show gallery navigation.",
  ],

  "page_up_navi_button_title" => [
    "fi" => "Takaisin galleriasivulle.",
    "en" => "Back to gallery page.",
  ],
];


//
// Various utility functions
//
function mgSetCookie($name, $value)
{
  global $galBaseURL;
  setcookie($name, $value, time() + 365*24*60*60, $galBaseURL); // expire in a year
}


function mgQM($msg)
{
  global $pageTranslations, $pageLang;

  if (isset($pageTranslations[$msg]) && isset($pageTranslations[$msg][$pageLang]))
    $str = $pageTranslations[$msg][$pageLang];
  else
    $str = $msg;

  foreach (func_get_args() as $argn => $argv)
    $str = preg_replace("/\%".$argn."/", $argv, $str);
  return $str;
}


function mgTrimIfString($val)
{
  if (is_string($val))
    return trim($val);
  else
    return $val;
}


function mgGetRequestItem($name, $default = "", $allowGet = FALSE)
{
  if ($allowGet)
    return isset($_REQUEST[$name]) ? mgTrimIfString($_REQUEST[$name]) : $default;
  else
    return isset($_POST[$name]) ? mgTrimIfString($_POST[$name]) : $default;
}


function chentities($str)
{
  return htmlspecialchars($str, ENT_NOQUOTES, "UTF-8");
}


function dhentities($str)
{
  return htmlspecialchars($str, ENT_COMPAT, "UTF-8");
}


function mgGetTrans($val, $filter = NULL)
{
  global $pageLang;

  if (is_array($val))
    $str = array_key_exists($pageLang, $val) ? $val[$pageLang] : reset($val);
  else
    $str = $val;

  if (is_callable($filter))
    return call_user_func($filter, $str);
  else
    return $str;
}


function mgMangleURI($filename)
{
  global $mgalDebug;
  return $filename.($mgalDebug ? "?".sha1(time()) : "");
}


function mgGetCSSLine($filename, $media = FALSE)
{
  return
    "  <link rel=\"stylesheet\" href=\"".mgMangleURI($filename).
    "\" type=\"text/css\" ".($media !== FALSE ? "media=\"".$media."\"": "")." />\n";
}


function mgGetJSLine($filename)
{
  return
    "  <script src=\"".mgMangleURI($filename)."\"></script>\n";
}


function mgIncludeUrchin($filename)
{
  if (file_exists($filename))
    require_once $filename;
}


function mgPrintPageHeader($pageTitle, $pageDivID)
{
  global $pageCSS, $pageCharset, $pageUrchin, $pageJS, $pageLang;

  echo
    "<!DOCTYPE html>\n".
    "<html lang=\"".$pageLang."\">\n".
    "<head>\n".
    "  <meta charset=\"".$pageCharset."\">\n".
    // Setting the viewport makes things break especially with the
    // text-size-adjust CSS settings... so we don't use it.
    // XXX: We do now. For now.
    "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n".
    "  <title>".strip_tags($pageTitle)."</title>\n".
    (is_array($pageJS) ? implode("", array_map('mgGetJSLine', $pageJS)) : mgGetJSLine($pageJS)).
    (is_array($pageCSS) ? implode("", array_map('mgGetCSSLine', $pageCSS)) : mgGetCSSLine($pageCSS, FALSE)).
    "</head>\n".
    "<body>\n";

  if ($pageUrchin !== NULL)
  {
    if (is_array($pageUrchin))
    {
      foreach ($pageUrchin as $filename)
        mgIncludeUrchin($filename);
    }
    else
      mgIncludeUrchin($pageUrchin);
  }

  echo
    "<div id=\"".$pageDivID."\">\n";
}


function mgPrintPageFooter()
{
  if (($str = mgGetSetting("page_info")) !== FALSE)
    echo "<div id=\"pageInfoFooter\">".$str."</div>";

  echo
    "\n</div>\n</body>\n</html>\n";
}


function mgGetImageTitleStr(&$data, $filename)
{
  return
    chentities($filename).
    mgGetArr($data, "datetime", " - %1", "", "mgTimeStr");
}


function mgGetImageURL($galPath, $fpath, $filename, $ffmt)
{
  global $galImageURL;
  return mgCleanPathStr($galImageURL.$galPath."/".$fpath.$filename.".".$ffmt);
}


function mgGetURL($path, $image, $entities = TRUE)
{
  global $galBaseURL, $galCleanURLS;
  $amp = $entities ? "&amp;" : "&";

  if ($galCleanURLS)
  {
    $url = $galBaseURL.$path."/".($image !== FALSE ? $image : "");
  }
  else
  {
    $url =
      $galBaseURL.mgGetSetting("mgallery_php")."?path=".
      $path.($image !== FALSE ? $amp."image=".$image : "");
  }

  return mgCleanPathStr($url);
}


function mgGetNaviActive($galPath, &$galIndex, $index, $delta, &$res, $entities)
{
  $res = $index + $delta;

  if ($res >= 0 && $res <= sizeof($galIndex) - 1)
    return mgGetURL($galPath, $galIndex[$res], $entities);
  else
    return FALSE;
}


function mgGetNaviControlImage($galPath, &$galIndex, &$galEntries, $index, $class, $url)
{
  global $galTNPath, $galTNFormat;

  if ($url !== FALSE)
  {
    $imgName = $galIndex[$index];
    $imgEntry = $galEntries[$imgName];
    $imgPath = isset($imgEntry["path"]) ? $imgEntry["path"] : $galPath;
    return
      "<div class=\"imageCtrl ".$class."\">".
      "<a href=\"".$url."\"><img src=\"".
      mgGetImageURL($imgPath, $galTNPath, $imgName, $galTNFormat).
      "\" alt=\"".$galIndex[$index]."\" /></a></div>";
  }
  else
    return "";
}


function mgGetNaviControlImageBox($galPath, &$galIndex, &$galEntries, $index, $class, $delta)
{
  $url = mgGetNaviActive($galPath, $galIndex, $index, $delta, $res, TRUE);
  return mgGetNaviControlImage($galPath, $galIndex, $galEntries, $res, $class, $url);
}


function mgGetNaviControlImageBoxJS($galPath, &$galIndex, &$galEntries, $index, $class, $delta)
{
  $str = mgGetNaviControlImageBox($galPath, $galIndex, $galEntries, $index, $class, $delta);

  if ($str != "")
    return
    "<script>".
    "document.write(\"".str_replace("\"", "\\\"", $str)."\");".
    "</script>";
  else
    return "";
}


function mgPrintTable($class, $galPath, &$galEntries, &$galIndex, $start, $limit)
{
  global $galAlbumIcon, $galTNPath, $galTNFormat,
         $galImageURL, $galUseCoverImages;

  $galCount = count($galIndex);
  if ($start >= $galCount)
    return $start;

  $end = ($limit === FALSE) ? $galCount : $start + $limit;
  if ($end > $galCount) $end = $galCount;

  echo "<div class=\"galleryTable ".$class."\">\n";

  for ($index = $start; $index < $end; $index++)
  {
    $filename = &$galIndex[$index];
    $data = &$galEntries[$filename];

    echo "  <div class=\"galleryEntry\">\n";

    if ($data["type"] == 0)
    {
      echo
        "    <div class=\"imageBox\" title=\"".mgGetImageTitleStr($data, $filename).
        "\"><a href=\"".mgGetURL($galPath, $filename)."\"><img src=\"".
        mgGetImageURL(isset($data["path"]) ? $data["path"] : $galPath, $galTNPath, $filename, $galTNFormat).
        "\" alt=\"".dhentities($filename)."\"></a></div>\n".
        mgGetArr($data, "caption", "    <div class=\"imageCaption\">%1</div>\n", "", "chentities");
/*
      if ($mode == "")
      {
      echo
        "  <select class=\"dropdown\" id=\"dd".$data["base"]."\" name=\"dd".$data["base"].
        "\" onchange=\"mgalPhotoDataChanged('".$data["base"]."');\">\n";

      foreach ($picChoices as $name => $value)
      {
        echo "   <option value=\"$value\"".($value == $data["id"] ? " selected=\"selected\"" : "").">".chentities($name)."</option>\n";
      }
      echo
        "  </select>\n";
      }
*/
    }
    else
    {
      if ($galUseCoverImages && isset($data["image"]))
      {
        // Recursively determine the album cover image
        $ptmp = [$galPath, $filename];
        $curr = &$data;
        while (is_array($curr["image"]))
        {
          $curr = &$curr["image"];
          $ptmp[] = $curr["base"];
        }

        $ptmp[] = $galTNPath;
        $ptmp[] = $curr["image"];

        $atmp = mgCleanPathStr($galImageURL.implode("/", mgCleanPathArray(TRUE, 0, count($ptmp), $ptmp)).".".$galTNFormat);
      }
      else
        // No album cover, use default
        $atmp = $galAlbumIcon;

      echo
        "    <a href=\"".mgGetURL(mgCleanPath(TRUE, $galPath, $filename), FALSE)."\">".
        "<img class=\"albumIcon\" src=\"".$atmp."\" alt=\"".
        mgGetTrans($data["caption"], "dhentities").
        "\" />\n".
        "    <div class=\"albumTitle\">".
        mgGetTrans($data["caption"], "chentities").
        "</div></a>\n";
    }

    echo "  </div>\n";
  }

  echo "</div>\n";
  return $index;
}


function mgTimeStr($stamp)
{
  global $pageLang, $pageCharset;
  $pageLocale = strtolower($pageLang)."_".strtoupper($pageLang).".".$pageCharset;
  setlocale(LC_TIME, $pageLocale);
  return strftime("%d %b %Y (%H:%M:%S)", ($stamp instanceOf DateTime) ? $stamp->getTimestamp() : $stamp);
}


function mgFileSize($size)
{
  foreach ([1024*1024 => "MiB", 1024 => "kiB"] as $mdiv => $mpost)
  {
    if ($size > $mdiv)
      return sprintf("%1.2f %s", $size / $mdiv, $mpost);
  }
  return sprintf("%d bytes", $size);
}


function mgGetPageInfoHeaderStart($class = NULL)
{
  return "<div id=\"pageInfoHeader\"".($class != NULL ? " class=\"".$class."\"" : "").">\n";
}


function mgGetPageInfoHeaderEnd()
{
  global $pageLang, $pageLanguages;

  $str = "<div id=\"languages\">";

  if (isset($pageLanguages) && is_array($pageLanguages))
  {
    foreach ($pageLanguages as $id => $lang)
      $str .= "<a class=\"lang_".$id."\" href=\"?lang=".$id."\">".$lang."</a>";
  }

  return $str.
    "</div>\n".
    "</div>\n";
}


function mgGetBreadCrump($class, &$pdata)
{
  return
    "<a class=\"".$class."\" href=\"".mgGetURL($pdata["path"], FALSE)."\">".
    mgGetTrans($pdata["caption"], "chentities").
    "</a>";
}


function mgPrintBreadCrumbs($galData)
{
  $res = [];
  if ($galData["caption"])
    $res[] = mgGetBreadCrump("naviBreadCrumbCurr", $galData);

  $tmp = $galData;
  while (isset($tmp["parent"]))
  {
    $pdata = $tmp["parent"];
    $res[] = mgGetBreadCrump("naviBreadCrumbItem", $pdata);
    $tmp = $tmp["parent"];
  }

  if (count($res) > 1)
  {
    echo
      "<div id=\"naviBreadCrumbs\">".
      implode("<span class=\"naviBreadCrumbSep\"></span>", array_reverse($res)).
      "</div>\n";
  }
}


function mgGetArrStr($data, $skeys, $sfmt1, $func = NULL)
{
  return mgGetArr($data, $skeys, $sfmt1, NULL, ($func == NULL) ? "chentities" : $func);
}


//
// Global locale initialization
//
if (!isset($localeInited) || !$localeInited)
{
  $localeInited = TRUE;
  $pageCharset = "UTF-8";

  $tmp = "en_US.".strtolower(str_replace("-", "", $pageCharset));
  setlocale(LC_ALL, $tmp);
}


//
// Read and process gallery settings
//
if (mgReadSettings($searchPaths) === FALSE)
{
  mgPrintPageHeader("Internal error!", "galleryPage");

  echo
    "<h1>Internal error!</h1>\n".
    "<p>Could not find MGallery configuration file.</p>";

  mgPrintPageFooter();
  exit;
}

$pageCSS = mgGetSetting("css");
$pageJS = mgGetSetting("js_file");
$pageUrchin = mgGetSetting("urchin_file");
$galBasePath = mgGetSetting("base_path");
$galBaseURL = mgGetSetting("base_url");
$galImageURL = mgGetSetting("image_url", mgGetSetting("base_url"));

$galUseCoverImages = mgGetSetting("cover_images");

$galAlbumIcon = mgGetSetting("album_icon");
$galCleanURLS = mgGetSetting("clean_urls");
$galTNPath = mgGetSetting("tn_path");
$galMedPath = mgGetSetting("med_path");
$galTitlePrefix = mgGetSetting("title_prefix");
$galTitleSep = mgGetSetting("title_sep");

$galMode = mgGetRequestItem("mode", "view", TRUE);
$galPath = mgGetRequestItem("path", ".", TRUE);
$galPageIndex = intval(mgGetRequestItem("index", 0, TRUE));
$galImage = mgGetRequestItem("image", FALSE, TRUE);

if (is_string($galImage))
  $galImage = basename($galImage);

if (($pageTimeZone = mgGetSetting("timezone")) !== NULL)
  date_default_timezone_set($pageTimeZone);


// Check language setting
if (($tmp = mgGetRequestItem("lang", FALSE, TRUE)) !== FALSE)
{
  $tmp = strtolower($tmp);
  if (array_key_exists($tmp, $pageLanguages))
  {
    $pageLang = $tmp;
    mgSetCookie("mglang", $tmp);
  }
}
else
if (isset($_COOKIE["mglang"]))
{
  $tmp = strtolower($_COOKIE["mglang"]);
  if (array_key_exists($tmp, $pageLanguages))
    $pageLang = $tmp;
}


//
// Attempt to read the data cache file
//
$filename = mgGetPath(mgCleanPath(TRUE, $galBasePath, $galPath), "cache_file");
$filename2 = mgGetPath(mgCleanPath(FALSE, $galBasePath, $galPath), "cache_file");
if ($filename == $filename2 && file_exists($filename) && ($fp = @fopen($filename, "rb")) !== FALSE)
{
  if (flock($fp, LOCK_SH))
  {
    require($filename);
    flock($fp, LOCK_UN);
  }
  fclose($fp);
}

// Check for chosen backend mode
if (($galBackend = mgGetSetting("backend")) === null)
  die("MGallery backend mode not set.\n");

switch ($galBackend = strtolower($galBackend))
{
  case "sql":
    // If SQL backend, and gallery is virtual, attempt a select
    if (isset($galData["virtual"]))
    {
      // Connect to database
      if (mgConnectSQLDB() === FALSE)
        die("Could not open database connection.\n");

      $asql = ["SELECT * FROM images ".
        "LEFT JOIN paths ON images.path_id=paths.id ".
        "WHERE"];

      $ccmds = preg_split("/\s*([,|])\s*/",
        strtolower($galData["virtual"]), -1,
        PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

      foreach ($ccmds as $ccmd)
      switch ($ccmd)
      {
        case "keyword":
          if (!isset($galData["v_keyword"]))
            die("Invalid definition.\n");

          $asql[] = mgPrepareSQL(
            "images.id IN (SELECT image_id FROM images_meta ".
            "LEFT JOIN metadata ON images_meta.meta_id=metadata.id ".
            "WHERE metadata.field='keywords' AND data=%s)",
            $galData["v_keyword"]);
          break;

        case "month_range":
          if (!isset($galData["v_month_begin"]) ||
              !isset($galData["v_month_end"]))
            die("Invalid definition.\n");

          $asql[] = mgPrepareSQL(
            "date_part('month', datetime) BETWEEN %d AND %d",
            $galData["v_month_begin"],
            $galData["v_month_end"]);
          break;

        case "date_range":
          if (!isset($galData["v_date_begin"]) ||
              !isset($galData["v_date_end"]))
            die("Invalid definition.\n");

          $asql[] = mgPrepareSQL(
            "datetime BETWEEN %s AND %s",
            $galData["v_date_begin"],
            $galData["v_date_end"]);
          break;

        case "year":
          if (!isset($galData["v_year"]))
            die("Invalid definition.\n");

          // Laatuklunssi
          $v_year = strtolower($galData["v_year"]);
          if (substr($v_year, 0, 7) == "parent:")
          {
            if (isset($galData["parent"]))
            {
              $v_field = substr($v_year, 7);
              if (isset($galData["parent"]["caption"]))
                $galData["v_year"] = $galData["parent"][$v_field];
              else
                die("Foobar\n");
            }
            else
              die("Fazboo\n");
          }

          $asql[] = mgPrepareSQL(
            "date_part('year', datetime)=%d",
            $galData["v_year"]);
          break;

        case "|":
          $asql[] = "OR";
          break;

        case ",":
          $asql[] = "AND";
          break;

        default:
          die("Invalid virtual gallery definition.\n");
      }

      $asql[] = "ORDER BY datetime DESC";
      $sql = implode(" ", $asql);

      // Query images for this gallery
      $galData["header"] .= "<p>".$sql."</p>";

      if (($res = mgExecSQL($sql)) === FALSE)
        die("Could not execute virtual gallery.\n");

      // Push the entries into our data structures
      foreach ($res as $entry)
      if (!in_array($entry["filename"], $galImagesIndex))
      {
        $entry["datetime"] = mgSQLToDateTime($db, $entry["datetime"]);
        $entry["type"] = 0;

        $galEntries[$entry["filename"]] = $entry;
        $galImagesIndex[] = $entry["filename"];
      }
    }
    //print_r($galEntries);
    break;

  case "php":
    break;

  default:
    die("Invalid MGallery backend mode '".$galBackend."'.\n");
}


// If no data available, show an error page
if (!isset($galData) || !isset($galEntries) ||
    !isset($galAlbumsIndex) || !isset($galImagesIndex))
{
  mgPrintPageHeader($galTitlePrefix.$galTitleSep."ERROR!", "galleryPage");

  echo
    "<h1>".mgQM("gallery_error")."</h1>\n".
    "<p>".mgQM("invalid_gallery_path", chentities($galPath))."</p>";

  //echo "<p>filename=: '".$filename."', X: galData=".intval(isset($galData)).", galEntries=".intval(isset($galEntries))."\n";

  mgPrintPageFooter();
  exit;
}


// Get gallery local settings
$galTNFormat = mgGetAlbumSetting($galData, "tn_format");
$galMedFormat = mgGetAlbumSetting($galData, "med_format");


//
// Print page header, etc.
//
if (($index = array_search($galImage, $galImagesIndex)) !== FALSE)
{
  //
  // Single image mode
  //
  $ctrlFlags = mgGetSetting("image_flags");
  $data = $galEntries[$galImage];

  $list = [
    mgGetArrStr($data, ["width", "height"], "<span class=\"infoDimensions\"><b>%1</b> x <b>%2</b> px</span>"),
    mgGetArrStr($data, "model", "<span class=\"infoModel\"><b>%1</b></span>"),
    mgGetArrStr($data, "fnumber", "<span class=\"infoFNumber\"><b>f/%1</b></span>"),
    mgGetArrStr($data, "exposure", "<span class=\"infoExposure\"><b>%1</b> sec</span>"),
    mgGetArrStr($data, "iso", "<span class=\"infoISO\">ISO <b>%1</b></span>"),
    mgGetArrStr($data, "focallength", "<span class=\"infoFocalLength\">F-L <b>%1</b>mm</span>"),
    mgGetArrStr($data, "lensmodel", "<span class=\"infoLensModel\"><i>%1</i></span>"),
    mgGetArrStr($data, "filesize", "<span class=\"infoFileSize\">%1</span>", "mgFileSize"),
  ];

  $pageTitle = $galTitlePrefix.$galTitleSep.mgGetTrans($galData["caption"])." - ".$galImage;
  mgPrintPageHeader($pageTitle, "imagePage");
  echo
    // Info header
    mgGetPageInfoHeaderStart("imagePageHeader").
    "<h1>".chentities($pageTitle)."</h1>\n";

  if ($ctrlFlags & MGF_BREADCRUMBS)
    mgPrintBreadCrumbs($galData);

  $gpath = isset($data["path"]) ? $data["path"] : $galPath;
  echo
    mgGetPageInfoHeaderEnd().
    "\n".
    // Hovering navigation buttons
    "<a id=\"pageInfoButton\" href=\"#\" title=\"".mgQM("page_info_button_title")."\">_</a>\n".
    "<a id=\"pageUpNaviButton\" href=\"".mgGetURL($galData["path"], FALSE)."\" title=\"".mgQM("page_up_navi_button_title")."\">^</a>\n".
    // pageImageBox
    "<div id=\"pageImageBox\">\n".
      mgGetNaviControlImageBoxJS($galPath, $galImagesIndex, $galEntries, $index, "prevBtm", -1)."\n".
      mgGetNaviControlImageBox($galPath, $galImagesIndex, $galEntries, $index, "prev", -1)."\n".
      "<div id=\"imageImageBox\" class=\"imageBox\">".
        "<img id=\"imageImage\" src=\"".
        mgGetImageURL($gpath, $galMedPath, $galImage, $galMedFormat).
        "\" alt=\"".chentities($galImage)."\">".
      "</div>\n".
      mgGetNaviControlImageBoxJS($galPath, $galImagesIndex, $galEntries, $index, "nextBtm", 1)."\n".
      mgGetNaviControlImageBox($galPath, $galImagesIndex, $galEntries, $index, "next", 1)."\n".
    "</div>\n". // pageImageBox
    (isset($data["caption"]) ? "<div id=\"pageImageCaption\" class=\"imageCaption\">".mgGetArrStr($data, "caption", "%1")."</div>\n" : "").
    // infoBox
    "<div id=\"infoBox\">\n".
      mgGetArr($data, "datetime", "<span class=\"infoDateTime\">%1</span>\n", "", "mgTimeStr").
      implode(",\n", array_filter($list, function($a) { return $a !== NULL; }))."\n".
      "<a id=\"imageLink\" href=\"".
      mgCleanPathStr($galImageURL.$gpath."/".$galImage)."\">".
      mgQM("view_best_quality")."</a>\n".
    "</div>\n"; // infoBox

  // Javascript navigation
  if ($ctrlFlags & MGF_JAVASCRIPT)
  {
    $prevURL = mgGetNaviActive($galPath, $galImagesIndex, $index, -1, $res, FALSE);
    $nextURL = mgGetNaviActive($galPath, $galImagesIndex, $index,  1, $res, FALSE);
    echo
      "<script>\n".
      "var mgalPrevURL = \"".($prevURL !== FALSE ? $prevURL : "")."\";\n".
      "var mgalNextURL = \"".($nextURL !== FALSE ? $nextURL : "")."\";\n".
      "var mgalUpURL = \"".mgGetURL($galData["path"], FALSE)."\";\n".
      "\n";
?>
mgalDisplayInfo(false);
mgalAddEvent("pageInfoButton", "click", mgalOpenInfo);
mgalAddEvent("pageImageBox", "click", mgalCloseInfo);

mgalAddEvent("imageImage", "load", mgalAdjustImage);
mgalAddEventOb("window", window, "resize", mgalAdjustImage);
mgalAddEventOb("window", window, "load", mgalAdjustImage);
mgalAddEventOb("document", document, "keypress", mgalProcessKeyPress);
mgalAddEventOb("document", document, "keydown", mgalProcessKeyPress);

mgalAddEventOb("document", document, "touchstart", mgalTouchStart);
mgalAddEventOb("document", document, "touchmove", mgalTouchMove);

mgalAdjustImagePID = -1;
</script>
<?
  }
}
else
{
  //
  // Gallery mode
  //
  // - needs sub-modes / handling of order shit
  // - Javascript stuff for picture data updates
  //
  $pageTitle = $galTitlePrefix.mgGetArr($galData, "caption", " - %1", "", "chentities");
  mgPrintPageHeader($pageTitle, "galleryPage");

  $ptmp = [];
  if (count($galImagesIndex) > 0)
    $ptmp[] = count($galImagesIndex)." ".mgQM("gallery_nimages");
  if (count($galAlbumsIndex) > 0)
    $ptmp[] = count($galAlbumsIndex)." ".mgQM("gallery_nsubalbums");

  if (count($ptmp))
    $pageTitle .= " (".implode($ptmp, ", ").")";

  echo
    mgGetPageInfoHeaderStart("galleryPageHeader").
    "<h1>".$pageTitle."</h1>\n";

  $ctrlFlags = mgGetSetting("album_flags");
  if ($ctrlFlags & MGF_BREADCRUMBS)
    mgPrintBreadCrumbs($galData);

  if (isset($galData["header"]) && strlen($gheader = mgGetTrans($galData["header"])) > 0)
  {
    // Translate relative URLs in header, if needed
    $baseURL = mgGetSetting("image_url");

    $headerText = preg_replace_callback(
      "@href\s*=\s*\"([^\"]+)\"@i",
      function ($matches) use($galPath, $baseURL)
      {
        $mstmp = $matches[1];
        if (preg_match("@^[a-z]+://@i", $mstmp) === 0)
        {
          if ($mstmp[0] != "/")
            $mstmp = $baseURL."/".$galPath."/".str_replace("//", "/", $mstmp);
        }
        return "href=\"".$mstmp."\"";
      },
      $gheader);

    echo "<div class=\"albumHeaderText\">".$headerText."</div>\n";
  }

  echo mgGetPageInfoHeaderEnd();

  mgPrintTable("albumTable", $galPath, $galEntries, $galAlbumsIndex, 0, FALSE);
  mgPrintTable("imageTable", $galPath, $galEntries, $galImagesIndex, 0, FALSE);
}

mgPrintPageFooter();
?>