// Copyright: Copyright (C) 2003-2009 Pristine Communications // Set the include path if (!defined("INCPATH_SET")) { require_once dirname(__FILE__) . "/incpath.inc.php"; } // Referenced subroutines require_once "monica/altlang.inc.php"; require_once "monica/chkfunc.inc.php"; require_once "monica/commtext.inc.php"; require_once "monica/echoform.inc.php"; require_once "monica/errhndl.inc.php"; require_once "monica/getlang.inc.php"; require_once "monica/gettext.inc.php"; require_once "monica/lninfo.inc.php"; require_once "monica/mkalldir.inc.php"; require_once "monica/page2rel.inc.php"; require_once "monica/rel2abs.inc.php"; require_once "monica/requri.inc.php"; require_once "monica/rmalldir.inc.php"; require_once "monica/scptpriv.inc.php"; require_once "monica/sql.inc.php"; require_once "monica/unicode.inc.php"; require_once "monica/xfileio.inc.php"; // page_param: Gather the HTML parameters function page_param($args = null) { // Default to an empty array if (is_null($args)) { $args = array(); } // It is already fixed if (array_key_exists(".fixed", $args)) { return $args; } // Obtain page parameters if (array_key_exists("PAGE_PARAM", $GLOBALS)) { $args = array_merge($args, $GLOBALS["PAGE_PARAM"]); } if (array_key_exists("ALT_PAGE_PARAM", $GLOBALS)) { $args = array_merge($args, $GLOBALS["ALT_PAGE_PARAM"]); } // Set the path if (!array_key_exists("path", $args)) { $args["path"] = REQUEST_PATH; } // Set the language if (!array_key_exists("lang", $args)) { $args["lang"] = getlang(); } // Set if static or not if (!array_key_exists("static", $args)) { $args["static"] = false; } // Set if show a pretty result or not if (!array_key_exists("clean", $args)) { $args["clean"] = false; } // Set if this page is administrative if (!array_key_exists("admin", $args)) { $args["admin"] = is_admin_script($args["path"]); } // Set if UTF-8 or not if (!array_key_exists("utf8", $args)) { $args["utf8"] = false; } // Set if this is a preview page or not if (!array_key_exists("preview", $args)) { $args["preview"] = null; } // Set if we shoud show the tite in html_header() or not if (!array_key_exists("no_auto_title", $args)) { $args["no_auto_title"] = false; } // Set if MathML is used or not if (!array_key_exists("mathml", $args)) { if ( !is_null($args["preview"]) && array_key_exists("mathml", $args["preview"])) { $args["mathml"] = $args["preview"]? true: false; } else { $args["mathml"] = false; } } // Set all the available languages if (!array_key_exists("all_linguas", $args)) { $args["all_linguas"] = $GLOBALS["ALL_LINGUAS"]; } // Set the language of the title if (!array_key_exists("title_lang", $args)) { $args["title_lang"] = $args["lang"]; } // The upper level index page if (!array_key_exists("up", $args)) { $langfile = ln($args["lang"], LN_FILENAME); // Certain pages that has no upper level index page $rootdir = preg_replace("/^\/$langfile\/([^\/]*\/?).*?$/", "$1", $args["path"]); switch ($rootdir) { case "errors/": case "longdesc/": break; default: // See the directory where I belongs $args["up"] = preg_replace("/[^\/]+\/?$/", "", $args["path"]); // The home page path $home = count($GLOBALS["ALL_LINGUAS"]) > 1? "/$langfile/": "/"; // Above the home -- go to the home page if (substr($args["up"], 0, strlen($home)) != $home) { $args["up"] = $home; } } } // Set the URLs of the language variants if (!array_key_exists("altlang", $args)) { set_altlang_urls($args); } // Load the local extension if (function_exists("page_param_site")) { $args = page_param_site($args); } if (function_exists("page_param_script")) { $args = page_param_script($args); } // Tag that we have fixed this $args[".fixed"] = true; return $args; } // page_tree: Get the page tree in a directory function page_tree($path, $lang, $preview = null) { // Get the available language list global $ALL_LINGUAS; // Set the language $langfile = ln($lang, LN_FILENAME); $lndb = ln($lang, LN_DATABASE); $islnpre = preg_match("/^\/$langfile\//", $path)? true: false; $lnpre = $islnpre? "/$langfile": ""; // Obtain the directory $dir = preg_replace("/[^\/]*$/", "", $path); if ($islnpre) { $dir = preg_replace("/^\/$langfile/", "", $dir); } // Cache the result static $cache = array(); // Initialize the directory array if (!array_key_exists($dir, $cache)) { $cache[$dir] = array(); } // Return the cache if (array_key_exists($lang, $cache[$dir])) { return $cache[$dir][$lang]; } // Initialize the result $tree = array(); // Disable the page tree of error documents if ($dir == "/errors/") { $_path = $path; if ($islnpre) { $_path = preg_replace("/^\/$langfile/", "", $_path); } $title = count($ALL_LINGUAS) > 1? "title_$lndb": "title"; $select = "SELECT $title AS title from pages" . " WHERE path='" . sql_esctext($_path) . "';\n"; $result = sql_query($select); $row = sql_fetch_assoc($result); $tree["index"] = array( "path" => $path, "_path" => $_path, "title" => $row["title"]); return $tree; } // Get the index page $conds = array(); $conds[] = "path='" . sql_esctext($dir) . "'"; if (count($ALL_LINGUAS) > 1) { $conds[] = "title_$lndb IS NOT NULL"; } $conds[] = sql_is_false("hid"); $select = "SELECT * from pages" . " WHERE " . implode(" AND ", $conds) . ";\n"; $result = sql_query($select); $count = sql_num_rows($result); // Index page exists if ($count == 1) { $row = sql_fetch_assoc($result); $tree["index"] = array( "path" => $lnpre . $dir, "_path" => $dir, "title" => count($ALL_LINGUAS) > 1? $row["title_$lndb"]: $row["title"]); } // Get the page tree $pages = _page_tree($dir, $lang, $lnpre, $preview); if (!is_null($pages)) { $tree["pages"] =& $pages; } // Nothing found if ( !array_key_exists("index", $tree) && !array_key_exists("pages", $tree)) { $cache[$dir][$lang] = null; return null; } // Cache it $cache[$dir][$lang] = $tree; return $tree; } // _page_tree: Get the page tree function _page_tree($dir, $lang, $lnpre, $preview = null) { // Get the available language list global $ALL_LINGUAS; // Cache the result static $cache = array(); // Initialize the directory array if (!array_key_exists($dir, $cache)) { $cache[$dir] = array(); } // Return the cache if (array_key_exists($lang, $cache[$dir])) { return $cache[$dir][$lang]; } // Set the language $lndb = ln($lang, LN_DATABASE); // Get the related pages $tree = array(); // Set the columns list $cols = array(); if ($lnpre == "") { $cols[] = "path AS path"; } else { $cols[] = sql_strcat("'$lnpre'", "path") . " AS path"; } $cols[] = "path AS _path"; if (count($ALL_LINGUAS) > 1) { $cols[] = "title_$lndb AS title"; } else { $cols[] = "title AS title"; } $cols[] = "ord AS ord"; // Set the criteria $conds = array(); $conds[] = "path LIKE '" . sql_esclike($dir) . "_%'"; $conds[] = "path NOT LIKE '" . sql_esclike($dir) . "_%/_%'"; if (count($ALL_LINGUAS) > 1) { $conds[] = "title_$lndb IS NOT NULL"; } // Skip the original file if (!is_null($preview) && array_key_exists("sn", $preview)) { $conds[] = "sn!=" . $preview["sn"]; } // Set the order key $orderbys = array(); $orderbys[] = "ord"; if (count($ALL_LINGUAS) > 1) { $orderbys[] = "title_$lndb"; } else { $orderbys[] = "title"; } $orderbys[] = "path"; $conds[] = sql_is_false("hid"); $select = "SELECT " . implode(", ", $cols) . " FROM pages" . " WHERE " . implode(" AND ", $conds) . " ORDER BY " . implode(", ", $orderbys) . ";\n"; $result = sql_query($select); $count = sql_num_rows($result); for ($i = 0; $i < $count; $i++) { $tree[] = sql_fetch_assoc($result); } // Insert the preview if (!is_null($preview) && dirname($preview["path"]) . "/" == $dir) { array_push($tree, array( "path" => $lnpre . $preview["path"], "_path" => $preview["path"], "title" => $preview["title"], "ord" => $preview["ord"] )); // Sort again usort($tree, "cmp_page_tree"); } // Recur into subdirectories for ($i = 0; $i < count($tree); $i++) { if (substr($tree[$i]["path"], -1) != "/") { continue; } $tree[$i]["sub"] = array(); $tree[$i]["sub"]["index"] = array( "path" => $tree[$i]["path"], "_path" => $tree[$i]["_path"], "title" => $tree[$i]["title"] ); $subtree = _page_tree($tree[$i]["_path"], $lang, $lnpre, $preview); if (!is_null($subtree)) { $tree[$i]["sub"]["pages"] = $subtree; } } // Nothing found if (count($tree) == 0) { $cache[$dir][$lang] = null; return null; } // Cache it $cache[$dir][$lang] = $tree; return $tree; } // cmp_page_tree: Sort the page tree again after inserting a preview function cmp_page_tree($page1, $page2) { // Compare the order if ($page1["ord"] != $page2["ord"]) { return $page1["ord"] - $page2["ord"]; } // Compare the title if ($page1["title"] != $page2["title"]) { return strcmp($page1["title"], $page2["title"]); } // Compare the path return strcmp($page1["path"], $page2["path"]); } // hash_tree: Make a hash of the page tree function hash_tree(&$tree) { $hash = array(); // The index page if (array_key_exists("index", $tree)) { $hash[$tree["index"]["path"]] =& $tree; } // Track the subdirectories if (array_key_exists("pages", $tree)) { for ($i = 0; $i < count($tree["pages"]); $i++) { // A subdirectory exists if (array_key_exists("sub", $tree["pages"][$i])) { $hash = array_merge($hash, hash_tree($tree["pages"][$i]["sub"])); } } } return $hash; } // hash_page: Make a hash of the page tree function hash_page(&$tree) { $hash = array(); // The index page if (array_key_exists("index", $tree)) { $hash[$tree["index"]["path"]] =& $tree["index"]; } // Track the subdirectories if (array_key_exists("pages", $tree)) { for ($i = 0; $i < count($tree["pages"]); $i++) { // A plain page if (!array_key_exists("sub", $tree["pages"][$i])) { $hash[$tree["pages"][$i]["path"]] =& $tree["pages"][$i]; // A subdirectory } else { $hash = array_merge($hash, hash_page($tree["pages"][$i]["sub"])); } } } return $hash; } // page_all_linguas: Get the available languages for this page function page_all_linguas($page) { // Get the available language list global $ALL_LINGUAS; // It is specified if (array_key_exists("all_linguas", $page)) { return $page["all_linguas"]; } // Preview if (array_key_exists("preview", $page) && $page["preview"]) { // Uni-lingual if (!sql_is_ml_table(THIS_TABLE)) { return array(getlang()); } // Find the page if (!array_key_exists("sn", $page)) { return array(getlang()); } $select = "SELECT * FROM " . THIS_TABLE . " WHERE sn=" . $page["sn"] . ";\n"; $result = sql_query($select); // If this record exist if (sql_num_rows($result) == 0) { return array(getlang()); } $row = sql_fetch_assoc($result); // Check each language $page_all_linguas = array(); for ($l = 0; $l < count($ALL_LINGUAS); $l++) { $lang = $ALL_LINGUAS[$l]; $lndb = ln($lang, LN_DATABASE); // Add it if the content in this language exists if (!is_null($row["title_$lndb"]) || $lang == getlang()) { $page_all_linguas[] = $lang; } } return $page_all_linguas; } // $page is uni-lingual if (array_key_exists("title", $page)) { return array(getlang()); } // $page is multi-lingual // Check each language $page_all_linguas = array(); for ($l = 0; $l < count($ALL_LINGUAS); $l++) { $lang = $ALL_LINGUAS[$l]; $lndb = ln($lang, LN_DATABASE); // Add it if the content in this language exists if (!is_null($page["title_$lndb"])) { $page_all_linguas[] = $lang; } } return $page_all_linguas; } // outpage: Output a page function outpage($content, $path, $lang = null) { if (is_null($lang)) { $lang = getlang(); } $langfile = ln($lang, LN_FILENAME); // An HTML file or directory index if (substr($path, -5) == ".html" || substr($path, -1) == "/") { // The page path in multi-lingual context $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? "/$langfile$path": $path; // Convert the URLs to relative if (substr($path, 0, 8) == "/errors/") { $content = page2abs($content, $lnpath, REL2ABS_RDIFF_STRIP); // $url variable is handled inside of page2abs(); } else { $content = page2rel($content, $lnpath); } // Encode the e-mail at-signs (@) $content = str_replace("@", "@", $content); // Decode the e-mail at-signs (@) of spamtrap $content = str_replace("spamtrap@", "spamtrap@", $content); // Encode the page to the target character set $content = page_encode($content, ln($lang, LN_CHARSET)); // Obtain the real file name $file = DOC_ROOT . $lnpath; if (substr($file, -1) == "/") { $file .= "index.html"; } // Create the necessary directories mkalldir(dirname($file)); // Write the file xfupdate_template("$file.xhtml", $content); // Make the symbolic link for the text/html $targfile = basename("$file.xhtml"); $linkfile = "$file.html"; if (!is_link($linkfile) || readlink($linkfile) != $targfile) { if (file_exists($linkfile)) { if (is_dir($linkfile)) { rmalldir($linkfile); } else { unlink($linkfile); } } symlink($targfile, $linkfile); } // An RSS file or OpenSearch description document } elseif (substr($path, -8) == "/rss.xml" || substr($path, -7) == "osd.xml") { // The page path in multi-lingual context $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? "/$langfile$path": $path; // Encode the e-mail at-signs (@) $content = str_replace("@", "@", $content); // Decode the e-mail at-signs (@) of spamtrap $content = str_replace("spamtrap@", "spamtrap@", $content); // Encode the page to the target character set // XML is not HTML, so HTML character entity reference should not be used. $content = page_encode($content, ln($lang, LN_CHARSET), UNICODE_NO_HCEREF); // Obtain the real file name $file = DOC_ROOT . $lnpath; // Create the necessary directories mkalldir(dirname($file)); // Write the file xfupdate_template($file, $content); // A text file } elseif (substr($path, -4) == ".txt") { // The page path in multi-lingual context $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? "/$langfile$path": $path; // We do not encode to a target character set. This is not always // possible for plain text files and hence not quite useful. // Hence the output are always in UTF-8. // Encode the e-mail at-signs (@) $content = str_replace("@", "-at-", $content); // Obtain the real file name $file = DOC_ROOT . $lnpath; // Create the necessary directories mkalldir(dirname($file)); // Write the file xfupdate_template($file, $content); // A PDF file } elseif (substr($path, -4) == ".pdf") { // The page path in multi-lingual context $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? "/$langfile$path": $path; // Obtain the real file name $file = DOC_ROOT . $lnpath; // Create the necessary directories mkalldir(dirname($file)); // Write the file xfupdate($file, $content); // A JavaScript file } elseif (substr($path, -3) == ".js") { // The page path in multi-lingual context $lnpath = (count($GLOBALS["ALL_LINGUAS"]) > 1)? substr($path, 0, -3) . ".$langfile.js": $path; // Encode the e-mail at-signs (@) $content = str_replace("@", "@", $content); // Encode the page to the target character set $content = page_encode($content, ln($lang, LN_CHARSET)); // Obtain the real file name $file = DOC_ROOT . $lnpath; // Create the necessary directories mkalldir(dirname($file)); // Write the file xfupdate_template($file, $content); } return; } // readpage: Read from an include page function readpage($path, $lang = null) { if (is_null($lang)) { $lang = getlang(); } $charset = ln($lang, LN_CHARSET); $file = DOC_ROOT . $path; if (count($GLOBALS["ALL_LINGUAS"]) > 1) { $file = sprintf($file, ln($lang, LN_FILENAME)); } $content = xfread($file); // Try to decode with the specified encoding $GLOBALS["php_errormsg"] = null; set_error_handler("null_error_handler"); $content = iconv($charset, "UTF-8", $content); restore_error_handler(); // Wrong encoding if (!is_null($GLOBALS["php_errormsg"])) { trigger_error("Failed decoding $file as $charset", E_USER_ERROR); // In case when error handler is disabled return null; } // An HTML file or XHTML file if (substr($file, -5) == ".html" || substr($file, -6) == ".xhtml") { // Decode the HTML character references $content = a_hcref2char($content); } return $content; } // array_keys_ml: Return a list of multi-lingual keys in an associative array function array_keys_ml(&$arr) { // Get the columns that have language variants $suffix = "_" . getlang(LN_DATABASE); $len = strlen($suffix); $keys = array_keys($arr); $mlkeys = array(); for ($i = 0; $i < count($keys); $i++) { // It has a language suffix if (substr($keys[$i], -$len) == $suffix) { $mlkeys[] = substr($keys[$i], 0, -$len); } } return $mlkeys; } // array_keys_nl: Return a list of keys without their multi-lingual // deviants in an associative array function array_keys_nl(&$arr) { $keys = array_keys($arr); $mlkeys = array_keys_ml($arr); // Remove those language variants $nlkeys = array(); for ($i = 0; $i < count($keys); $i++) { $pos = strrpos($keys[$i], "_"); // No suffix if ($pos === false) { $nlkeys[] = $keys[$i]; // Check the prefix } else { $prefix = substr($keys[$i], 0, $pos); // The prefix is one of the language columns if (in_array($prefix, $mlkeys)) { // Not counted yet if (!in_array($prefix, $nlkeys)) { $nlkeys[] = $prefix; } // An ordinary prefix } else { $nlkeys[] = $keys[$i]; } } } return $nlkeys; } // page_title: Obtain a page title function page_title($sn) { // Cache the result static $cache = array(); // Bounce if there is any problem with $sn if (is_null($sn)) { return t_notset(); } // Return the cache if (array_key_exists($sn, $cache)) { return $cache[$sn]; } // Check the serial number first if (!check_sn($sn)) { $cache[$sn] = t_na(); return $cache[$sn]; } // Query // Default language if (getlang() == DEFAULT_LANG) { $title = "title_" . getlang(LN_DATABASE) . " AS title"; // Fall back to the default language } else { $title = "COALESCE(title_" . getlang(LN_DATABASE) . "," . " title_" . ln(DEFAULT_LANG, LN_DATABASE) . ") AS title"; } $select = "SELECT $title FROM pages" . " WHERE sn=$sn;\n"; $result = sql_query($select); // Not found if (sql_num_rows($result) != 1) { $cache[$sn] = t_na(); return $cache[$sn]; } // Found $row = sql_fetch_assoc($result); $cache[$sn] = $row["title"]; return $cache[$sn]; } // page_path: Obtain a page path function page_path($sn) { // Cache the result static $cache = array(); // Bounce if there is any problem with $sn if (is_null($sn)) { return t_notset(); } // Return the cache if (array_key_exists($sn, $cache)) { return $cache[$sn]; } // Check the serial number first if (!check_sn($sn)) { $cache[$sn] = t_na(); return $cache[$sn]; } // Query $select = "SELECT path FROM pages WHERE sn=$sn;\n"; $result = sql_query($select); // Not found if (sql_num_rows($result) != 1) { $cache[$sn] = t_na(); return $cache[$sn]; } // Found $row = sql_fetch_assoc($result); $cache[$sn] = $row["path"]; return $cache[$sn]; } // rebuildtype_options: Obtain a rebuild type options list function rebuildtype_options($value) { // The type labels $labels = array( "pages" => C_("Web pages"), "news" => C_("News"), "links" => C_("Related links"), "home" => C_("Home page"), "all" => C_("Whole web site"), ); if (array_key_exists("REBUILD_LABELS", $GLOBALS)) { global $REBUILD_LABELS; foreach (array_keys($REBUILD_LABELS) as $type) { $labels[$type] = _($REBUILD_LABELS[$type]); } } // Get the available rebuild types $allfuncs = get_defined_functions(); $opts = array(); foreach ($allfuncs["user"] as $func) { if (substr($func, 0, 8) == "rebuild_") { $type = substr($func, 8); // Skip rebuild_a_page() // To be removed -- only for DK-Taipei now. if ($type == "a_page") { continue; } $label = array_key_exists($type, $labels)? $labels[$type]: $type; $opts[] = array( "value" => $type, "content" => $label, ); } } // Obtain the HTML $html = opt_list_array($opts); return preselect_options($html, $value); } ?>