// Copyright: Copyright (C) 2002-2013 Pristine Communications // This file is in UTF-8 萬國碼 // Set the include path if (!defined("INCPATH_SET")) { require_once dirname(__FILE__) . "/incpath.inc.php"; } // Referenced subroutines require_once "monica/a2html.inc.php"; require_once "monica/actlog.inc.php"; require_once "monica/addget.inc.php"; require_once "monica/addslash.inc.php"; require_once "monica/chkfunc.inc.php"; require_once "monica/commtext.inc.php"; require_once "monica/echoform.inc.php"; require_once "monica/errmsg.inc.php"; require_once "monica/formfunc.inc.php"; require_once "monica/getlang.inc.php"; require_once "monica/gettext.inc.php"; require_once "monica/htmlchar.inc.php"; require_once "monica/listpref.inc.php"; require_once "monica/lninfo.inc.php"; require_once "monica/login.inc.php"; require_once "monica/markabbr.inc.php"; require_once "monica/pagefunc.inc.php"; require_once "monica/pic.inc.php"; require_once "monica/requri.inc.php"; require_once "monica/runcmd.inc.php"; require_once "monica/sql.inc.php"; require_once "monica/sqlconst.inc.php"; require_once "monica/userpref.inc.php"; // _list_cmp_range: Compare the abstract ranges for usort() function _list_cmp_range($a, $b) { if ($a["start"] != $a["end"]) { return $a["start"] - $b["start"]; } else { return $a["end"] - $b["end"]; } } // _list_cmp_query: Compare the query phrases for usort() function _list_cmp_query($a, $b) { return mb_strlen($b) - mb_strlen($a); } // list_type: Return the list name function list_type($type = null) { // Cache the result static $cache; // Set the list type if (!is_null($type)) { $cache = $type; } // Return the cache if (isset($cache)) { return $cache; } // Obtain the current form $FORM =& curform(); // Form type specified in arguments if (array_key_exists("list", $FORM)) { $cache = $FORM["list"]; // No form source is found } else { $cache = null; } return $cache; } // parse_query: Parse the query string into multiple search phrases function parse_query($query) { // Cache the result static $cache = array(); // Return the cache if (array_key_exists($query, $cache)) { return $cache[$query]; } $phrases = array(); $query = trim($query); while ($query != "") { // Non-quoted word if (preg_match("/^([^\s\"']+)\s*(.*?)$/", $query, $m)) { $phrases[] = $m[1]; $query = $m[2]; // Double-quoted string } elseif (preg_match("/^(?:\"((?:[^\\\\\"]|\\\\.)+)\"?)\s*(.*?)$/", $query, $m)) { $m[1] = str_replace("$", "\\$", $m[1]); eval("\$phrases[] = \"$m[1]\";"); $query = $m[2]; // Single-quoted string } elseif (preg_match("/^(?:'((?:[^\\\\']|\\\\.)+)'?)\s*(.*?)$/", $query, $m)) { eval("\$phrases[] = '$m[1]';"); $query = $m[2]; // Empty quoted strings } elseif (preg_match("/^(?:\"\"?|''?)\s*(.*?)$/", $query, $m)) { $query = $m[1]; } } sort($phrases); // Cache it $cache[$query] = $phrases; return $phrases; } // urlcheck: Perform URL. checks on the current list function urlcheck(&$current) { // Check the URL. format and gather those to check the availibility. $tocheck = array(); $stdin = ""; for ($i = 0; $i < count($current); $i++) { if (is_null($current[$i]["_urlcheck"])) { $current[$i]["_urlcheck"] = t_notset(); } elseif (!is_url_wellformed($current[$i]["_urlcheck"])) { $current[$i]["_urlcheck"] = C_("Malformed"); } else { $tocheck[count($tocheck)] =& $current[$i]; $stdin .= $current[$i]["_urlcheck"] . "\n"; } } // Nothing to check further if (count($tocheck) == 0) { return; } // Preserve the original timeout $timeout = ini_get("max_execution_time"); ini_set("max_execution_time", 0); // Run the command and obtain the output $cmd = array(dirname(__FILE__) . "/urlcheck"); $out = xruncmd($cmd, $stdin); // Restore the timeout ini_set("max_execution_time", $timeout); // Save the result $result = explode("\n", $out); for ($i = 0; $i < count($tocheck); $i++) { $tocheck[$i]["_urlcheck"] = $result[$i]? C_("OK"): C_("Unreachable"); } return; } ///////////////////////// // New Object-Oriented List Handler // By imacat 2004-05-30 ///////////////////////// // BaseList: Base list handler class class BaseList { // Parameters to be set by the user // The default number of rows per page when user preference is unavailable. // Don't set to null. // This is not to set the number of rows. Set $_pagesize instead. protected $_DEFAULT_LIST_SIZE = 10; protected $_DEFAULT_LIST_COLS = array("sn"); // The default sort order -- for non-VIEW lists only protected $_DEFAULT_SORTBY = null; // The list brief size protected $_DEFAULT_BRIEF_LEN = 15; // The query abstract span from the found phrase protected $_QABS_SPAN = 30; // The maximum query abstract length protected $_QABS_MAXLEN = 200; // The picture thumbnail size protected $_PIC_THUMBNAIL_SIZE = 70; // Default settings // Known columns that should not be displayed (has a special purpose) protected $_COLS_NO_DISPLAY = array("_viewurl", "_sel", "_selurl", "_statord"); // Known columns that should never be searched against protected $_COLS_NO_SEARCH = array("pic", "att", "pdf", "_urlcheck", "_viewurl", "_sel", "_selurl", "_statord"); // Known columns that should not be sorted with protected $_COLS_NO_SORT_BY = array("_urlcheck", "_viewurl", "_sel", "_selurl", "_statord"); // Columns that should display its brief instead protected $_COLS_BRIEF = array(); // The page title for the current list public $title = null; // The error status after fetching the list public $error = null; // The switch for different lists public $lists_switch = null; // The number of total/matching records public $total = null; // Whether we have fetched the list protected $_fetched = false; // Whether we need mass deletion checkers protected $_massdel = false; // Whether we need preceding numbering protected $_nonumber = false; // Whether we need selection links protected $_noselect = false; // Whether we need sorting links protected $_nosortby = false; // Whether the list should be in a reversed order protected $_reverse = false; // Whether these are static pages protected $_static = false; // The file name pattern of the static pages protected $_static_filepat = "%04d.html"; protected $_static_lastfile = "last.html"; // Query arguments protected $_form = null; protected $_query = null; protected $_pageno = null; protected $_sortby = null; protected $_limit = null; // Select parameters protected $_is_called_form = null; protected $_caller = null; protected $_cformid = null; // The language to use protected $_lang = null; // If this is a multi-lingual table protected $_is_ml_table = null; // Column labels to be used in _html_list() and _html_listprefform() protected $_col_labels = array(); // This shall be set when initializing the handler protected $_useview; protected $_seltext; protected $_selurl_tmpl; // The parsing results protected $_table = null; protected $_view = null; protected $_select = null; protected $_select_total = null; protected $_current = null; protected $_cols = null; protected $_lastpage = null; // The number of rows per page. Set to false to disable paging. protected $_pagesize = null; protected $_startno = null; protected $_endno = null; // Intermediate parsing results when fetching a list protected $_coldefs = array(); protected $_sortkeys = array(); protected $_query_phrases = array(); protected $_listcols = array(); // __construct: Initialize the handler // We only set up the environment, but do not really initialize // the object here. This way we can configure the environment // in the beginning before we pass its arguments in the middle // of the script function __construct($FORM, $table) { // The default value if (is_null($FORM)) { $FORM = curform(); } // Set the environment if ($GLOBALS["SQL_DBTYPE"] != SQL_NONE) { $this->_useview = sql_support(SQL_FEATURE_VIEW); } // Set the parameters $this->_form =& $FORM; $this->_table = $table; $this->_pageno = array_key_exists("pageno", $this->_form)? $this->_form["pageno"]: null; $this->_sortby = array_key_exists("sortby", $this->_form)? $this->_form["sortby"]: null; $this->_query = array_key_exists("query", $this->_form)? $this->_form["query"]: null; if ($this->_query == C_("(query phrase)")) { $this->_query = ""; } $this->_lang = array_key_exists("lang", $this->_form) && in_array($this->_form["lang"], $GLOBALS["ALL_LINGUAS"])? $this->_form["lang"]: getlang(); // The default column labels $this->_col_labels(array( // Common labels shared by all list handlers "sn" => C_("S/N"), "created" => C_("Created"), "createdby" => C_("Created by"), "updated" => C_("Updated"), "updatedby" => C_("Updated by"), // Other commonly-seen column labels "body" => C_("Content"), "cat" => C_("Category"), "cov" => C_("Coverage"), "date" => C_("Date"), "disabled" => C_("Disabled?"), "dsc" => C_("Description"), "email" => C_("E-mail"), "hid" => C_("Hidden?"), "html" => C_("HTML?"), "id" => C_("ID."), "kw" => C_("Keywords"), "name" => C_("Name"), "ord" => C_("Order"), "path" => C_("Page path"), "pic" => C_("Picture"), "picratio" => C_("Pic. ratio"), "piccap" => C_("Pic. caption"), "picpos" => C_("Pic. position"), "subject" => C_("Subject"), "title" => C_("Title"), "url" => C_("URL."), "_urlcheck" => C_("Status (slow)"), )); // Parameters for the called forms $this->_is_called_form = array_key_exists("caller", $this->_form) && array_key_exists("cformid", $this->_form); if ($this->_is_called_form) { $this->_caller = $this->_form["caller"]; $this->_cformid = $this->_form["cformid"]; $this->_seltext = C_("Select"); $this->_selurl_tmpl = $this->_caller . "?formid=" . $this->_cformid . "&selsn=%d"; $this->_title = C_("Select a Data Record"); } else { $this->_caller = null; $this->_cformid = null; $this->_seltext = C_("Edit"); $this->_selurl_tmpl = REQUEST_FILE . "?form=cur&sn=%d"; $this->_title = C_("Manage Data"); } // The default of the multi-lingual status $this->_is_ml_table = null; } // fetch: Fetch the current list. // We dispatch here for different query engines function fetch() { // Fetched before if ($this->_fetched) { return $this->error; } $this->_fetched = true; // Initialize the error status $this->error = null; switch ($GLOBALS["SQL_DBTYPE"]) { case SQL_MYSQL: return $this->_fetch_offset(); case SQL_POSTGRESQL: return $this->_fetch_once(); } } // page_param: Obtain page parameters function page_param() { // Fetch the current list if not fetched yet if (!$this->_fetched) { $this->fetch(); } // Don't show the list if (is_null($this->total)) { return null; } // No record to be listed if ($this->total == 0) { return null; } $args = array(); $baseurl = rem_get_arg(REQUEST_FILEQS, "pageno"); // The first page -- only meaningful when there is more than one page if ($this->_lastpage > 1) { if ($this->_static) { $args["first"] = sprintf($this->_static_filepat, 1); } elseif ($this->_reverse) { $args["first"] = add_get_arg($baseurl, "pageno", 1, DUP_OK); } else { $args["first"] = $baseurl; } } // The previous page if ($this->_pageno > 1) { if ($this->_static) { $args["prev"] = sprintf($this->_static_filepat, $this->_pageno - 1); } elseif ($this->_reverse || $this->_pageno - 1 != 1) { $args["prev"] = add_get_arg($baseurl, "pageno", $this->_pageno - 1, DUP_OK); } else { $args["prev"] = $baseurl; } } // The next page if ($this->_pageno < $this->_lastpage) { if ($this->_static) { if ( !is_null($this->_static_lastfile) && $this->_pageno + 1 == $this->_lastpage) { $args["next"] = $this->_static_lastfile; } else { $args["next"] = sprintf($this->_static_filepat, $this->_pageno + 1); } } elseif (!$this->_reverse || $this->_pageno + 1 != $this->_lastpage) { $args["next"] = add_get_arg($baseurl, "pageno", $this->_pageno + 1, DUP_OK); } else { $args["next"] = $baseurl; } } // The last page -- only meaningful when there is more than one page if ($this->_lastpage > 1) { if ($this->_static) { if (!is_null($this->_static_lastfile)) { $args["last"] = $this->_static_lastfile; } else { $args["last"] = sprintf($this->_static_filepat, $this->_lastpage); } } elseif (!$this->_reverse) { $args["last"] = add_get_arg($baseurl, "pageno", $this->_lastpage, DUP_OK); } else { $args["last"] = $baseurl; } } return $args; } // html: Output the list function html() { // Fetch the current list if not fetched yet if (!$this->_fetched) { $this->fetch(); } // Display the title $this->_html_title(); // Display the error message $this->_html_errmsg(); // Display the switch for different lists $this->_html_lists_switch(); // Display a link to add a new item $this->_html_newlink(); // Display the search box $this->_html_search(); // Display the list status message $this->_html_liststat(); // Display the page bar at the beginning $this->_html_pagebar(); // List the items $this->_html_list(); // Display the page bar at the end $this->_html_pagebar(); // Display a form to change the list preference $this->_html_listprefform(); return; } // set_listpref: Set the list preference function set_listpref() { $handler = new ListPreference($this->_form); $handler->main(); } ///////////////////////// // Methods belows are private. Do not call them directly. // Override them when needed. ///////////////////////// // _fetch_once: Fetch the current list in once. // Fetching the list in one query: Query everything, fetch // the total and only the wanted portion. // This is faster in PostgreSQL but slower in MySQL. function _fetch_once() { // See if we need to use views or not. // Views make things much faster and easier, but some DBMS has no views. if ($this->_useview) { $r = $this->_select_with_view(); } else { $r = $this->_select_without_view(); } $this->_select = sprintf("SELECT %s FROM %s%s%s%s;\n", $r["cols"], $r["table"], $r["where"], $r["orderby"], $r["limit"]); $result = sql_query($this->_select); $this->total = sql_num_rows($result); // The number of rows per page if (is_null($this->_pagesize)) { $this->_pagesize = userpref("listsize", get_class($this)); if (is_null($this->_pagesize)) { $this->_pagesize = $this->_DEFAULT_LIST_SIZE; } } // Paging not in use if ($this->_pagesize === false) { $this->_lastpage = 1; $this->_startno = 0; $this->_endno = $this->total - 1; // If endno is -1 (when total is 0), set to 0 if ($this->_endno < 0) { $this->_endno = 0; } // Fetch everything for ($i = 0, $this->_current = array(); $i < $this->total; $i++) { $this->_current[] = sql_fetch_assoc($result); } // Set the columns to be displayed $this->_check_listcols(); // Done return $this->error; } $this->_lastpage = floor(($this->total - 1) / $this->_pagesize) + 1; // The output type of floor() is float settype($this->_lastpage, "integer"); // If last page is 0 (when total is 0), set to page 1 if ($this->_lastpage < 1) { $this->_lastpage = 1; } // Check the page number $error = $this->_check_pageno(); if (!is_null($error) && is_null($this->error)) { $this->error = $error; } // Calculate the start and end record number $this->_startno = ($this->_pageno - 1) * $this->_pagesize; $this->_endno = $this->_pageno * $this->_pagesize - 1; // If there are not enough remaining records, set to the last one if ($this->_endno > $this->total - 1) { $this->_endno = $this->total - 1; } // If the last record is -1 (when total is 0), set to 0 if ($this->_endno < 0) { $this->_endno = 0; } // Go to that page $this->_current = array(); // If not empty if ($this->total > 0) { // Move to startno sql_seek($result, $this->_startno); // Fetch until endno for ($i = $this->_startno; $i <= $this->_endno; $i++) { $this->_current[] = sql_fetch_assoc($result); } } // Set the columns to be displayed $this->_check_listcols(); // Done return $this->error; } // _fetch_offset: Fetch the current list with LIMIT and OFFSET. // Fetching the list in 2 queries: First query the total with count(*) // and then query only the wanted portion with LIMIT and OFFSET. // This is faster in MySQL but slower in PostgreSQL. function _fetch_offset() { // See if we need to use views or not. // Views make things much faster and easier, but some DBMS has no views. if ($this->_useview) { $r = $this->_select_with_view(); } else { $r = $this->_select_without_view(); } // The number of rows per page if (is_null($this->_pagesize)) { $this->_pagesize = userpref("listsize", get_class($this)); if (is_null($this->_pagesize)) { $this->_pagesize = $this->_DEFAULT_LIST_SIZE; } } // Paging not in use if ($this->_pagesize === false) { $this->_select = sprintf("SELECT %s FROM %s%s%s%s;\n", $r["cols"], $r["table"], $r["where"], $r["orderby"], $r["limit"]); $result = sql_query($this->_select); // Fetch everything for ($i = 0, $this->_current = array(); $i < $this->total; $i++) { $this->_current[] = sql_fetch_assoc($result); } $this->total = sql_num_rows($result); $this->_lastpage = 1; $this->_startno = 0; $this->_endno = $this->total - 1; // If endno is -1 (when total is 0), set to 0 if ($this->_endno < 0) { $this->_endno = 0; } // Set the columns to be displayed $this->_check_listcols(); // Done return $this->error; } // Obtain the total number $this->_select_total = sprintf("SELECT count(*) AS count FROM %s%s%s;\n", $r["table"], $r["where"], $r["limit"]); $result = sql_query($this->_select_total); $row = sql_fetch_assoc($result); $this->total = $row["count"]; $this->_lastpage = floor(($this->total - 1) / $this->_pagesize) + 1; // The output type of floor() is float settype($this->_lastpage, "integer"); // If last page is 0 (when total is 0), set to page 1 if ($this->_lastpage < 1) { $this->_lastpage = 1; } // Check the page number $error = $this->_check_pageno(); if (!is_null($error) && is_null($this->error)) { $this->error = $error; } // Calculate the start and end record number $this->_startno = ($this->_pageno - 1) * $this->_pagesize; $this->_endno = $this->_pageno * $this->_pagesize - 1; // If there are not enough remaining records, set to the last one if ($this->_endno > $this->total - 1) { $this->_endno = $this->total - 1; } // If the last record is -1 (when total is 0), set to 0 if ($this->_endno < 0) { $this->_endno = 0; } // Obtain everything in this page $this->_current = array(); if (!$this->_reverse) { $this->_select = sprintf("SELECT %s FROM %s%s%s LIMIT %d OFFSET %d;\n", $r["cols"], $r["table"], $r["where"], $r["orderby"], $this->_endno - $this->_startno + 1, $this->_startno); } else { $this->_select = sprintf("SELECT %s FROM %s%s%s LIMIT %d OFFSET %d;\n", $r["cols"], $r["table"], $r["where"], $r["orderby"], $this->_endno - $this->_startno + 1, $this->total - $this->_endno - 1); } // If not empty if ($this->total > 0) { $result = sql_query($this->_select); $count = sql_num_rows($result); for ($i = 0; $i < $count; $i++) { $this->_current[] = sql_fetch_assoc($result); } } // Set the columns to be displayed $this->_check_listcols(); // Done return $this->error; } // _sql_cols: Obtain the SQL columns list phase function _sql_cols() { // Obtain the columns to list for ( $i = 0, $this->_coldefs = array(), $cols = array(); $i < count($this->_cols); $i++) { $def = $this->_coldef($this->_cols[$i]); $this->_coldefs[] = array( "def" => $def, "alias" => $this->_cols[$i]); $cols[] = $def . " AS " . $this->_cols[$i]; } return implode(", ", $cols); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "createdby": case "updatedby": return $col . ".name"; default: // Multi-lingual columns if (in_array($col, sql_cols_ml($this->_table))) { // Default language if ($this->_lang == DEFAULT_LANG) { return $this->_table . "." . $col . "_" . ln($this->_lang, LN_DATABASE); // Fall back to the default language } else { $thiscol = $this->_table . "." . $col . "_" . ln($this->_lang, LN_DATABASE); $defcol = $this->_table . "." . $col . "_" . ln(DEFAULT_LANG, LN_DATABASE); return "COALESCE(" . $thiscol . ", " . $defcol . ")"; } // Ordinary columns } else { return $this->_table . "." . $col; } } } // _sql_join: Get the SQL JOIN phase function _sql_join() { $join = ""; $cols = sql_cols_nl($this->_table); if (in_array("createdby", $cols)) { $join .= " LEFT JOIN users AS createdby ON " . $this->_table . ".createdby=createdby.sn"; } if (in_array("updatedby", $cols)) { $join .= " LEFT JOIN users AS updatedby ON " . $this->_table . ".updatedby=updatedby.sn"; } return $join; } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Empty comes from a query if (!is_null($this->_query)) { return C_("Nothing found. Please try another query."); // Empty database } else { return C_("The database is empty."); } // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s record.", "Your query found %s records.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s record.", "%s records.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s record, listing %s to %s.", "Your query found %s records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s record, listing %s to %s.", "%s records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } // _echo_colval: Output a list column value function _echo_colval($col, &$row) { // Null/no value if (is_null($row[$col])) { echo h_abbr(t_notset()); // A brief should be displayed instead } elseif ( in_array($col, $this->_COLS_BRIEF) && mb_strlen($row[$col]) > $this->_DEFAULT_BRIEF_LEN) { // Strip the HTML tags $text = $row[$col]; if ( array_key_exists("html", $row) && $row["html"]) { $text = strip_tags($text); } echo h(mb_substr($text, 0, $this->_DEFAULT_BRIEF_LEN)) . "…"; // Always display "pic" column as a thumbnail preview } elseif ($col == "pic") { $alt = C_("Picture preview"); $picid = readpic_content($row[$col], array("max" => $this->_PIC_THUMBNAIL_SIZE), $row["sn"], $this->_table); $PICS =& pic_deposit(); $pic = $PICS[$picid]; echopic_thumbnail($pic, $alt); // Always display "att" and "pdf" columns as their sizes } elseif ($col == "att" || $col == "pdf") { echo h_abbr(report_size(strlen($row[$col]))); // Always display "_urlcheck" column as URL. checking status } elseif ($col == "_urlcheck") { echo h($row[$col]); // Ordinary columns } else { echo h($row[$col]); } return; } ///////////////////////// // Methods belows are private. Do not call them directly. // Do not override them, either. ///////////////////////// // _check_pageno: Check the page number function _check_pageno() { // Save it elsewhere and replace with default value temporarily $pageno = $this->_pageno; $this->_pageno = !$this->_reverse? 1: $this->_lastpage; // Page number not specified if (is_null($pageno)) { return null; } // Text string if (is_string($pageno)) { // If it is too long or too short if (strlen($pageno) > 9) { return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), "margs"=>array($pageno)); } // If it is all-digits if (!preg_match("/^\d+$/", $pageno)) { return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), "margs"=>array($pageno)); } // If it is all-digits if (preg_match("/^0+$/", $pageno)) { return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), "margs"=>array($pageno)); } // Convert its type to integer settype($pageno, "integer"); } // Not an integer still if (!is_int($pageno)) { return array("msg"=>NC_("Page number (%s) invalid. Please specify a valid page number."), "margs"=>array($pageno)); } // Out of range if (!is_null($this->_lastpage) && $pageno > $this->_lastpage) { return array("msg"=>NC_("Page number (%d) out of range. Please specify a number between 1 and %d."), "margs"=>array($pageno, $this->_lastpage)); } // OK $this->_pageno = $pageno; return null; } // _select_with_view: Obtain the SQL statement with views // This makes life easier *^_^* function _select_with_view() { // Obtain the view name if (is_null($this->_view)) { $this->_view = $this->_table . "_list"; if (count($GLOBALS["ALL_LINGUAS"]) > 1) { $this->_view .= "_" . ln($this->_lang, LN_DATABASE); } } // Obtain the available columns if (is_null($this->_cols)) { $this->_cols = sql_cols($this->_view); } // Obtain the SQL WHERE phase $where = $this->_sql_filter(); // Obtain the SQL ORDER BY phase $orderby = $this->_sql_orderby(); // Obtain the LIMIT phase $limit = !is_null($this->_limit)? " LIMIT " . $this->_limit: ""; // Compose the SQL query return array( "cols" => "*", "table" => $this->_view, "where" => $where, "orderby" => $orderby, "limit" => $limit, ); } // _select_without_view: Obtain the SQL statement manually without views // SQL DBMS without views are to be cursed -- old MySQL does function _select_without_view() { // Obtain the available columns $this->_cols = sql_cols_nl($this->_table); $this->_cols = array_diff($this->_cols, array("mtime")); // _sql_cols() set the column definitions and may alter // $this->_cols to to get the final columns list $cols = $this->_sql_cols(); // Obtain the SQL JOIN phase $join = $this->_sql_join(); // Obtain the SQL WHERE phase $where = $this->_sql_filter(); // Obtain the SQL ORDER BY phase $orderby = $this->_sql_orderby(); // Obtain the LIMIT phase $limit = !is_null($this->_limit)? " LIMIT " . $this->_limit: ""; // Compose the SQL query return array( "cols" => $cols, "table" => $this->_table . $join, "where" => $where, "orderby" => $orderby, "limit" => $limit, ); } // _sql_filter: Get the SQL WHERE phase // The returned SQL phrase is always in UTF-8 function _sql_filter() { // No query, return empty string if (is_null($this->_query)) { if ( method_exists($this, "_pre_filter") && !is_null($this->_pre_filter())) { return " WHERE " . $this->_pre_filter(); } return ""; } // Regularize it $this->_query = trim($this->_query); // Check if it is filled if ($this->_query == "") { $this->error = array("msg"=>NC_("Please fill in your query.")); if ( method_exists($this, "_pre_filter") && !is_null($this->_pre_filter())) { return " WHERE " . $this->_pre_filter(); } return ""; } $this->_query_phrases = parse_query($this->_query); // Bounce if nothing to query if (count($this->_query_phrases) == 0) { if ( method_exists($this, "_pre_filter") && !is_null($this->_pre_filter())) { return " WHERE " . $this->_pre_filter(); } return ""; } // Obtain the columns to query if ($this->_useview) { $cols = array_diff($this->_cols, $this->_COLS_NO_SEARCH); // Use the column definition kept so far } else { for ($i = 0, $cols = array(); $i < count($this->_coldefs); $i++) { // Columns that should not be searched against if (in_array($this->_coldefs[$i]["alias"], $this->_COLS_NO_SEARCH)) { continue; } $cols[] = $this->_coldefs[$i]["def"]; } } // Compose the query condition $conds = array(); // Obtain each phase foreach ($this->_query_phrases as $phrase) { $subconds = array(); foreach ($cols as $col) { if ($GLOBALS["SQL_DBTYPE"] == SQL_POSTGRESQL) { $subconds[] = "cast($col AS text) ILIKE '%" . sql_esclike($phrase) . "%'"; } else { $subconds[] = "cast($col AS text) LIKE '%" . sql_esclike($phrase) . "%'"; } } $conds[] = implode(" OR ", $subconds); } // Append the the pre-defined filter if ( method_exists($this, "_pre_filter") && !is_null($this->_pre_filter())) { $conds[] = $this->_pre_filter(); } // Compose the statement if (count($conds) == 1) { $sql = $conds[0]; } else { $conds0 = array(); foreach ($conds as $cond) { $conds0[] = "($cond)"; } $sql = implode(" AND ", $conds0); } // Append WHERE return " WHERE " . $sql; } // _compose_query_key: Compose the query key from the query phrases function _compose_query_key() { // Bounce if there is no query phrases if (count($this->_query_phrases) == 0) { return ""; } for ($i = 0, $phrases = array(); $i < count($this->_query_phrases); $i++) { $phreses[] = "\"" . addslashes($this->_query_phrases[$i]) . "\""; } return implode(",", $phreses); } // _sql_orderby: Get the SQL ORDER BY phase function _sql_orderby() { // Parse the "sortby" argument $this->_parse_sortby($this->_sortby); // Check the sort keys, and empty them if invalid $error = $this->_check_sortkeys(); if (!is_null($error)) { if (is_null($this->error)) { $this->error = $error; } $this->_sortkeys = array(); } // Apply _DEFAULT_SORTBY if not in a view if ( count($this->_sortkeys) == 0 && !$this->_useview && !is_null($this->_DEFAULT_SORTBY)) { // Parse the _DEFAULT_SORTBY argument $this->_parse_sortby($this->_DEFAULT_SORTBY); // Check the sort keys, and empty them if invalid $error = $this->_check_sortkeys(); if (!is_null($error)) { if (is_null($this->error)) { $this->error = $error; } $this->_sortkeys = array(); } } // Set the "sortby" attribute $this->_compose_sortby(); // Bounce if there is no sorting key if (count($this->_sortkeys) == 0) { return ""; } // Obtain the corresponding SQL phrase for ($i = 0, $phrases = array(); $i < count($this->_sortkeys); $i++) { $phrases[] = $this->_sortkeys[$i]["sql"]; } $sql = " ORDER BY " . implode(", ", $phrases); return $sql; } // _parse_sortby: Parse the "sortby" argument // $sortby argument should be specified as "key1,-key2,...", // where initial minus (-) before the key means decreasing. function _parse_sortby($sortby) { $this->_sortkeys = array(); // Bounce for nothing if (is_null($sortby)) { return; } $sortby = trim($sortby); // Bounce if $sortby is empty if ($sortby == "") { return; } // Split by comma $phrases = explode(",", $sortby); for ($i = 0; $i < count($phrases); $i++) { // Compose the sort key $key = trim($phrases[$i]); $desc = false; $sql = $key; // Check the decreasing flag with the initial "-" sign if (substr($key, 0, 1) == "-") { $key = trim(substr($key, 1)); $desc = true; $sql = "$key DESC"; } // Add this sort key $this->_sortkeys[] = array( "key" => $key, "desc" => $desc, "sql" => $sql, ); } return; } // _check_sortkeys: Check if the sorting keys are valid function _check_sortkeys() { // Skip if nothing to check if (count($this->_sortkeys) == 0) { return null; } // Obtain the valid sorting keys if ($this->_useview) { $validkeys = array_diff($this->_cols, $this->_COLS_NO_SORT_BY); // Check each candidate for ($i = 0; $i < count($this->_sortkeys); $i++) { if (!in_array($this->_sortkeys[$i]["key"], $validkeys)) { return array("msg"=>NC_("You cannot sort by \"%s\"."), "margs"=>array($this->_sortkeys[$i]["key"])); } } // Use the column definition kept so far } else { // Turn to associative array for ($i = 0, $coldefs = array(); $i < count($this->_coldefs); $i++) { $coldefs[$this->_coldefs[$i]["alias"]] = $this->_coldefs[$i]["def"]; } // Check each candidate for ($i = 0; $i < count($this->_sortkeys); $i++) { if (!array_key_exists($this->_sortkeys[$i]["key"], $coldefs)) { return array("msg"=>NC_("You cannot sort by \"%s\"."), "margs"=>array($this->_sortkeys[$i]["key"])); } // Reset the SQL according to the column definition $this->_sortkeys[$i]["sql"] = $coldefs[$this->_sortkeys[$i]["key"]]; if ($this->_sortkeys[$i]["desc"]) { $this->_sortkeys[$i]["sql"] .= " DESC"; } } } // OK return null; } // _compose_sortby: Compose the "sortby" argument from sorting keys function _compose_sortby() { // Bounce if there is no sorting keys if (count($this->_sortkeys) == 0) { $this->_sortby = ""; return; } for ($i = 0, $sortbys = array(); $i < count($this->_sortkeys); $i++) { if ($this->_sortkeys[$i]["desc"]) { $sortbys[] = "-" . $this->_sortkeys[$i]["key"]; } else { $sortbys[] = $this->_sortkeys[$i]["key"]; } } $this->_sortby = implode(",", $sortbys); return; } // _cols: Obtain the list columns // To be removed. Use $this->_cols instead. function _cols() { // Obtain the available column list when not set yet if (is_null($this->_cols)) { $this->_cols = sql_cols_nl($this->_table); } return $this->_cols; } // _col_labels: Set the column labels function _col_labels($labels) { $this->_col_labels = array_merge($this->_col_labels, $labels); } // _check_listcols: Set the columns to be displayed function _check_listcols() { // The columns to be displayed $userpref = userpref("listcols", get_class($this)); if (!is_null($userpref)) { $listcols = explode(" ", $userpref); } else { $listcols = $this->_DEFAULT_LIST_COLS; } // Obtain the columns to list $validcols = array_diff($this->_cols, $this->_COLS_NO_DISPLAY); $this->_listcols = array_intersect($listcols, $validcols); return; } // _query_abstract: Get the abstract regarding to the query phrase // It always work on the "body" column function _query_abstract($body, $html = false, $queries = null) { // Default to the current query phrases if (is_null($queries)) { $queries = $this->_query_phrases; } // A single query phrase is provided if (!is_array($queries)) { $queries = array($queries); } // Return nothing if body is empty if (is_null($body)) { return null; } // Strip the HTML tags if ($html) { $body = str_replace("", "\"", $body); $body = str_replace("", "\"", $body); $body = strip_tags($body); $body = dh($body); } // Trim excess spaces $body = preg_replace("/\s+/", " ", $body); // Sort the query phrases by their lengths, shortest first usort($queries, "_list_cmp_query"); // Gather the abstract of each query phrase $bodylen = mb_strlen($body); for ($i = 0, $ranges = array(); $i < count($queries); $i++) { $len = mb_strlen($queries[$i]); $base = 0; $query = addslashes_re_php($queries[$i]); // Gather each match while (preg_match("/^(.*?)$query/i", mb_substr($body, $base), $m)) { $pos = $base + mb_strlen($m[1]); $start = $pos - $this->_QABS_SPAN; if ($start < 0) { $start = 0; } $end = $pos + $len + $this->_QABS_SPAN; if ($end >= $bodylen) { $end = $bodylen - 1; } $ranges[] = array( "start" => $start, "end" => $end, ); $base = $pos + $len; } } // Sanity check if (count($ranges) == 0) { return null; } // Sort the ranges usort($ranges, "_list_cmp_range"); // Get the union of the ranges $union = array(); $i = 0; $start = $ranges[0]["start"]; $end = $ranges[0]["end"]; while (true) { // Find the next segment that exceeds the current segment for ( ; $i < count($ranges) && $ranges[$i]["end"] <= $end; $i++) {}; // Meet the last entry if ($i == count($ranges)) { // Save the last segment $union[] = array( "start" => $start, "end" => $end, "len" => $end - $start, "text" => mb_substr($body, $start, $end - $start), ); break; } // A new segment seperated from the current segment if ($ranges[$i]["start"] > $end) { // Save the last segment $union[] = array( "start" => $start, "end" => $end, "len" => $end - $start, "text" => mb_substr($body, $start, $end - $start), ); // Start a new segment $start = $ranges[$i]["start"]; $end = $ranges[$i]["end"]; continue; } // Expend the current segment $end = $ranges[$i]["end"]; continue; } // Trim the union $len_andsoon = 1; $len = 0; if ($union[0]["start"] != 0) { $len += $len_andsoon; } $reached_maximum = false; for ($i = 0; $i < count($union) - 1; $i++) { $needlen = $union[$i]["len"] + $len_andsoon; // Not even enough for an abstract section if ($len + $len_andsoon > $this->_QABS_MAXLEN) { $reached_maximum = true; // Discard the rest sections while (count($union) > $i) { array_pop($union); } break; // Reached the maximum } elseif ($len + $needlen > $this->_QABS_MAXLEN) { $reached_maximum = true; $union[$i]["len"] = $this->_QABS_MAXLEN - $len - $len_andsoon; $union[$i]["end"] = $union[$i]["start"] + $union[$i]["len"]; $union[$i]["text"] = mb_substr($body, $union[$i]["start"], $union[$i]["len"]); // Discard the rest sections while (count($union) > $i + 1) { array_pop($union); } break; } // Not reached the maximum yet $len += $union[$i]["len"] + $len_andsoon; } // Not reached the maximum yet - check the last section if (!$reached_maximum) { $i = count($union) - 1; $needlen = $union[$i]["len"]; if ($union[$i]["end"] != $bodylen) { $needlen += $len_andsoon; } // Not even enough for an abstract section if ($len + $len_andsoon > $this->_QABS_MAXLEN) { // Forget it. We can do nothing now. array_pop($union); // Reached the maximum } elseif ($len + $needlen > $this->_QABS_MAXLEN) { $union[$i]["len"] = $this->_QABS_MAXLEN - $len - $len_andsoon; $union[$i]["end"] = $union[$i]["start"] + $union[$i]["len"]; $union[$i]["text"] = mb_substr($body, $union[$i]["start"], $union[$i]["len"]); } // Not reached the maximum yet } // Mark the query phrases for ($i = 0, $union_text = array(); $i < count($union); $i++) { $pieces = array( array( "text" => $union[$i]["text"], "is_match" => false, ), ); // Mark each query phrase for ($j = 0; $j < count($queries); $j++) { $query = addslashes_re_php($queries[$j]); for ($k = 0; $k < count($pieces); $k++) { // Skip matches of other query phrases if ($pieces[$k]["is_match"]) { continue; } // Skip if not matched if (!preg_match("/^(.*?)($query)(.*)$/i", $pieces[$k]["text"], $m)) { continue; } $pieces = array_merge( array_slice($pieces, 0, $k), array( array( "text" => $m[1], "is_match" => false, ), array( "text" => $m[2], "is_match" => true, ), array( "text" => $m[3], "is_match" => false, ), ), array_slice($pieces, $k + 1) ); $k++; } } for ($j = 0, $text = ""; $j < count($pieces); $j++) { if ($pieces[$j]["is_match"]) { $text .= "" . h($pieces[$j]["text"]) . ""; } else { $text .= h($pieces[$j]["text"]); } } $union_text[] = $text; } // Join these segments $abstract = implode("…", $union_text); if ($union[0]["start"] != 0) { $abstract = "…" . $abstract; } if ($union[count($union)-1]["end"] != $bodylen) { $abstract .= "…"; } return $abstract; } // _html_title: Display the title // Make it a null function function _html_title() { return; } // _html_errmsg: Display the error message function _html_errmsg() { if (is_null($this->error)) { return; } $message = err2msg($this->error); ?>

