Mercurial > hg > mgallery
view mgallery.inc.php @ 348:596196f2b0c5 default tip
Improve relative URL translation in header text blobs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 20 Dec 2023 09:17:55 +0200 |
parents | 7da360685721 |
children |
line wrap: on
line source
<?php // // Yet Another Image Gallery // -- Common functions and data include // Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org> // (C) Copyright 2015-2023 Tecnic Software productions (TNSP) // $mgProgVersion = "v0.9.14"; $mgProgInfo = "Programmed by Matti 'ccr' Hamalainen"; $mgProgEmail = "<ccr@tnsp.org>"; $mgProgCopyright = "2015-2023 Tecnic Software productions (TNSP)"; $mgProgConfigFile = "mgallery.cfg"; $mgalDebug = FALSE; // // Navigation control defines // define("MGF_JAVASCRIPT" , 0x01); define("MGF_BREADCRUMBS" , 0x10); define("MGF_CAPTIONS" , 0x20); // // Constants for different value types // define("MG_STR" , 1); define("MG_STR_LC" , 2); define("MG_STR_ARRAY" , 3); define("MG_INT" , 4); define("MG_DVA" , 5); define("MG_BOOL" , 6); define("MG_FLAGS" , 7); define("MG_DATE" , 8); define("MG_CALLABLE" , 9); $mgValueTypes = [ MG_STR => "string", MG_STR_LC => "string lc", MG_STR_ARRAY => "string array", MG_INT => "int", MG_DVA => "dva", MG_BOOL => "bool", MG_FLAGS => "flags", MG_DATE => "date", MG_CALLABLE => "callable", ]; $mgGFlags = [ "javascript" => MGF_JAVASCRIPT, "breadcrumbs" => MGF_BREADCRUMBS, "captions" => MGF_CAPTIONS, ]; function mgPathName($path) { $tmp = mgCleanPathArray(TRUE, 0, func_num_args(), func_get_args()); if (count($tmp) > 0) return implode("/", array_splice($tmp, 0, -1))."/"; else return $path; } // // Configuration settings and their default values // $mgDefaults = [ "timezone" => [MG_STR, NULL], "clean_urls" => [MG_BOOL, FALSE], "base_path" => [MG_STR, mgPathName(mgRealPath($_SERVER["SCRIPT_FILENAME"]))], "base_url" => [MG_STR, mgPathName($_SERVER["PHP_SELF"])], "image_url" => [MG_STR, mgPathName($_SERVER["PHP_SELF"])], "mgallery_php" => [MG_STR, ""], "format_exts" => [MG_STR, "\.jpg|\.png|\.gif|\.jpeg|\.webp"], "captions_file" => [MG_STR, "captions.txt"], "header_file" => [MG_STR, "header.txt"], "info_file" => [MG_STR, "mgallery.info"], "cache_file" => [MG_STR, ".mgallery.cache"], "cover_images" => [MG_BOOL, TRUE], "album_icon" => [MG_STR, NULL], "show_keywords" => [MG_CALLABLE, FALSE, "mgParseShowKeywords"], "title_prefix" => [MG_STR, ""], "title_sep" => [MG_STR, " - "], "page_info" => [MG_STR, "Powered by <b>MGallery ".$mgProgVersion."</b> © Copyright ".$mgProgCopyright], "css" => [MG_STR_ARRAY, NULL], "js_file" => [MG_STR_ARRAY, NULL], "urchin_file" => [MG_STR_ARRAY, FALSE], "global_flags" => [MG_FLAGS, MGF_JAVASCRIPT | MGF_BREADCRUMBS | MGF_CAPTIONS, &$mgGFlags], "image_flags" => [MG_FLAGS, MGF_JAVASCRIPT | MGF_BREADCRUMBS, &$mgGFlags], "album_flags" => [MG_FLAGS, MGF_JAVASCRIPT | MGF_BREADCRUMBS, &$mgGFlags], "tn_path" => [MG_STR, "tn/"], "med_path" => [MG_STR, "med/"], "tn_format" => [MG_STR_LC, "jpeg"], "tn_width" => [MG_INT, 140], // In pixels, applies as bounding box for w/h "tn_height" => [MG_INT, 100], "tn_quality" => [MG_INT, 90], // JPEG/WEBP quality percent "med_format" => [MG_STR_LC, "jpeg"], "med_width" => [MG_INT, 1200], "med_height" => [MG_INT, 900], "med_quality" => [MG_INT, 90], ]; // // Gallery album settings // $mgAlbumDefaults = [ "show_keywords" => [MG_CALLABLE, FALSE, "mgParseShowKeywords"], "hide" => [MG_BOOL, FALSE], "hide_contents" => [MG_BOOL, FALSE], "albumpic" => [MG_STR, FALSE], "tn_format" => [MG_STR_LC, "jpeg"], "med_format" => [MG_STR_LC, "jpeg"], "header" => [MG_STR_ARRAY, FALSE], "caption" => [MG_STR_ARRAY, FALSE], "title" => [MG_STR_ARRAY, FALSE], ]; function mgDebug($msg) { global $mgalDebug; if ($mgalDebug) { echo "<p>MGAL[debug]: ".htmlspecialchars($msg)."</p>"; error_log("MGAL[debug]: ".$msg); } } function mgFatal($msg) { die("MGAL[fatal]: ".$msg); } function mgError($msg) { error_log("MGAL[error]: ".$msg); return FALSE; } function mgCArg($index, $clip = FALSE) { global $argc, $argv; if ($index < $argc) { $str = $argv[$index]; return ($clip !== FALSE) ? substr($str, 0, $clip) : $str; } else return FALSE; } function mgCArgLC($index, $clip = FALSE) { global $argc, $argv; if ($index < $argc) { $str = strtolower($argv[$index]); return ($clip !== FALSE) ? substr($str, 0, $clip) : $str; } else return FALSE; } function mgGetSetting($key, $default = NULL) { global $mgSettings, $mgDefaults; if (!array_key_exists($key, $mgDefaults)) mgFatal("Setting '".$key."' does not exist.\n"); if (array_key_exists($key, $mgSettings)) $val = $mgSettings[$key]; else $val = $mgDefaults[$key][1]; if (!isset($val) || $val === NULL) { if ($default !== NULL) $val = $default; else mgFatal("Setting '".$key."' is not set, but is required to be configured.\n"); } return $val; } function mgGetAlbumSetting(&$data, $key, $default = NULL) { if (array_key_exists($key, $data)) $val = $data[$key]; else $val = mgGetSetting($key, $default); // XXX This is a rather silly place for this check, but since any album can // set their own formats, we can't do this check globally without scanning // all the sub-albums etc .. maybe we'll do that some day. if (($key == "tn_format" || $key == "med_format") && $val == "webp" && version_compare(PHP_VERSION, "7.1.0") < 0) { mgFatal("WebP image format support requires PHP version 7.1 or later.\n"); } return $val; } function mgGetPath($path, $key) { $val = mgGetSetting($key); return ($val !== FALSE) ? $path."/".$val : FALSE; } function mgParseShowKeywords($val) { return preg_split("/\s*[,|]\s*/", $val, -1, PREG_SPLIT_NO_EMPTY); } function mgInvalidType(&$defaults, $key, $val) { global $mgValueTypes; mgFatal("Invalid value type '".gettype($val)."' for setting '".$key."', expected '". $mgValueTypes[$defaults[$key][0]]."', value: '".$val."'.\n"); return FALSE; } function mgParseConfigSetting(&$settings, &$defaults, $key, $val) { if (!array_key_exists($key, $defaults)) return mgFatal("Unknown setting key '".$key."'.\n"); switch ($defaults[$key][0]) { case MG_STR: if (!is_string($val)) return mgInvalidType($defaults, $key, $val); break; case MG_STR_LC: if (!is_string($val)) return mgInvalidType($defaults, $key, $val); $val = strtolower($val); break; case MG_STR_ARRAY: if (is_string($val)) $val = array($val); if (!is_array($val)) return mgInvalidType($defaults, $key, $val); break; case MG_INT: if (!is_int($val)) return mgInvalidType($defaults, $key, $val); break; case MG_BOOL: if (is_string($val)) { switch (strtolower(trim($val))) { case "yes": case "on": case "true": case "1": $val = true; break; case "no": case "off": case "false": case "0": $val = false; break; default: mgInvalidType($defaults, $key, $val); } } if (!is_bool($val) && !is_int($val)) return mgInvalidType($defaults, $key, $val); break; case MG_FLAGS: if (is_string($val)) { $flags = $mgDefaults[$key][2]; $cval = preg_split("/\s*[,|]\s*/", strtolower($val), -1, PREG_SPLIT_NO_EMPTY); $nval = 0; foreach ($cval as $qval) { if (array_key_exists($qval, $flags)) $nval |= $flags[$qval]; else return mgFatal("Invalid flag value for '".$key."': '".$qval."'."); } $val = $nval; } else return mgInvalidType($defaults, $key, $val); break; case MG_CALLABLE: if (!is_callable($defaults[$key][2])) return mgInvalidType($defaults, $key, $val); $val = call_user_func($defaults[$key][2], $val); break; } $settings[$key] = $val; return TRUE; } function mgReadOneConfig(&$searchPaths, $pathList) { global $mgSettings, $mgDefaults, $mgProgConfigFile; $found = FALSE; foreach (array_unique($pathList) as $path) { $filename = $path.$mgProgConfigFile; $searchPaths[] = $filename; if (!$found) { mgDebug("Checking '".$filename."' for configuration ..\n"); if (file_exists($filename) && ($data = parse_ini_file($filename, FALSE)) !== FALSE) { mgDebug("Found '".$filename."' config.\n"); foreach ($data as $dkey => &$dval) mgParseConfigSetting($mgSettings, $mgDefaults, $dkey, $dval); $found = TRUE; } } } return $found; } function mgReadSettings(&$searchPaths) { global $mgSettings; $mgSettings = []; $searchPaths = []; // System-wide $ok = mgReadOneConfig($searchPaths, ["/etc/", "/usr/local/etc/"]); // User-specific $spaths = []; if (($tmp = getenv("HOME")) !== FALSE && strlen($tmp) > 0) { $spaths[] = $tmp."/.config/mgallery/"; $spaths[] = $tmp."/."; } else { $data = posix_getpwuid(posix_getuid()); if ($data !== FALSE && isset($data["dir"])) { $tmp = $data["dir"]; $spaths[] = $tmp."/.config/mgallery/"; $spaths[] = $tmp."/."; } } $ok |= mgReadOneConfig($searchPaths, $spaths); // Album/directory-local $ok |= mgReadOneConfig($searchPaths, [ dirname(__FILE__)."/", getcwd()."/" ]); $searchPaths = array_unique($searchPaths); return $ok; } function mgRealPath($path) { return realpath($path); } function mgCleanPathStr($path) { return str_replace("//", "/", $path); } function mgCleanPathArray($refs, $start, $argc, $argv) { $path = []; $first = TRUE; for ($n = $start; $n < $argc; $n++) { foreach (explode("/", $argv[$n]) as $piece) { switch ($piece) { case ".": case "": if ($first) $path[] = $piece; break; case "..": if ($refs && count($path) > 0) array_pop($path); break; default: $path[] = $piece; break; } $first = FALSE; } } return mgCleanPathStr($path); } function mgCleanPath($refs) { return implode("/", mgCleanPathArray($refs, 1, func_num_args(), func_get_args())); } function mgGetArr($data, $skeys, $sfmt1 = "%1", $sfmt2 = "", $func = NULL) { global $pageLang; if (!is_array($skeys)) $skeys = array($skeys); foreach ($skeys as $skey) { if (!array_key_exists($skey, $data)) return $sfmt2; } $str = $sfmt1; for ($i = 1; $i <= sizeof($skeys); $i++) { $val = $data[$skeys[$i - 1]]; if (is_array($val)) $vtmp = array_key_exists($pageLang, $val) ? $val[$pageLang] : reset($val); else $vtmp = $val; if (is_callable($func)) $vtmp = call_user_func($func, $vtmp); $str = str_replace("%".$i, $vtmp, $str); } return $str; } ?>