3775 lines
131 KiB
PHP
3775 lines
131 KiB
PHP
<?php
|
|
// File name: list.inc.php
|
|
// Description: PHP subroutines to handle the item list
|
|
// Date: 2002-12-26
|
|
// Author: imacat <imacat@pristine.com.tw>
|
|
// 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("<q>", "\"", $body);
|
|
$body = str_replace("</q>", "\"", $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 .= "<em>" . h($pieces[$j]["text"]) . "</em>";
|
|
} 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);
|
|
?><p class="message"><?php echo h($message); ?></p>
|
|
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// _html_lists_switch: Display the switch for different lists
|
|
function _html_lists_switch()
|
|
{
|
|
// Bounce for nothing
|
|
if (is_null($this->lists_switch) || count($this->lists_switch) == 0) {
|
|
return;
|
|
}
|
|
|
|
?><div>
|
|
<?php
|
|
for ($i = 0, $htmls = array(); $i < count($this->lists_switch); $i++) {
|
|
$htmls[] = " <a href=\"" . h($this->lists_switch[$i]["url"]) . "\">"
|
|
. h($this->lists_switch[$i]["title"]) . "</a>";
|
|
}
|
|
echo implode(" |\n", $htmls);
|
|
?></div>
|
|
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// _html_newlink: Display a link to add a new item
|
|
function _html_newlink($prompt = false)
|
|
{
|
|
// No new item creation if it is a called form
|
|
if ($this->_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);
|
|
?><p><a href="<?php echo h($url); ?>"><?php echo h($prompt); ?></a></p>
|
|
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// _html_search: Display the search box
|
|
function _html_search($prompt = false)
|
|
{
|
|
// No search box is displayed if no records yet
|
|
if ( $this->_fetched
|
|
&& !is_null($this->total) && $this->total == 0
|
|
&& is_null($this->_query)) {
|
|
return;
|
|
}
|
|
|
|
$label = C_("Search");
|
|
|
|
?><form action="<?php echo h(REQUEST_FILE); ?>" method="get"
|
|
accept-charset="<!--monica:charset-->">
|
|
<div class="searchbox">
|
|
<?php
|
|
// Embed the list type
|
|
if (array_key_exists("list", $this->_form)) {
|
|
$type = $this->_form["list"];
|
|
?><input type="hidden" name="list" value="<?php echo h($type); ?>" />
|
|
<?php
|
|
}
|
|
// Embed the caller information
|
|
if ($this->_is_called_form) {
|
|
?><input type="hidden" name="caller" value="<?php echo h($this->_caller); ?>" />
|
|
<input type="hidden" name="cformid" value="<?php echo h($this->_cformid); ?>" />
|
|
<?php
|
|
}
|
|
if (!is_null($prompt) && $prompt !== false) {
|
|
?><label for="query"><?php echo h($prompt); ?></label>
|
|
<?php
|
|
}
|
|
$defquery = C_("(query phrase)");
|
|
$query = !is_null($this->_query) && $this->_query != ""?
|
|
$this->_query: $defquery;
|
|
?><input id="query" type="text" name="query" value="<?php echo h($query); ?>"
|
|
onfocus="if (this.value == "<?php echo h($defquery); ?>") this.value = "";" />
|
|
<input type="hidden" name="charset" value="<!--monica:charset-->" />
|
|
<input type="submit" value="<?php echo h($label); ?>" />
|
|
</div>
|
|
</form>
|
|
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// _html_liststat: Display the list statistics
|
|
function _html_liststat()
|
|
{
|
|
// Don't show the list
|
|
if (is_null($this->total)) {
|
|
return;
|
|
}
|
|
$message = $this->_liststat_message();
|
|
if (is_null($message)) {
|
|
return;
|
|
}
|
|
?><p><?php echo h($message); ?></p>
|
|
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// _html_pagebar: Display a page navigation bar
|
|
// We display a page bar for scrolling between previous and next 2 pages
|
|
function _html_pagebar()
|
|
{
|
|
// Don't show the list
|
|
if (is_null($this->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) {
|
|
?><div class="pagebar">
|
|
<span><a href="."><?php echo h(C_("Index")); ?></a></span> |
|
|
<?php
|
|
// Dynamic page -- Display a paging form
|
|
} else {
|
|
// Base url without the "pageno" argument
|
|
$baseurl = rem_get_arg(REQUEST_FILEQS, "pageno");
|
|
?><form action="<?php echo h(REQUEST_FILE); ?>" method="get" accept-charset="<!--monica:charset-->">
|
|
<div class="pagebar">
|
|
<?php
|
|
if ($this->_is_called_form) {
|
|
?><input type="hidden" name="caller" value="<?php echo h($this->_caller); ?>" />
|
|
<input type="hidden" name="cformid" value="<?php echo h($this->_cformid); ?>" />
|
|
<?php
|
|
}
|
|
if (!is_null($this->_query)) {
|
|
?><input type="hidden" name="query" value="<?php echo h($this->_query); ?>" />
|
|
<?php
|
|
}
|
|
if (!is_null($this->_sortby) && $this->_sortby != "") {
|
|
?><input type="hidden" name="sortby" value="<?php echo h($this->_sortby); ?>" />
|
|
<?php
|
|
}
|
|
}
|
|
// The first page
|
|
$cell = h(C_("First"));
|
|
if ($this->_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 = "<a href=\"" . h($url) . "\">" . $cell . "</a>";
|
|
}
|
|
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 = "<a href=\"" . h($url) . "\">" . $cell . "</a>";
|
|
}
|
|
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 = "<a href=\"" . h($url) . "\">" . $cell . "</a>";
|
|
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 = "<a href=\"" . h($url) . "\">" . $cell . "</a>";
|
|
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 = "<a href=\"" . h($url) . "\">" . $cell . "</a>";
|
|
}
|
|
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 = "<a href=\"" . h($url) . "\">" . $cell . "</a>";
|
|
}
|
|
echo " $cell\n";
|
|
|
|
if ($this->_static) {
|
|
?></div>
|
|
|
|
<?php
|
|
} else {
|
|
$submit = C_("Page:");
|
|
?> <input type="submit" value="<?php echo h($submit); ?>" />
|
|
<input type="text" name="pageno" size="5" maxlength="5" value="<?php echo h($this->_pageno); ?>" />
|
|
<input type="hidden" name="charset" value="<!--monica:charset-->" />
|
|
</div>
|
|
</form>
|
|
|
|
<?php
|
|
}
|
|
// Cache it
|
|
$cache = ob_get_contents();
|
|
ob_end_clean();
|
|
// Output the cache
|
|
echo $cache;
|
|
|
|
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;
|
|
}
|
|
|
|
// 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.");
|
|
?><form action="<?php echo h(REQUEST_FILE); ?>" method="post">
|
|
<div><input type="hidden" name="form" value="_massdel" /><input
|
|
type="hidden" name="referer2" value="<?php echo h(REQUEST_FULLURI); ?>" /><input
|
|
type="submit" value="<?php echo h($massdel); ?>" /></div>
|
|
<?php
|
|
}
|
|
?><table class="deflist">
|
|
<colgroup><?php
|
|
if (!$this->_nonumber) {
|
|
echo "<col />";
|
|
}
|
|
if ($this->_massdel && !$this->_is_called_form) {
|
|
echo "<col />";
|
|
}
|
|
if (in_array("_viewurl", $this->_cols) && !$this->_is_called_form) {
|
|
echo "<col />";
|
|
}
|
|
if (!$this->_noselect) {
|
|
echo "<col />";
|
|
}
|
|
for ($i = 0; $i < count($this->_listcols); $i++) {
|
|
echo "<col />";
|
|
}
|
|
?></colgroup>
|
|
<thead>
|
|
<tr>
|
|
<?php
|
|
if (!$this->_nonumber) {
|
|
?> <th class="listno" scope="col"><?php echo h_abbr(C_("No.")); ?></th>
|
|
<?php
|
|
}
|
|
if ($this->_massdel && !$this->_is_called_form) {
|
|
?> <th class="listdel" scope="col"><?php echo h_abbr(C_("Delete")); ?></th>
|
|
<?php
|
|
}
|
|
if (in_array("_viewurl", $this->_cols) && !$this->_is_called_form) {
|
|
?> <th scope="col"><?php echo h_abbr(C_("View")); ?></th>
|
|
<?php
|
|
}
|
|
if (!$this->_noselect) {
|
|
?> <th scope="col"><?php echo h_abbr($this->_seltext); ?></th>
|
|
<?php
|
|
}
|
|
foreach ($this->_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)) {
|
|
?> <th scope="col"><?php echo h_abbr($label); ?></th>
|
|
<?php
|
|
} else {
|
|
$url = add_get_arg($baseurl, "sortby",
|
|
(($this->_sortby == $col)? "-" . $col: $col), DUP_OK);
|
|
?> <th scope="col"><a href="<?php echo h($url); ?>"><?php echo h_abbr($label); ?></a></th>
|
|
<?php
|
|
}
|
|
}
|
|
?></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
|
|
// Print each record
|
|
for ($i = 0; $i < count($this->_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"]);
|
|
}
|
|
}
|
|
|
|
?><tr class="<?php echo h($rowclass); ?>">
|
|
<?php
|
|
if (!$this->_nonumber) {
|
|
?> <td class="listno"><?php echo h($no); ?></td>
|
|
<?php
|
|
}
|
|
if ($this->_massdel && !$this->_is_called_form) {
|
|
$name = "delsn" . $current["sn"];
|
|
?> <td class="listdel"><input type="checkbox" name="<?php echo h($name); ?>" /></td>
|
|
<?php
|
|
}
|
|
if (in_array("_viewurl", $this->_cols) && !$this->_is_called_form) {
|
|
if (is_null($current["_viewurl"])) {
|
|
?> <td></td>
|
|
<?php
|
|
} else {
|
|
$viewurl = $current["_viewurl"];
|
|
?> <td><a href="<?php echo h($viewurl); ?>"><?php
|
|
echo h(C_("View")); ?></a></td>
|
|
<?php
|
|
}
|
|
}
|
|
if (!$this->_noselect) {
|
|
?> <td><?php
|
|
if ($issel) {
|
|
?><a href="<?php echo h($selurl); ?>"><?php
|
|
echo h($this->_seltext); ?></a><?php
|
|
}
|
|
?></td>
|
|
<?php
|
|
}
|
|
foreach ($this->_listcols as $col) {
|
|
?> <td><?php $this->_echo_colval($col, $current); ?></td>
|
|
<?php
|
|
}
|
|
?></tr>
|
|
<?php
|
|
}
|
|
?></tbody>
|
|
</table>
|
|
|
|
<?php
|
|
|
|
// Mass deletion -- surround it with a form
|
|
if ($this->_massdel && !$this->_is_called_form) {
|
|
$massdel = C_("Delete the selected items.");
|
|
?><div><input type="submit" value="<?php echo h($massdel); ?>" /></div>
|
|
</form>
|
|
|
|
<?php
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// _html_list_th: Display the table header cell of the list
|
|
function _html_list_th($baseurl, $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)) {
|
|
?> <th scope="col"><?php echo h_abbr($label); ?></th>
|
|
<?php
|
|
} else {
|
|
$url = add_get_arg($baseurl, "sortby",
|
|
(($this->_sortby == $col)? "-" . $col: $col), DUP_OK);
|
|
?> <th scope="col"><a href="<?php echo h($url); ?>"><?php echo h_abbr($label); ?></a></th>
|
|
<?php
|
|
}
|
|
}
|
|
|
|
// _html_listprefform: Display a form to change the list preference
|
|
function _html_listprefform()
|
|
{
|
|
// Don't show the list
|
|
if (is_null($this->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);
|
|
|
|
?><form class="listprefform" action="<?php echo h(REQUEST_FILE); ?>" method="post"
|
|
accept-charset="<!--monica:charset-->">
|
|
<p><input type="hidden" name="charset" value="<!--monica:charset-->" />
|
|
<input type="hidden" name="form" value="listpref" />
|
|
<input type="hidden" name="referer" value="<?php echo h($referer); ?>" />
|
|
<input type="hidden" name="domain" value="<?php echo h(get_class($this)); ?>" />
|
|
<?php
|
|
|
|
// The number of rows per page
|
|
?><label for="listsize"><?php echo h(C_("Rows per page:")); ?></label><input
|
|
id="listsize" type="text" name="listsize" size="5" maxlength="5" value="<?php echo h($this->_pagesize); ?>" />
|
|
<?php
|
|
|
|
// The display columns
|
|
echo h(C_("Display columns:")) . "\n";
|
|
foreach ($validcols as $col) {
|
|
$label = array_key_exists($col, $this->_col_labels)? $this->_col_labels[$col]:
|
|
$col;
|
|
$name = "listcols_" . $col;
|
|
?><span><input id="<?php echo h($name); ?>" type="checkbox" name="<?php echo h($name); ?>"<?php
|
|
if (in_array($col, $this->_listcols)) {
|
|
echo " checked=\"checked\"";
|
|
}
|
|
?> /><label for="<?php echo h($name); ?>"><?php echo h_abbr($label); ?></label></span>
|
|
<?php
|
|
}
|
|
|
|
?><input type="submit" name="confirm" value="<?php echo h($submit); ?>" /></p>
|
|
</form>
|
|
|
|
<?php
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// UsersList: Users list handler class
|
|
class UsersList extends BaseList
|
|
{
|
|
// __construct: Initialize the handler
|
|
function __construct($FORM = null, $table = "users")
|
|
{
|
|
parent::__construct($FORM, $table);
|
|
// The page title
|
|
$this->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);
|
|
|
|
?><form action="<?php echo h(REQUEST_FILE); ?>" method="get"
|
|
accept-charset="<!--monica:charset-->">
|
|
<div class="searchbox">
|
|
<label for="query"><?php echo h($prompt); ?></label><input
|
|
id="query" type="text" name="query" value="<?php echo h($query); ?>"
|
|
onfocus="if (this.value == "<?php echo h($defquery); ?>") this.value = "";" />
|
|
<label for="rows"><?php echo h(C_("Display rows:")); ?></label><input
|
|
id="rows" type="text" name="rows" size="<?php echo h($this->_rdgt); ?>" maxlength="<?php echo h($this->_rdgt); ?>" value="<?php echo h($rows); ?>" />
|
|
<input type="hidden" name="charset" value="<!--monica:charset-->" />
|
|
<input type="submit" value="<?php echo h($label); ?>" />
|
|
</div>
|
|
</form>
|
|
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// _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 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);
|
|
?><div>
|
|
<?php
|
|
echo a2html($html);
|
|
?></div>
|
|
|
|
<?php
|
|
return;
|
|
}
|
|
|
|
// _html_listprefform: Display a form to change the list preference
|
|
// Make it a null function
|
|
function _html_listprefform()
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
?>
|