lists_switch) || count($this->lists_switch) == 0) { return; } ?>
lists_switch); $i++) { $htmls[] = " lists_switch[$i]["url"]) . "\">" . h($this->lists_switch[$i]["title"]) . ""; } echo implode(" |\n", $htmls); ?>
_is_called_form) { return; } if (is_null($prompt) || $prompt === false) { return; } // Start from the default language $is_ml_table = !is_null($this->_is_ml_table)? $this->_is_ml_table: sql_is_ml_table($this->_table); if ($is_ml_table && $this->_lang != DEFAULT_LANG) { return; } $url = REQUEST_FILEQS; // Remove list parameters $url = rem_get_arg($url, array("query", "sortby", "pageno", "form", "formid", "statid")); $url = add_get_arg($url, "form", "new", DUP_OK); ?>

_fetched && !is_null($this->total) && $this->total == 0 && is_null($this->_query)) { return; } $label = C_("Search"); ?>
total)) { return; } $message = $this->_liststat_message(); if (is_null($message)) { return; } ?>

total)) { return; } // Fit in one page - paging is not needed if ($this->_lastpage <= 1) { return; } // Cache the result static $cache; // Cached before if (isset($cache)) { echo $cache; return; } // Fewer than 5 pages if ($this->_lastpage <= 5) { $startpage = 1; $endpage = $this->_lastpage; // Near the beginning } elseif ($this->_pageno < 3) { $startpage = 1; $endpage = 5; // Near the end } elseif ($this->_pageno > $this->_lastpage - 2) { $startpage = $this->_lastpage - 4; $endpage = $this->_lastpage; // Normal, at the middle } else { $startpage = $this->_pageno - 2; $endpage = $this->_pageno + 2; } // Start output // Cache it! ob_start(); // Static page -- Display the index if ($this->_static) { ?>
|
_is_called_form) { ?> _query)) { ?> _sortby) && $this->_sortby != "") { ?> _pageno != 1) { if ($this->_static) { $url = sprintf($this->_static_filepat, 1); } elseif ($this->_reverse) { $url = add_get_arg($baseurl, "pageno", 1, DUP_OK); } else { $url = $baseurl; } $cell = "" . $cell . ""; } echo " $cell |\n"; // The previous page $cell = h(C_("Previous")); if ($this->_pageno != 1) { if ($this->_static) { $url = sprintf($this->_static_filepat, $this->_pageno - 1); } elseif ($this->_reverse || $this->_pageno - 1 != 1) { $url = add_get_arg($baseurl, "pageno", $this->_pageno - 1, DUP_OK); } else { $url = $baseurl; } $cell = "" . $cell . ""; } echo " $cell |\n"; // Pages before for ($i = $startpage; $i < $this->_pageno; $i++) { $cell = h($i); if ($this->_static) { $url = sprintf($this->_static_filepat, $i); } elseif ($this->_reverse || $i != 1) { $url = add_get_arg($baseurl, "pageno", $i, DUP_OK); } else { $url = $baseurl; } $cell = "" . $cell . ""; echo " $cell |\n"; } // Current page $cell = h($this->_pageno); echo " $cell |\n"; // Pages after for ($i = $this->_pageno + 1; $i <= $endpage; $i++) { $cell = h($i); if ($this->_static) { if ( !is_null($this->_static_lastfile) && $i == $this->_lastpage) { $url = $this->_static_lastfile; } else { $url = sprintf($this->_static_filepat, $i); } } elseif (!$this->_reverse || $i != $this->_lastpage) { $url = add_get_arg($baseurl, "pageno", $i, DUP_OK); } else { $url = $baseurl; } $cell = "" . $cell . ""; echo " $cell |\n"; } // The next page $cell = h(C_("Next")); if ($this->_pageno != $this->_lastpage) { if ($this->_static) { if ( !is_null($this->_static_lastfile) && $this->_pageno + 1 == $this->_lastpage) { $url = $this->_static_lastfile; } else { $url = sprintf($this->_static_filepat, $this->_pageno + 1); } } elseif (!$this->_reverse || $this->_pageno + 1 != $this->_lastpage) { $url = add_get_arg($baseurl, "pageno", $this->_pageno + 1, DUP_OK); } else { $url = $baseurl; } $cell = "" . $cell . ""; } echo " $cell |\n"; // The last page $cell = h(C_("Last")); if ($this->_pageno != $this->_lastpage) { if ($this->_static) { if (!is_null($this->_static_lastfile)) { $url = $this->_static_lastfile; } else { $url = sprintf($this->_static_filepat, $this->_lastpage); } } elseif (!$this->_reverse) { $url = add_get_arg($baseurl, "pageno", $this->_lastpage, DUP_OK); } else { $url = $baseurl; } $cell = "" . $cell . ""; } echo " $cell\n"; if ($this->_static) { ?>
total)) { return; } // No record to be listed if ($this->total == 0) { return; } // Remove "sortby" from the URL. first $baseurl = REQUEST_FILEQS; $baseurl = rem_get_arg($baseurl, array("formid", "statid", "sortby", "pageno")); // Check the URL. first if (in_array("_urlcheck", $this->_listcols)) { urlcheck($this->_current); } // Mass deletion -- surround it with a form if ($this->_massdel && !$this->_is_called_form) { $massdel = C_("Delete the selected items."); ?>
_nonumber) { echo ""; } if ($this->_massdel && !$this->_is_called_form) { echo ""; } if (in_array("_viewurl", $this->_cols) && !$this->_is_called_form) { echo ""; } if (!$this->_noselect) { echo ""; } for ($i = 0; $i < count($this->_listcols); $i++) { echo ""; } ?>_nonumber) { ?> _massdel && !$this->_is_called_form) { ?> _cols) && !$this->_is_called_form) { ?> _noselect) { ?> _listcols as $col) { $label = array_key_exists($col, $this->_col_labels)? $this->_col_labels[$col]: $col; if ($this->_nosortby || in_array($col, $this->_COLS_NO_SORT_BY)) { ?> _sortby == $col)? "-" . $col: $col), DUP_OK); ?> _current); $i++) { $no = $this->_startno + $i + 1; $rowclass = ($i % 2 == 0)? "evenrow": "oddrow"; $current =& $this->_current[$i]; $issel = ((!in_array("_sel", $this->_cols) || $current["_sel"]) && !$this->_noselect); // The URL. to handle the selection if ($issel) { if ( array_key_exists("_selurl", $current) && !$this->_is_called_form) { $selurl = $current["_selurl"]; } else { $selurl = sprintf($this->_selurl_tmpl, $current["sn"]); } } ?>_nonumber) { ?> _massdel && !$this->_is_called_form) { $name = "delsn" . $current["sn"]; ?> _cols) && !$this->_is_called_form) { if (is_null($current["_viewurl"])) { ?> _noselect) { ?> _listcols as $col) { ?>
_seltext); ?>
_seltext); ?> _echo_colval($col, $current); ?>
_massdel && !$this->_is_called_form) { $massdel = C_("Delete the selected items."); ?>
_col_labels)? $this->_col_labels[$col]: $col; if ($this->_nosortby || in_array($col, $this->_COLS_NO_SORT_BY)) { ?> _sortby == $col)? "-" . $col: $col), DUP_OK); ?> total)) { return; } // No record to be listed if ($this->total == 0) { return; } // Return if users preferences are not available if (!use_users() || !isset($_SESSION) || is_null(get_login_sn())) { return; } $submit = C_("Set"); // The referer $referer = rem_get_arg(REQUEST_FULLURI, "statid"); // Obtain the columns to list $validcols = array_diff($this->_cols, $this->_COLS_NO_DISPLAY); ?>

