Files
selima-perl/lib/php/monica/page.inc.php
2026-03-10 21:31:43 +08:00

330 lines
9.9 KiB
PHP

<?php
// File name: page.inc.php
// Description: PHP classes to manage web pages
// Date: 2005-02-27
// Author: imacat <imacat@pristine.com.tw>
// Copyright: Copyright (C) 2005-2008 Pristine Communications
// Set the include path
if (!defined("INCPATH_SET")) {
require_once dirname(__FILE__) . "/incpath.inc.php";
}
// Referenced subroutines
require_once "monica/getlang.inc.php";
require_once "monica/lninfo.inc.php";
require_once "monica/sql.inc.php";
// Page: A web page
class Page
{
protected $_title;
protected $_path;
protected $_ord;
protected $_lang;
protected $_sitemap;
protected $_sub;
// __construct: Initiate the web page
function __construct($args)
{
// An array of arguments
if (is_array($args)) {
// Set the title
if (!array_key_exists("title", $args)) {
trigger_error("Please specify the page title.", E_USER_ERROR);
}
$this->title($args["title"]);
// Set the page path
if (!array_key_exists("path", $args)) {
trigger_error("Please specify the page path.", E_USER_ERROR);
}
$this->path($args["path"]);
// Set the order
$this->ord(array_key_exists("ord", $args)? $args["ord"]: 5000);
// Set the language
$this->lang(array_key_exists("lang", $args)? $args["lang"]: null);
// Set if this page is to be shown on the site map
$this->sitemap(array_key_exists("sitemap", $args)?
$args["sitemap"]: true);
// A Page object
} elseif (strtolower(get_class($args)) == "page") {
$this->title($args->title());
$this->path($args->path());
$this->ord($args->ord());
$this->lang($args->lang());
$this->sitemap($args->sitemap());
// Invalid argument
} else {
trigger_error("Please specify the page arguments.", E_USER_ERROR);
}
}
// title: Set/return the page title
function title($title = null)
{
if (func_num_args() > 0) {
$this->_title = $title;
}
return $this->_title;
}
// path: Set/return the page path
function path($path = null)
{
if (func_num_args() > 0) {
$this->_path = $path;
}
return $this->_path;
}
// ord: Set/return the page order
function ord($ord = null)
{
if (func_num_args() > 0) {
$this->_ord = $ord;
}
return $this->_ord;
}
// lang: Set/return the page language
function lang($lang = null)
{
if (func_num_args() > 0) {
// Delete it
if (is_null($lang)) {
$this->_lang = null;
// Set it
} else {
$this->_lang = $lang;
}
}
return $this->_lang;
}
// sitemap: Set/return if this page is to be shown on the site map
function sitemap($sitemap = true)
{
if (func_num_args() > 0) {
$this->_sitemap = $sitemap;
}
return $this->_sitemap;
}
// sub: Set/return the pages under this page
function sub($pagelist = null)
{
if (func_num_args() > 0) {
// Delete it
if (is_null($pagelist)) {
$this->_sub = null;
// Set it
} else {
// We only accept a PageList object
if (strtolower(get_class($pagelist)) != "pagelist") {
trigger_error("The sub() method of a Page object only accepts a PageList object.", E_USER_ERROR);
}
$this->_sub = $pagelist;
$index = new Page($this);
$index->sub(null);
$this->_sub->index($index);
}
}
return $this->_sub;
}
// compare_to: Compare the order with another page
function compare_to($another)
{
// We only compare to another Selima::Page object
if (strtolower(get_class($another)) != "page") {
trigger_error("The compare_to() method of a Page object only accepts another Page object.", E_USER_ERROR);
}
// Check the page order
if ($this->ord() != $another->ord()) {
return ($this->ord() < $another->ord()? -1: 1);
}
// Check the page path
if ($this->path() != $another->path()) {
return strcmp($this->path(), $another->path());
}
// Check the page title (should not)
if ($this->title() != $another->title()) {
return strcmp($this->title(), $another->title());
}
// Equal
return 0;
}
// fetch_subtree: Fetch the sub page tree from the database
function fetch_subtree()
{
// Not a directory - there is no sub page tree for them
if (substr($this->path(), -1) != "/") {
return;
}
// Compose the SQL statement
$cols = array();
if (count($GLOBALS["ALL_LINGUAS"]) > 1) {
$lndb = ln($this->lang(), LN_DATABASE);
$cols[] = "title_$lndb AS title";
} else {
$cols[] = "title AS title";
}
$cols[] = "ord AS ord";
$cols[] = "path AS path";
if (count($GLOBALS["ALL_LINGUAS"]) > 1) {
$cols[] = "'" . sql_esctext($this->lang()) . "' AS lang";
} else {
$cols[] = "'" . sql_esctext(getlang()) . "' AS lang";
}
$select = "SELECT " . implode(", ", $cols) . " FROM pages"
. " WHERE " . sql_is_false("hid")
. " AND path LIKE '" . sql_esclike($this->path()) . "_%'"
. " AND path NOT LIKE '" . sql_esclike($this->path()) . "_%/_%';\n";
$result = sql_query($select);
$count = sql_num_rows($result);
for ($i = 0, $pages = array(); $i < $count; $i++) {
$row = sql_fetch_assoc($result);
$pages[] = new Page($row);
}
// Recursively fetch the sub page tree
for ($i = 0; $i < count($pages); $i++) {
$pages[$i]->fetch_subtree();
}
// Save it
$this->sub(new PageList($pages));
return;
}
// fetch_full_page_tree: Fetch the full page tree from the database
static function fetch_full_page_tree($lang = null)
{
// Get the available language list
global $ALL_LINGUAS;
// Cache the result
static $tree = null;
// The language
if (is_null($lang)) {
$lang = getlang();
}
// Multi-lingual - obtain each language tree
if (count($ALL_LINGUAS) > 0) {
if (is_null($tree)) {
$tree = array();
}
// Not cached yet
if (!array_key_exists($lang, $tree)) {
$tree[$lang] = new Page(array(
"title" => "",
"path" => "/",
"ord" => 5000,
"lang" => $lang,
));
$tree[$lang]->fetch_subtree();
}
return $tree[$lang];
// Uni-lingual
} else {
// Not cached yet
if (is_null($tree)) {
$tree = new Page(array(
"title" => "",
"path" => "/",
"ord" => 5000,
"lang" => $lang,
));
$tree->fetch_subtree();
}
return $tree;
}
}
// neighbor_pages: Obtain the neighbor pages for a specific page path
static function neighbor_pages($path, $lang = null)
{
// Obtain the full apge tree
$tree = self::fetch_full_page_tree($lang);
// Obtain each level of directories
$dirs = array();
while ($path = preg_replace("/\/[^\/]+\/?$/", "/", $path)) {
array_unshift($dirs, $path);
}
// Nothing - path is "/" (root directory)
if (count($dirs) == 0) {
return $tree->sub();
}
}
}
// PageList: A list of web pages
class PageList
{
protected $_index = null;
protected $_pages = array();
// __construct: Initiate the list of web pages
function __construct($pages)
{
$this->_pages = array();
$this->add($pages);
}
// add: Add web pages to the page list
function add($pages)
{
// Add all the pages
for ($i = 0; $i < count($pages); $i++) {
// We only accept Page objects
if (strtolower(get_class($pages[$i])) != "page") {
trigger_error("The add() method of a PageList object only accepts Page objects.", E_USER_ERROR);
}
// Find the page after the added page
for ($j = 0; $j < count($this->_pages); $j++) {
if ($pages[$i]->compare_to($this->_pages[$j]) < 0) {
break;
}
}
// Insert the page
$this->_pages = array_merge(
array_slice($this->_pages, 0, $j),
array($pages[$i]),
array_slice($this->_pages, $j)
);
}
return;
}
// index: Set/return the index page
function index($page)
{
if (func_num_args() > 0) {
// Delete it
if (is_null($page)) {
$this->_index = null;
// Set it
} else {
// We only accept a Page object
if (strtolower(get_class($page)) != "page") {
trigger_error("The index() method of a PageList object only accepts a Page object.", E_USER_ERROR);
}
$this->_index = $page;
}
}
return $this->_index;
}
// pages: Return the pages
function pages()
{
return $this->_pages;
}
}
?>