Mercurial > hg > mgallery
view mgallery.php @ 307:a09452ac196e
Improve WebP PHP 7.1 requirement error message.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 03 Apr 2020 17:12:20 +0300 |
parents | 2c5ff6aa9845 |
children | f07e3d79c421 |
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-2020 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 mgPrintPageHeader($pageTitle, $pageClass) { global $pageCSS, $pageCharset, $pageUrchin, $pageJSFile, $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. " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n". " <script src=\"".mgMangleURI($pageJSFile)."\"></script>\n". " <title>".strip_tags($pageTitle)."</title>\n". mgGetCSSLine($pageCSS, FALSE). "</head>\n". "<body>\n"; if ($pageUrchin !== FALSE && file_exists($pageUrchin)) require_once $pageUrchin; echo "<div id=\"".$pageClass."\">\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 ? "&" : "&"; 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"); $pageJSFile = 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); adjustPID = -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(); ?>