_col_labels)? $this->_col_labels[$col]: $col; $name = "listcols_" . $col; ?>_listcols)) { echo " checked=\"checked\""; } ?> />

title = $this->_is_called_form? C_("Select a User"): C_("Manage Users"); // The default sort order $this->_DEFAULT_SORTBY = "id"; // Column labels $this->_col_labels(array( "id" => C_("User ID."), "name" => C_("Full name"), "deleted" => C_("Deleted?"), "lang" => C_("Pref. language"), "visits" => C_("Visits"), "visited" => C_("Visited"), "ip" => C_("IP"), "host" => C_("Host"), "ct" => C_("From country"), "fails" => C_("Fail logins"), )); } // _sql_cols: Obtain the SQL columns list phase function _sql_cols() { // Adjust the column list $this->_cols = array_values(array_diff($this->_cols, array("passwd"))); // Run the parent method return parent::_sql_cols(); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "lang": $cases = array(); foreach (array_keys($GLOBALS["LNINFO"]) as $lang) { $cases[] = "WHEN '" . sql_esctext($lang) . "'" . " THEN '" . sql_esctext(ln($lang, LN_DESC_CURLC)) . "'"; } return "CASE " . $this->_table . "." . $col . " " . implode(" ", $cases) . " END"; case "disabled": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("Disabled")) . "'" . " ELSE '' END"; case "deleted": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("Deleted")) . "'" . " ELSE '' END"; default: return parent::_coldef($col); } } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new user account."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a user:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s user.", "Your query found %s users.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s user.", "%s users.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s user, listing %s to %s.", "Your query found %s users, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s user, listing %s to %s.", "%s users, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // GroupsList: Groups list handler class class GroupsList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "groups") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Group"): C_("Manage Groups"); // The default sort order $this->_DEFAULT_SORTBY = "id"; // Column labels $this->_col_labels(array( "id" => C_("Group ID."), )); } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new group."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a group:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s group.", "Your query found %s groups.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s group.", "%s groups.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s group, listing %s to %s.", "Your query found %s groups, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s group, listing %s to %s.", "%s groups, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // UserMembershipsList: User memberships list handler class class UserMembershipsList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "usermem") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a User Membership Record"): C_("Manage User Membership"); // The default sort order $this->_DEFAULT_SORTBY = "grp,member"; // Column labels $this->_col_labels(array( "grp" => C_("Group"), "member" => C_("Member"), )); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "grp": // Default language if ($this->_lang == DEFAULT_LANG) { return sql_strcat("groups.id", "' ('", "groups.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); // Fall back to the default language } else { $thiscol = "groups.dsc_" . ln($this->_lang, LN_DATABASE); $defcol = "groups.dsc_" . ln(DEFAULT_LANG, LN_DATABASE); return sql_strcat("groups.id", "' ('", "COALESCE($thiscol, $defcol)", "')'"); } case "member": return sql_strcat("usrmembers.id", "' ('", "usrmembers.name", "')'"); default: return parent::_coldef($col); } } // _sql_join: Get the SQL JOIN phase function _sql_join() { $join = ""; $join .= " LEFT JOIN groups ON " . $this->_table . ".grp=groups.sn"; $join .= " LEFT JOIN users AS usrmembers ON " . $this->_table . ".member=usrmembers.sn"; return $join . parent::_sql_join(); } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new membership record."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a membership record:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s membership record.", "Your query found %s membership records.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s membership record.", "%s membership records.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s membership record, listing %s to %s.", "Your query found %s membership records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s membership record, listing %s to %s.", "%s membership records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // GroupMembershipsList: Group memberships list handler class class GroupMembershipsList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "groupmem") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Group Membership Record"): C_("Manage Group Membership"); // The default sort order $this->_DEFAULT_SORTBY = "grp,member"; // Column labels $this->_col_labels(array( "grp" => C_("Group"), "member" => C_("Member"), )); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "grp": // Default language if ($this->_lang == DEFAULT_LANG) { return sql_strcat("groups.id", "' ('", "groups.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); // Fall back to the default language } else { $thiscol = "groups.dsc_" . ln($this->_lang, LN_DATABASE); $defcol = "groups.dsc_" . ln(DEFAULT_LANG, LN_DATABASE); return sql_strcat("groups.id", "' ('", "COALESCE($thiscol, $defcol)", "')'"); } case "member": // Default language if ($this->_lang == DEFAULT_LANG) { return sql_strcat("grpmembers.id", "' ('", "grpmembers.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); // Fall back to the default language } else { $thiscol = "grpmembers.dsc_" . ln($this->_lang, LN_DATABASE); $defcol = "grpmembers.dsc_" . ln(DEFAULT_LANG, LN_DATABASE); return sql_strcat("grpmembers.id", "' ('", "COALESCE($thiscol, $defcol)", "')'"); } default: return parent::_coldef($col); } } // _sql_join: Get the SQL JOIN phase function _sql_join() { $join = ""; $join .= " LEFT JOIN groups ON " . $this->_table . ".grp=groups.sn"; $join .= " LEFT JOIN groups AS grpmembers ON " . $this->_table . ".member=grpmembers.sn"; return $join . parent::_sql_join(); } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new membership record."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a membership record:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s membership record.", "Your query found %s membership records.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s membership record.", "%s membership records.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s membership record, listing %s to %s.", "Your query found %s membership records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s membership record, listing %s to %s.", "%s membership records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // ScriptPrivilegesList: Script privileges list handler class class ScriptPrivilegesList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "scptpriv") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Script Privilege Record"): C_("Manage Script Privileges"); // The default sort order $this->_DEFAULT_SORTBY = "script,grp"; // Column labels $this->_col_labels(array( "script" => C_("Script"), "grp" => C_("Privilege"), )); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "grp": // Default language if ($this->_lang == DEFAULT_LANG) { return sql_strcat("groups.id", "' ('", "groups.dsc_" . ln($this->_lang, LN_DATABASE), "')'"); // Fall back to the default language } else { $thiscol = "groups.dsc_" . ln($this->_lang, LN_DATABASE); $defcol = "groups.dsc_" . ln(DEFAULT_LANG, LN_DATABASE); return sql_strcat("groups.id", "' ('", "COALESCE($thiscol, $defcol)", "')'"); } default: return parent::_coldef($col); } } // _sql_join: Get the SQL JOIN phase function _sql_join() { $join = ""; $join .= " LEFT JOIN groups ON " . $this->_table . ".grp=groups.sn"; return $join . parent::_sql_join(); } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new script privilege record."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a script privilege record:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s script privilege record.", "Your query found %s script privilege records.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s script privilege record.", "%s script privilege records.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s script privilege record, listing %s to %s.", "Your query found %s script privilege records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s script privilege record, listing %s to %s.", "%s script privilege records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // UserPreferencesList: User preferences list handler class class UserPreferencesList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "userpref") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a User Preference"): C_("Manage User Preferences"); // The default sort order $this->_DEFAULT_SORTBY = "domain,usr,name"; // Columns that should display its brief instead $this->_COLS_BRIEF = array("value"); // Column labels $this->_col_labels(array( "usr" => C_("User"), "domain" => C_("Domain"), "value" => C_("Value"), )); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "usr": return "CASE WHEN " . $this->_table . ".usr IS NOT NULL" . " THEN users.name" . " ELSE '" . sql_esctext(C_("Everyone")) . "' END"; case "domain": return "CASE WHEN " . $this->_table . ".domain IS NOT NULL" . " THEN " . $this->_table . ".domain" . " ELSE '" . sql_esctext(C_("Everywhere")) . "' END"; default: return parent::_coldef($col); } } // _sql_join: Get the SQL JOIN phase function _sql_join() { $join = ""; $join = " LEFT JOIN users ON " . $this->_table . ".usr=users.sn"; return $join . parent::_sql_join(); } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new user preference."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a user preference:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s user preference.", "Your query found %s user preferences.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s user preference.", "%s user preferences.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s user preference, listing %s to %s.", "Your query found %s user preferences, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s user preference, listing %s to %s.", "%s user preferences, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // UserRequestsList: User requests list handler class class UserRequestsList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "userreq") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a User Request"): C_("Manage User Requests"); // Columns that should display its brief instead $this->_COLS_BRIEF = array("args"); // Column labels $this->_col_labels(array( "type" => C_("Type"), "usr" => C_("User"), "args" => C_("Arguments"), "expire" => C_("Expiration"), )); } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new user request."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a user request:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query) && $this->_query != "") { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s user request.", "Your query found %s user requests.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s user request.", "%s user requests.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query) && $this->_query != "") { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s user request, listing %s to %s.", "Your query found %s user requests, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s user request, listing %s to %s.", "%s user requests, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // BaseCategoriesList: Base categories list handler class class BaseCategoriesList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = null) { parent::__construct($FORM, $table); // The default sort order $this->_DEFAULT_SORTBY = "ord,id"; } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new category."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a category:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query) && $this->_query != "") { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s category.", "Your query found %s categories.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s category.", "%s categories.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query) && $this->_query != "") { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s category, listing %s to %s.", "Your query found %s categories, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s category, listing %s to %s.", "%s categories, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // BaseCategorizationList: Base categorization records list handler class class BaseCategorizationList extends BaseList { // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new categorization record."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a categorization record:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query) && $this->_query != "") { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s categorization record.", "Your query found %s categorization records.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s categorization record.", "%s categorization records.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query) && $this->_query != "") { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s categorization record, listing %s to %s.", "Your query found %s categorization records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s categorization record, listing %s to %s.", "%s categorization records, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // PagesList: Pages list handler class class PagesList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "pages") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Page"): C_("Manage Pages"); // The default sort order $this->_DEFAULT_SORTBY = "path"; // Columns that should display its brief instead $this->_COLS_BRIEF = array("body"); } // _sql_cols: Obtain the SQL columns list phase function _sql_cols() { // Adjust the column list $this->_cols = array_merge(array("_viewurl"), $this->_cols); // Run the parent method return parent::_sql_cols(); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "_viewurl": return sql_strcat( "'/" . ln($this->_lang, LN_FILENAME) . "'", $this->_table . ".path"); case "html": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("HTML")) . "'" . " ELSE '" . sql_esctext(C_("Plain text")) . "' END"; case "hid": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("Hidden")) . "'" . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; default: return parent::_coldef($col); } } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Write a new page."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a page:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s page.", "Your query found %s pages.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s page.", "%s pages.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s page, listing %s to %s.", "Your query found %s pages, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s page, listing %s to %s.", "%s pages, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // NewsList: News list handler class class NewsList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "news") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a News Article"): C_("Manage News"); // The default sort order $this->_DEFAULT_SORTBY = "-date,-ord"; // Columns that should display its brief instead $this->_COLS_BRIEF = array("body"); } // _sql_cols: Obtain the SQL columns list phase function _sql_cols() { // Adjust the column list $this->_cols = array_merge(array("_viewurl"), $this->_cols); // Run the parent method return parent::_sql_cols(); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "_viewurl": return sql_strcat( "'/" . ln($this->_lang, LN_FILENAME) . "/news'", $this->_table . ".date"); case "html": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("HTML")) . "'" . " ELSE '" . sql_esctext(C_("Plain text")) . "' END"; case "hid": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("Hidden")) . "'" . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; default: return parent::_coldef($col); } } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Write a new news article."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a news article:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s news article.", "Your query found %s news articles.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s news article.", "%s news articles.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s news article, listing %s to %s.", "Your query found %s news articles, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s news article, listing %s to %s.", "%s news articles, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // LinkCategoriesList: Link categories list handler class class LinkCategoriesList extends BaseCategoriesList { // __construct: Initialize the handler function __construct($FORM = null, $table = "linkcat") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Link Category"): C_("Manage Link Categories"); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "parent": // Default language if ($this->_lang == DEFAULT_LANG) { $title = "parent.title_" . ln($this->_lang, LN_DATABASE); // Fall back to the default language } else { $thiscol = "parent.title_" . ln($this->_lang, LN_DATABASE); $thiscol = "parent.title_" . ln(DEFAULT_LANG, LN_DATABASE); $title = "COALESCE(" . $thiscol . ", " . $defcol . ")"; } return "CASE WHEN " . $this->_table . ".parent IS NOT NULL" . " THEN $title" . " ELSE '" . sql_esctext(t_none()) . "' END"; case "hid": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("Hidden")) . "'" . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; default: return parent::_coldef($col); } } // _sql_join: Get the SQL JOIN phase function _sql_join() { $join = ""; $join .= " LEFT JOIN links AS parent ON " . $this->_table . ".parent=parent.sn"; return $join . parent::_sql_join(); } } // LinksList: Links list handler class class LinksList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "links") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Link"): C_("Manage Links"); // The default sort order $this->_DEFAULT_SORTBY = "title"; // Columns that should display its brief instead $this->_COLS_BRIEF = array("dsc"); } // _sql_cols: Obtain the SQL columns list phase function _sql_cols() { // Adjust the column list $this->_cols = array_merge(array("_viewurl"), $this->_cols); for ($i = 0; $i < count($this->_cols); $i++) { switch ($this->_cols[$i]) { // Insert a URL. checker case "url": $this->_cols = array_merge( array_slice($this->_cols, 0, $i+1), array("_urlcheck"), array_slice($this->_cols, $i+1)); $i++; break; } } // Run the parent method return parent::_sql_cols(); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "_viewurl": return $this->_table . ".url"; case "_urlcheck": return $this->_table . ".url"; case "hid": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("Hidden")) . "'" . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; default: return parent::_coldef($col); } } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new related link."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a related link:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s related link.", "Your query found %s related links.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s related link.", "%s related links.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s related link, listing %s to %s.", "Your query found %s related links, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s related link, listing %s to %s.", "%s related links, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // LinkCategorizationList: Link categorization records list handler class class LinkCategorizationList extends BaseCategorizationList { // __construct: Initialize the handler function __construct($FORM = null, $table = "linkcatz") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Link Categorization Record"): C_("Manage Link Categorization"); // The default sort order $this->_DEFAULT_SORTBY = "cat,link"; // Column labels $this->_col_labels(array( "link" => C_("Link"), )); } // _coldef: Column definition for non-view usage function _coldef($col) { // Obtain the column definition switch ($col) { case "cat": // Default language if ($this->_lang == DEFAULT_LANG) { return "linkcat.title_" . ln($this->_lang, LN_DATABASE); // Fall back to the default language } else { $thiscol = "linkcat.title_" . ln($this->_lang, LN_DATABASE); $thiscol = "linkcat.title_" . ln(DEFAULT_LANG, LN_DATABASE); return "COALESCE(" . $thiscol . ", " . $defcol . ")"; } case "link": // Default language if ($this->_lang == DEFAULT_LANG) { return "links.title_" . ln($this->_lang, LN_DATABASE); // Fall back to the default language } else { $thiscol = "links.title_" . ln($this->_lang, LN_DATABASE); $thiscol = "links.title_" . ln(DEFAULT_LANG, LN_DATABASE); return "COALESCE(" . $thiscol . ", " . $defcol . ")"; } case "hid": return "CASE WHEN " . sql_is_true($this->_table . "." . $col) . " THEN '" . sql_esctext(C_("Hidden")) . "'" . " ELSE '" . sql_esctext(C_("Shown")) . "' END"; default: return parent::_coldef($col); } } // _sql_join: Get the SQL JOIN phase function _sql_join() { $join = ""; $join .= " LEFT JOIN linkcat ON " . $this->_table . ".cat=linkcat.sn"; $join .= " LEFT JOIN links ON " . $this->_table . ".link=links.sn"; return $join . parent::_sql_join(); } } // CountriesList: Countries list handler class class CountriesList extends BaseList { // __construct: Initialize the handler function __construct($FORM = null, $table = "country") { parent::__construct($FORM, $table); // The page title $this->title = $this->_is_called_form? C_("Select a Country"): C_("Manage Country Data"); // The default sort order $this->_DEFAULT_SORTBY = "title"; // Column labels $this->_col_labels(array( "id" => C_("Code"), "name" => C_("Country name"), "special" => C_("Special?"), )); } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = C_("Add a new country record."); } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for a country:"); } // Run the parent method return parent::_html_search($prompt); } // _liststat_message: Return the current list statistics message function _liststat_message() { // No record to list if ($this->total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s country.", "Your query found %s countries.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s country.", "%s countries.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s country, listing %s to %s.", "Your query found %s countries, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s country, listing %s to %s.", "%s countries, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } } // ActivityLogList: Activity log list handler class class ActivityLogList extends BaseList { protected $_rdgt = 4; protected $_rows = 4; // __construct: Initialize the handler function __construct($FORM = null, $table = null) { parent::__construct($FORM, $table); // The page title $this->title = C_("Browse the Activity Log"); $this->_rows = array_key_exists("rows", $this->_form)? $this->_form["rows"]: null; $this->_reverse = true; } // fetch: Fetch the current list. function fetch() { // Fetched before if ($this->_fetched) { return $this->error; } $this->_fetched = true; // Initialize the error status $this->error = null; // Check the query phrases $this->_check_query(); // Check the number of rows to display $error = $this->_check_pagesize(); if (!is_null($error)) { if (is_null($this->error)) { $this->error = $error; } $this->_pagesize = $this->_DEFAULT_LIST_SIZE; } elseif (is_null($this->_rows)) { $this->_pagesize = $this->_DEFAULT_LIST_SIZE; } else { $this->_pagesize = $this->_rows; } $fp = fopen(ACTLOG, "r"); flock($fp, LOCK_SH); $this->_current = array(); // Obtain all the log entries if (count($this->_query_phrases) == 0) { while (!feof($fp)) { $line = fgets($fp); if ($line === false) { break; } $this->_current[] = $line; } // Obtain all the matched log entries } else { while (!feof($fp)) { $line = fgets($fp); if ($line === false) { break; } for ($i = 0, $matched = true; $i < count($this->_query_phrases); $i++) { if (stripos($line, $this->_query_phrases[$i]) === false) { $matched = false; break; } } if ($matched) { $this->_current[] = $line; } } } flock($fp, LOCK_UN); fclose($fp); $this->total = count($this->_current); $this->_endno = $this->total - 1; $this->_startno = 1; if ($this->total > $this->_pagesize) { $this->_startno = $this->_endno - $this->_pagesize + 1; $this->_current = array_slice($this->_current, $this->_startno); } $this->_current = array_reverse($this->_current); // Done return $this->error; } // _check_query: Check the query phrases function _check_query() { // No query, return if (is_null($this->_query)) { return; } // Regularize it $this->_query = trim($this->_query); // Check if it is filled if ($this->_query == "") { $this->_query = null; return; } $this->_query_phrases = parse_query($this->_query); return; } // _check_pagesize: Check the number of rows to display function _check_pagesize() { // No rows, return if (is_null($this->_rows)) { return null; } $min = 0; $max = pow(10, $this->_rdgt) - 1; // Text string if (is_string($this->_rows)) { // Regularize it $this->_rows = trim($this->_rows); // Check if it is filled if ($this->_rows == "") { return array("msg"=>NC_("Please fill in the number of rows to display.")); } // Check the length if (sql_strlen($this->_rows) > $this->_rdgt) { return array("msg"=>NC_("This number of rows to display is too long. (Max. length %d)"), "margs"=>array($this->_rdgt)); } // If there is any non-digit character if (preg_match("/\D/", $this->_rows)) { return array("msg"=>NC_("Please fill in a positive integer number of rows to display.")); } // Check if it is in the valid range if ($this->_rows < $min) { return array("msg"=>NC_("The number of rows to display is too small. Please fill in a larger number of rows to display between %d and %d."), "margs"=>array($min, $max)); } // It is not possible to be too large now. // Convert its type to integer settype($this->_rows, "integer"); // Integer } elseif (is_int($this->_rows)) { // Check if it is in the valid range if ($this->_rows < $min) { return array("msg"=>NC_("The number of rows to display is too small. Please fill in a larger number of rows to display between %d and %d."), "margs"=>array($min, $max)); } if ($this->_rows > $max) { return array("msg"=>NC_("The number of rows to display is too large. Please fill in a smaller number of rows to display between %d and %d."), "margs"=>array($min, $max)); } // Other types are non-sense } else { trigger_error("Unknown type for column \"rows\"", E_USER_ERROR); } // OK return null; } // _html_newlink: Display a link to add a new item function _html_newlink($prompt = false) { if ($prompt === false) { $prompt = null; } // Run the parent method return parent::_html_newlink($prompt); } // _html_search: Display the search box function _html_search($prompt = false) { if ($prompt === false) { $prompt = C_("Search for log entries:"); } $label = C_("Display"); $defquery = C_("(query phrase)"); $query = !is_null($this->_query) && $this->_query != ""? $this->_query: $defquery; $rows = (!is_null($this->_rows)? $this->_rows: $this->_DEFAULT_LIST_SIZE); ?>
total == 0) { // Inherit the empty list statistics message return parent::_liststat_message(); // Fit in one page } elseif ($this->_pagesize === false || $this->total <= $this->_pagesize) { // Result comes from a query if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s log entry.", "Your query found %s log entries.", $this->total), number_format($this->total)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s log entry.", "%s log entries.", $this->total), number_format($this->total)); } // More than one page } else { if (!is_null($this->_query)) { return sprintf(dngettext(COMMONDOMAIN, "Your query found %s log entry, listing %s to %s.", "Your query found %s log entries, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); // List result } else { return sprintf(dngettext(COMMONDOMAIN, "%s log entry, listing %s to %s.", "%s log entries, listing %s to %s.", $this->total), number_format($this->total), number_format($this->_startno+1), number_format($this->_endno+1)); } } } // _html_pagebar: Display a page navigation bar // Make it a null function function _html_pagebar() { return; } // _html_list: List the items function _html_list() { // Don't show the list if (is_null($this->total)) { return; } // No record to be listed if ($this->total == 0) { return; } $html = implode("", $this->_current); $html = preg_replace_callback("/([\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F])/", function ($matches) { return sprintf("\\x%02x", ord($matches[1])); }, $html); ?>