330 lines
9.9 KiB
PHP
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;
|
|
}
|
|
}
|
|
|
|
?>
|