lots of docs
This commit is contained in:
parent
24b715424b
commit
627ecdbf4c
12 changed files with 648 additions and 139 deletions
43
core/README
Normal file
43
core/README
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
The Highest Level
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
index.php takes care of loading the globals:
|
||||||
|
|
||||||
|
$config -- some variety of Config class
|
||||||
|
$database -- a class used to get raw SQL access
|
||||||
|
$page -- a GenericPage object, a data structure which holds all the page parts
|
||||||
|
$user -- the currently logged in User
|
||||||
|
|
||||||
|
then it sends an InitExtEvent and PageRequestEvent, these can each trigger
|
||||||
|
more events of their own.
|
||||||
|
|
||||||
|
Once the chain of events comes to an end, the $page object is passed
|
||||||
|
to the theme's layout.class.php to be turned into HTML
|
||||||
|
|
||||||
|
|
||||||
|
Events and Extensions
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
An event is a little blob of data saying "something happened", possibly
|
||||||
|
"something happened, here's the specific data". Events are sent with the
|
||||||
|
send_event() function.
|
||||||
|
|
||||||
|
An extension is something which is capable of reacting to events. They
|
||||||
|
register themselves using the add_event_listener() command. (Although for
|
||||||
|
subclasses of SimpleExtension, registration is handled automatically).
|
||||||
|
|
||||||
|
|
||||||
|
Themes
|
||||||
|
~~~~~~
|
||||||
|
Each extension has a theme with a specific name -- the extension Cake which
|
||||||
|
is stored in ext/cake/main.php will have a theme called CakeTheme stored in
|
||||||
|
ext/cake/theme.php. If you want to customise it, create a class in the file
|
||||||
|
themes/mytheme/cake.theme.php called CustomCakeTheme which extends CakeTheme
|
||||||
|
and overrides some of its methods.
|
||||||
|
|
||||||
|
Generally an extension should only deal with processing data; whenever it
|
||||||
|
wants to display something, it should pass the $page data structure along
|
||||||
|
with the data to be displayed to the theme object, and the theme will add
|
||||||
|
the data into the page.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,38 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
* A basic chunk of page
|
* @package SCore
|
||||||
* $header -- the block's title
|
*/
|
||||||
* $body -- the content
|
|
||||||
* $section -- where the block should be placed. The default theme supports
|
/**
|
||||||
* "main" and "left", other themes can add their own areas
|
* A basic chunk of a page
|
||||||
* $position -- how far down the section the block should appear, higher
|
|
||||||
* numbers appear lower. The scale is 0-100 by convention,
|
|
||||||
* though any number or string will work.
|
|
||||||
*/
|
*/
|
||||||
class Block {
|
class Block {
|
||||||
|
/**
|
||||||
|
* The block's title
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
var $header;
|
var $header;
|
||||||
|
/**
|
||||||
|
* The content
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
var $body;
|
var $body;
|
||||||
|
/**
|
||||||
|
* Where the block should be placed. The default theme supports
|
||||||
|
* "main" and "left", other themes can add their own areas
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
var $section;
|
var $section;
|
||||||
|
/**
|
||||||
|
* How far down the section the block should appear, higher
|
||||||
|
* numbers appear lower. The scale is 0-100 by convention,
|
||||||
|
* though any number or string will work.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
var $position;
|
var $position;
|
||||||
|
|
||||||
public function __construct($header, $body, $section="main", $position=50) {
|
public function __construct($header, $body, $section="main", $position=50) {
|
||||||
|
@ -24,9 +44,10 @@ class Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* A generic navigation block with a link to the main page. Used
|
* A generic navigation block with a link to the main page.
|
||||||
* because "new NavBlock()" is easier than "new Block('Navigation', ..."
|
*
|
||||||
|
* Used because "new NavBlock()" is easier than "new Block('Navigation', ..."
|
||||||
*/
|
*/
|
||||||
class NavBlock extends Block {
|
class NavBlock extends Block {
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
* Functions which are only in some versions of PHP,
|
* Functions which are only in some versions of PHP,
|
||||||
* or only implemented on some platforms
|
* or only implemented on some platforms
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
|
* @package SCore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
# (PHP 5 >= 5.2.1)
|
# (PHP 5 >= 5.2.1)
|
||||||
# Based on http://www.phpit.net/
|
# Based on http://www.phpit.net/
|
||||||
# article/creating-zip-tar-archives-dynamically-php/2/
|
# article/creating-zip-tar-archives-dynamically-php/2/
|
||||||
if(!function_exists('sys_get_temp_dir')) {
|
if(!function_exists('sys_get_temp_dir')) {
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function sys_get_temp_dir() {
|
function sys_get_temp_dir() {
|
||||||
// Try to get from environment variable
|
// Try to get from environment variable
|
||||||
if(!empty($_ENV['TMP'])) {
|
if(!empty($_ENV['TMP'])) {
|
||||||
|
@ -40,6 +46,9 @@ function sys_get_temp_dir() {
|
||||||
# (PHP >= 5.1)
|
# (PHP >= 5.1)
|
||||||
# from http://www.php.net/inet_pton
|
# from http://www.php.net/inet_pton
|
||||||
if(!function_exists('inet_pton')) {
|
if(!function_exists('inet_pton')) {
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function inet_pton($ip) {
|
function inet_pton($ip) {
|
||||||
# ipv4
|
# ipv4
|
||||||
if(strpos($ip, '.') !== FALSE) {
|
if(strpos($ip, '.') !== FALSE) {
|
||||||
|
@ -61,6 +70,9 @@ function inet_pton($ip) {
|
||||||
# (PHP >= 5.1)
|
# (PHP >= 5.1)
|
||||||
# from http://www.php.net/inet_ntop
|
# from http://www.php.net/inet_ntop
|
||||||
if(!function_exists('inet_ntop')) {
|
if(!function_exists('inet_ntop')) {
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function inet_ntop($ip) {
|
function inet_ntop($ip) {
|
||||||
if (strlen($ip)==4) {
|
if (strlen($ip)==4) {
|
||||||
// ipv4
|
// ipv4
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
|
* @package SCore
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
* an abstract interface for altering a name:value pair list
|
* an abstract interface for altering a name:value pair list
|
||||||
*/
|
*/
|
||||||
interface Config {
|
interface Config {
|
||||||
|
@ -22,9 +26,11 @@ interface Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Common methods for manipulating the list, loading and saving is
|
* Common methods for manipulating the list, loading and saving is
|
||||||
* left to the concrete implementation
|
* left to the concrete implementation
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
*/
|
*/
|
||||||
abstract class BaseConfig implements Config {
|
abstract class BaseConfig implements Config {
|
||||||
var $values = array();
|
var $values = array();
|
||||||
|
@ -93,13 +99,15 @@ abstract class BaseConfig implements Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Loads the config list from a PHP file; the file should be in the format:
|
* Loads the config list from a PHP file; the file should be in the format:
|
||||||
*
|
*
|
||||||
* <?php
|
* <?php
|
||||||
* $config['foo'] = "bar";
|
* $config['foo'] = "bar";
|
||||||
* $config['baz'] = "qux";
|
* $config['baz'] = "qux";
|
||||||
* ?>
|
* ?>
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
*/
|
*/
|
||||||
class StaticConfig extends BaseConfig {
|
class StaticConfig extends BaseConfig {
|
||||||
public function __construct($filename) {
|
public function __construct($filename) {
|
||||||
|
@ -123,7 +131,7 @@ class StaticConfig extends BaseConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Loads the config list from a table in a given database, the table should
|
* Loads the config list from a table in a given database, the table should
|
||||||
* be called config and have the schema:
|
* be called config and have the schema:
|
||||||
*
|
*
|
||||||
|
@ -131,6 +139,8 @@ class StaticConfig extends BaseConfig {
|
||||||
* name VARCHAR(255) NOT NULL,
|
* name VARCHAR(255) NOT NULL,
|
||||||
* value TEXT
|
* value TEXT
|
||||||
* );
|
* );
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
*/
|
*/
|
||||||
class DatabaseConfig extends BaseConfig {
|
class DatabaseConfig extends BaseConfig {
|
||||||
var $database = null;
|
var $database = null;
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* @package SCore
|
||||||
|
*/
|
||||||
|
|
||||||
require_once "compat.inc.php";
|
require_once "compat.inc.php";
|
||||||
$ADODB_CACHE_DIR=sys_get_temp_dir();
|
$ADODB_CACHE_DIR=sys_get_temp_dir();
|
||||||
require_once "lib/adodb/adodb.inc.php";
|
require_once "lib/adodb/adodb.inc.php";
|
||||||
require_once "lib/adodb/adodb-exceptions.inc.php";
|
require_once "lib/adodb/adodb-exceptions.inc.php";
|
||||||
|
|
||||||
/* Querylet {{{
|
/**#@+
|
||||||
* A fragment of a query, used to build large search queries
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
// Querylet {{{
|
||||||
class Querylet {
|
class Querylet {
|
||||||
var $sql;
|
var $sql;
|
||||||
var $variables;
|
var $variables;
|
||||||
|
@ -197,17 +202,28 @@ class MemCache implements CacheEngine {
|
||||||
public function get_misses() {return $this->misses;}
|
public function get_misses() {return $this->misses;}
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
/**#@-*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* A class for controlled database access
|
* A class for controlled database access
|
||||||
*/
|
*/
|
||||||
class Database {
|
class Database {
|
||||||
|
/**
|
||||||
|
* The ADODB database connection object, for anyone who wants direct access
|
||||||
|
*/
|
||||||
var $db;
|
var $db;
|
||||||
var $extensions;
|
|
||||||
|
/**
|
||||||
|
* Meta info about the database engine
|
||||||
|
*/
|
||||||
var $engine = null;
|
var $engine = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently active cache engine
|
||||||
|
*/
|
||||||
var $cache = null;
|
var $cache = null;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Create a new database object using connection info
|
* Create a new database object using connection info
|
||||||
* stored in config.php in the root shimmie folder
|
* stored in config.php in the root shimmie folder
|
||||||
*/
|
*/
|
||||||
|
@ -263,6 +279,9 @@ class Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute an SQL query and return an ADODB resultset
|
||||||
|
*/
|
||||||
public function execute($query, $args=array()) {
|
public function execute($query, $args=array()) {
|
||||||
$result = $this->db->Execute($query, $args);
|
$result = $this->db->Execute($query, $args);
|
||||||
if($result === False) {
|
if($result === False) {
|
||||||
|
@ -274,6 +293,9 @@ class Database {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute an SQL query and return a 2D array
|
||||||
|
*/
|
||||||
public function get_all($query, $args=array()) {
|
public function get_all($query, $args=array()) {
|
||||||
$result = $this->db->GetAll($query, $args);
|
$result = $this->db->GetAll($query, $args);
|
||||||
if($result === False) {
|
if($result === False) {
|
||||||
|
@ -285,6 +307,9 @@ class Database {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute an SQL query and return a single row
|
||||||
|
*/
|
||||||
public function get_row($query, $args=array()) {
|
public function get_row($query, $args=array()) {
|
||||||
$result = $this->db->GetRow($query, $args);
|
$result = $this->db->GetRow($query, $args);
|
||||||
if($result === False) {
|
if($result === False) {
|
||||||
|
@ -301,6 +326,9 @@ class Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a table from pseudo-SQL
|
||||||
|
*/
|
||||||
public function create_table($name, $data) {
|
public function create_table($name, $data) {
|
||||||
$this->execute($this->engine->create_table_sql($name, $data));
|
$this->execute($this->engine->create_table_sql($name, $data));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,27 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
* Event:
|
* @package SCore
|
||||||
* generic parent class
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic parent class for all events.
|
||||||
|
*
|
||||||
|
* An event is anything that can be passed around via send_event($blah)
|
||||||
*/
|
*/
|
||||||
abstract class Event {
|
abstract class Event {
|
||||||
public function __construct() {}
|
public function __construct() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* InitExtEvent:
|
|
||||||
* A wake-up call for extensions
|
* A wake-up call for extensions
|
||||||
*/
|
*/
|
||||||
class InitExtEvent extends Event {}
|
class InitExtEvent extends Event {}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* PageRequestEvent:
|
* A signal that a page has been requested.
|
||||||
|
*
|
||||||
* User requests /view/42 -> an event is generated with $args = array("view",
|
* User requests /view/42 -> an event is generated with $args = array("view",
|
||||||
* "42"); when an event handler asks $event->page_matches("view"), it returns
|
* "42"); when an event handler asks $event->page_matches("view"), it returns
|
||||||
* true and ignores the matched part, such that $event->count_args() = 1 and
|
* true and ignores the matched part, such that $event->count_args() = 1 and
|
||||||
|
@ -25,7 +30,6 @@ class InitExtEvent extends Event {}
|
||||||
class PageRequestEvent extends Event {
|
class PageRequestEvent extends Event {
|
||||||
var $args;
|
var $args;
|
||||||
var $arg_count;
|
var $arg_count;
|
||||||
|
|
||||||
var $part_count;
|
var $part_count;
|
||||||
|
|
||||||
public function __construct($args) {
|
public function __construct($args) {
|
||||||
|
@ -33,6 +37,11 @@ class PageRequestEvent extends Event {
|
||||||
$this->arg_count = count($args);
|
$this->arg_count = count($args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if the requested path matches a given pattern.
|
||||||
|
*
|
||||||
|
* If it matches, store the remaining path elements in $args
|
||||||
|
*/
|
||||||
public function page_matches($name) {
|
public function page_matches($name) {
|
||||||
$parts = explode("/", $name);
|
$parts = explode("/", $name);
|
||||||
$this->part_count = count($parts);
|
$this->part_count = count($parts);
|
||||||
|
@ -66,18 +75,27 @@ class PageRequestEvent extends Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* TextFormattingEvent:
|
* A signal that some text needs formatting, the event carries
|
||||||
* $original - for reference
|
* both the text and the result
|
||||||
* $formatted - with formatting applied
|
|
||||||
* $stripped - with formatting removed
|
|
||||||
*/
|
*/
|
||||||
class TextFormattingEvent extends Event {
|
class TextFormattingEvent extends Event {
|
||||||
|
/**
|
||||||
|
* For reference
|
||||||
|
*/
|
||||||
var $original;
|
var $original;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with formatting applied
|
||||||
|
*/
|
||||||
var $formatted;
|
var $formatted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* with formatting removed
|
||||||
|
*/
|
||||||
var $stripped;
|
var $stripped;
|
||||||
|
|
||||||
public function TextFormattingEvent($text) {
|
public function __construct($text) {
|
||||||
$h_text = html_escape(trim($text));
|
$h_text = html_escape(trim($text));
|
||||||
$this->original = $h_text;
|
$this->original = $h_text;
|
||||||
$this->formatted = $h_text;
|
$this->formatted = $h_text;
|
||||||
|
@ -86,16 +104,36 @@ class TextFormattingEvent extends Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* LogEvent
|
* A signal that something needs logging
|
||||||
* $section = a category, normally the extension name
|
|
||||||
* $priority = see python
|
|
||||||
* $message = free text
|
|
||||||
*/
|
*/
|
||||||
class LogEvent extends Event {
|
class LogEvent extends Event {
|
||||||
|
/**
|
||||||
|
* a category, normally the extension name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
var $section;
|
var $section;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See python...
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
var $priority = 0;
|
var $priority = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free text to be logged
|
||||||
|
*
|
||||||
|
* @var text
|
||||||
|
*/
|
||||||
var $message;
|
var $message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The time that the event was created
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
var $time;
|
var $time;
|
||||||
|
|
||||||
public function __construct($section, $priority, $message) {
|
public function __construct($section, $priority, $message) {
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* @package SCore
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base exception to be caught by the upper levels
|
||||||
|
*/
|
||||||
class SCoreException extends Exception {}
|
class SCoreException extends Exception {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fairly common, generic exception
|
||||||
|
*/
|
||||||
class PermissionDeniedException extends SCoreException {}
|
class PermissionDeniedException extends SCoreException {}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
|
* @package SCore
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
* A generic extension class, for subclassing
|
* A generic extension class, for subclassing
|
||||||
*/
|
*/
|
||||||
interface Extension {
|
interface Extension {
|
||||||
public function receive_event(Event $event);
|
public function receive_event(Event $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* send_event(BlahEvent()) -> onBlah($event)
|
* send_event(BlahEvent()) -> onBlah($event)
|
||||||
*
|
*
|
||||||
* Also loads the theme object into $this->theme if available
|
* Also loads the theme object into $this->theme if available
|
||||||
|
@ -40,7 +44,7 @@ abstract class SimpleExtension implements Extension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Several extensions have this in common, make a common API
|
* Several extensions have this in common, make a common API
|
||||||
*/
|
*/
|
||||||
abstract class FormatterExtension implements Extension {
|
abstract class FormatterExtension implements Extension {
|
||||||
|
@ -55,7 +59,7 @@ abstract class FormatterExtension implements Extension {
|
||||||
abstract public function strip($text);
|
abstract public function strip($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* This too is a common class of extension with many methods in common,
|
* This too is a common class of extension with many methods in common,
|
||||||
* so we have a base class to extend from
|
* so we have a base class to extend from
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
* All the imageboard-specific bits of code should be in this file, everything
|
* All the imageboard-specific bits of code should be in this file, everything
|
||||||
* else in /core should be standard SCore bits.
|
* else in /core should be standard SCore bits.
|
||||||
|
*
|
||||||
|
* @package SCore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
||||||
* Classes *
|
* Classes *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* An object representing an entry in the images table. As of 2.2, this no
|
* An object representing an entry in the images table. As of 2.2, this no
|
||||||
* longer necessarily represents an image per se, but could be a video,
|
* longer necessarily represents an image per se, but could be a video,
|
||||||
* sound file, or any other supported upload type.
|
* sound file, or any other supported upload type.
|
||||||
|
@ -23,8 +24,9 @@ class Image {
|
||||||
var $posted;
|
var $posted;
|
||||||
var $source;
|
var $source;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Constructors and other instance creators
|
* One will very rarely construct an image directly, more common
|
||||||
|
* would be to use Image::by_id, Image::by_hash, etc
|
||||||
*/
|
*/
|
||||||
public function Image($row=null) {
|
public function Image($row=null) {
|
||||||
if(!is_null($row)) {
|
if(!is_null($row)) {
|
||||||
|
@ -37,6 +39,11 @@ class Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an image by ID
|
||||||
|
*
|
||||||
|
* @var Image
|
||||||
|
*/
|
||||||
public static function by_id($id) {
|
public static function by_id($id) {
|
||||||
assert(is_numeric($id));
|
assert(is_numeric($id));
|
||||||
global $database;
|
global $database;
|
||||||
|
@ -45,6 +52,11 @@ class Image {
|
||||||
return ($row ? new Image($row) : null);
|
return ($row ? new Image($row) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an image by hash
|
||||||
|
*
|
||||||
|
* @var Image
|
||||||
|
*/
|
||||||
public static function by_hash($hash) {
|
public static function by_hash($hash) {
|
||||||
assert(is_string($hash));
|
assert(is_string($hash));
|
||||||
global $database;
|
global $database;
|
||||||
|
@ -53,6 +65,11 @@ class Image {
|
||||||
return ($row ? new Image($row) : null);
|
return ($row ? new Image($row) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick a random image out of a set
|
||||||
|
*
|
||||||
|
* @var Image
|
||||||
|
*/
|
||||||
public static function by_random($tags=array()) {
|
public static function by_random($tags=array()) {
|
||||||
assert(is_array($tags));
|
assert(is_array($tags));
|
||||||
$max = Image::count_images($tags);
|
$max = Image::count_images($tags);
|
||||||
|
@ -62,6 +79,9 @@ class Image {
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for an array of images
|
||||||
|
*/
|
||||||
public static function find_images($start, $limit, $tags=array()) {
|
public static function find_images($start, $limit, $tags=array()) {
|
||||||
assert(is_numeric($start));
|
assert(is_numeric($start));
|
||||||
assert(is_numeric($limit));
|
assert(is_numeric($limit));
|
||||||
|
@ -87,6 +107,10 @@ class Image {
|
||||||
/*
|
/*
|
||||||
* Image-related utility functions
|
* Image-related utility functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of image results for a given search
|
||||||
|
*/
|
||||||
public static function count_images($tags=array()) {
|
public static function count_images($tags=array()) {
|
||||||
assert(is_array($tags));
|
assert(is_array($tags));
|
||||||
global $database;
|
global $database;
|
||||||
|
@ -100,6 +124,9 @@ class Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of pages for a given search
|
||||||
|
*/
|
||||||
public static function count_pages($tags=array()) {
|
public static function count_pages($tags=array()) {
|
||||||
assert(is_array($tags));
|
assert(is_array($tags));
|
||||||
global $config, $database;
|
global $config, $database;
|
||||||
|
@ -111,6 +138,15 @@ class Image {
|
||||||
/*
|
/*
|
||||||
* Accessors & mutators
|
* Accessors & mutators
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the next image in the sequence.
|
||||||
|
*
|
||||||
|
* Rather than simply $this_id + 1, one must take into account
|
||||||
|
* deleted images and search queries
|
||||||
|
*
|
||||||
|
* @var Image
|
||||||
|
*/
|
||||||
public function get_next($tags=array(), $next=true) {
|
public function get_next($tags=array(), $next=true) {
|
||||||
assert(is_array($tags));
|
assert(is_array($tags));
|
||||||
assert(is_bool($next));
|
assert(is_bool($next));
|
||||||
|
@ -138,14 +174,27 @@ class Image {
|
||||||
return ($row ? new Image($row) : null);
|
return ($row ? new Image($row) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reverse of get_next
|
||||||
|
*
|
||||||
|
* @var Image
|
||||||
|
*/
|
||||||
public function get_prev($tags=array()) {
|
public function get_prev($tags=array()) {
|
||||||
return $this->get_next($tags, false);
|
return $this->get_next($tags, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the User who owns this Image
|
||||||
|
*
|
||||||
|
* @var User
|
||||||
|
*/
|
||||||
public function get_owner() {
|
public function get_owner() {
|
||||||
return User::by_id($this->owner_id);
|
return User::by_id($this->owner_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this image's tags as an array
|
||||||
|
*/
|
||||||
public function get_tag_array() {
|
public function get_tag_array() {
|
||||||
global $database;
|
global $database;
|
||||||
$cached = $database->cache->get("image-{$this->id}-tags");
|
$cached = $database->cache->get("image-{$this->id}-tags");
|
||||||
|
@ -164,10 +213,18 @@ class Image {
|
||||||
return $this->tag_array;
|
return $this->tag_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this image's tags as a string
|
||||||
|
*/
|
||||||
public function get_tag_list() {
|
public function get_tag_list() {
|
||||||
return implode(' ', $this->get_tag_array());
|
return implode(' ', $this->get_tag_array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the URL for the full size image
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_image_link() {
|
public function get_image_link() {
|
||||||
global $config;
|
global $config;
|
||||||
if(strlen($config->get_string('image_ilink')) > 0) {
|
if(strlen($config->get_string('image_ilink')) > 0) {
|
||||||
|
@ -181,11 +238,22 @@ class Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a short link to the full size image
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_short_link() {
|
public function get_short_link() {
|
||||||
global $config;
|
global $config;
|
||||||
return $this->parse_link_template($config->get_string('image_slink'));
|
return $this->parse_link_template($config->get_string('image_slink'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the URL for the thumbnail
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_thumb_link() {
|
public function get_thumb_link() {
|
||||||
global $config;
|
global $config;
|
||||||
if(strlen($config->get_string('image_tlink')) > 0) {
|
if(strlen($config->get_string('image_tlink')) > 0) {
|
||||||
|
@ -199,11 +267,22 @@ class Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tooltip for this image, formatted according to the
|
||||||
|
* configured template
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_tooltip() {
|
public function get_tooltip() {
|
||||||
global $config;
|
global $config;
|
||||||
return $this->parse_link_template($config->get_string('image_tip'), "html_escape");
|
return $this->parse_link_template($config->get_string('image_tip'), "html_escape");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figure out where the full size image is on disk
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_image_filename() {
|
public function get_image_filename() {
|
||||||
$hash = $this->hash;
|
$hash = $this->hash;
|
||||||
$ab = substr($hash, 0, 2);
|
$ab = substr($hash, 0, 2);
|
||||||
|
@ -211,34 +290,69 @@ class Image {
|
||||||
return "images/$ab/$hash";
|
return "images/$ab/$hash";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figure out where the thumbnail is on disk
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_thumb_filename() {
|
public function get_thumb_filename() {
|
||||||
$hash = $this->hash;
|
$hash = $this->hash;
|
||||||
$ab = substr($hash, 0, 2);
|
$ab = substr($hash, 0, 2);
|
||||||
return "thumbs/$ab/$hash";
|
return "thumbs/$ab/$hash";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the original filename
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_filename() {
|
public function get_filename() {
|
||||||
return $this->filename;
|
return $this->filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the image's mime type
|
||||||
|
*
|
||||||
|
* FIXME: now we handle more than just images
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_mime_type() {
|
public function get_mime_type() {
|
||||||
return "image/".($this->ext);
|
return "image/".($this->ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the image's filename extension
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_ext() {
|
public function get_ext() {
|
||||||
return $this->ext;
|
return $this->ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the image's source URL
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function get_source() {
|
public function get_source() {
|
||||||
return $this->source;
|
return $this->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the image's source URL
|
||||||
|
*/
|
||||||
public function set_source($source) {
|
public function set_source($source) {
|
||||||
global $database;
|
global $database;
|
||||||
if(empty($source)) $source = null;
|
if(empty($source)) $source = null;
|
||||||
$database->execute("UPDATE images SET source=? WHERE id=?", array($source, $this->id));
|
$database->execute("UPDATE images SET source=? WHERE id=?", array($source, $this->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all tags from this image.
|
||||||
|
*
|
||||||
|
* Normally in preparation to set them to a new set.
|
||||||
|
*/
|
||||||
public function delete_tags_from_image() {
|
public function delete_tags_from_image() {
|
||||||
global $database;
|
global $database;
|
||||||
$database->execute(
|
$database->execute(
|
||||||
|
@ -247,6 +361,9 @@ class Image {
|
||||||
$database->execute("DELETE FROM image_tags WHERE image_id=?", array($this->id));
|
$database->execute("DELETE FROM image_tags WHERE image_id=?", array($this->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the tags for this image
|
||||||
|
*/
|
||||||
public function set_tags($tags) {
|
public function set_tags($tags) {
|
||||||
global $database;
|
global $database;
|
||||||
$tags = Tag::resolve_list($tags);
|
$tags = Tag::resolve_list($tags);
|
||||||
|
@ -287,9 +404,8 @@ class Image {
|
||||||
$database->cache->delete("image-{$this->id}-tags");
|
$database->cache->delete("image-{$this->id}-tags");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
* Delete this image from the database and disk
|
||||||
* Other actions
|
|
||||||
*/
|
*/
|
||||||
public function delete() {
|
public function delete() {
|
||||||
global $database;
|
global $database;
|
||||||
|
@ -301,6 +417,11 @@ class Image {
|
||||||
unlink($this->get_thumb_filename());
|
unlink($this->get_thumb_filename());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ...?
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
public function parse_link_template($tmpl, $_escape="url_escape") {
|
public function parse_link_template($tmpl, $_escape="url_escape") {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
|
@ -649,7 +770,15 @@ class Image {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class for organising the tag related functions.
|
||||||
|
*
|
||||||
|
* All the methods are static, one should never actually use a tag object.
|
||||||
|
*/
|
||||||
class Tag {
|
class Tag {
|
||||||
|
/**
|
||||||
|
* Remove any excess fluff from a user-input tag
|
||||||
|
*/
|
||||||
public static function sanitise($tag) {
|
public static function sanitise($tag) {
|
||||||
assert(is_string($tag));
|
assert(is_string($tag));
|
||||||
$tag = preg_replace("/[\s?*]/", "", $tag);
|
$tag = preg_replace("/[\s?*]/", "", $tag);
|
||||||
|
@ -658,16 +787,18 @@ class Tag {
|
||||||
return $tag;
|
return $tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn any string or array into a valid tag array
|
||||||
|
*/
|
||||||
public static function explode($tags) {
|
public static function explode($tags) {
|
||||||
|
assert(is_string($tags) || is_array($tags));
|
||||||
|
|
||||||
if(is_string($tags)) {
|
if(is_string($tags)) {
|
||||||
$tags = explode(' ', $tags);
|
$tags = explode(' ', $tags);
|
||||||
}
|
}
|
||||||
else if(is_array($tags)) {
|
else if(is_array($tags)) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
die("Tag::explode() only takes strings or arrays");
|
|
||||||
}
|
|
||||||
|
|
||||||
$tags = array_map("trim", $tags);
|
$tags = array_map("trim", $tags);
|
||||||
|
|
||||||
|
@ -729,83 +860,14 @@ class Tag {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
|
||||||
* Debugging functions *
|
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
function get_debug_info() {
|
|
||||||
global $config, $_event_count;
|
|
||||||
|
|
||||||
if(function_exists('memory_get_usage')) {
|
|
||||||
$i_mem = sprintf("%5.2f", ((memory_get_usage()+512)/1024)/1024);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$i_mem = "???";
|
|
||||||
}
|
|
||||||
if(function_exists('getrusage')) {
|
|
||||||
$ru = getrusage();
|
|
||||||
$i_utime = sprintf("%5.2f", ($ru["ru_utime.tv_sec"]*1e6+$ru["ru_utime.tv_usec"])/1000000);
|
|
||||||
$i_stime = sprintf("%5.2f", ($ru["ru_stime.tv_sec"]*1e6+$ru["ru_stime.tv_usec"])/1000000);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$i_utime = "???";
|
|
||||||
$i_stime = "???";
|
|
||||||
}
|
|
||||||
$i_files = count(get_included_files());
|
|
||||||
global $_execs;
|
|
||||||
global $database;
|
|
||||||
$hits = $database->cache->get_hits();
|
|
||||||
$miss = $database->cache->get_misses();
|
|
||||||
$debug = "<br>Took $i_utime + $i_stime seconds and {$i_mem}MB of RAM";
|
|
||||||
$debug .= "; Used $i_files files and $_execs queries";
|
|
||||||
$debug .= "; Sent $_event_count events";
|
|
||||||
$debug .= "; $hits cache hits and $miss misses";
|
|
||||||
|
|
||||||
return $debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
// print_obj ($object, $title, $return)
|
|
||||||
function print_obj($object,$title="Object Information", $return=false) {
|
|
||||||
global $user;
|
|
||||||
if(DEBUG && isset($_GET['debug']) && $user->is_admin()) {
|
|
||||||
$pr = print_r($object,true);
|
|
||||||
$count = substr_count($pr,"\n")<=25?substr_count($pr,"\n"):25;
|
|
||||||
$pr = "<textarea rows='".$count."' cols='80'>$pr</textarea>";
|
|
||||||
|
|
||||||
if($return) {
|
|
||||||
return $pr;
|
|
||||||
} else {
|
|
||||||
global $page;
|
|
||||||
$page->add_block(new Block($title,$pr,"main",1000));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// preset tests.
|
|
||||||
|
|
||||||
// Prints the contents of $event->args, even though they are clearly visible in
|
|
||||||
// the URL bar.
|
|
||||||
function print_url_args() {
|
|
||||||
global $event;
|
|
||||||
print_obj($event->args,"URL Arguments");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prints all the POST data.
|
|
||||||
function print_POST() {
|
|
||||||
print_obj($_POST,"\$_POST");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prints GET, though this is also visible in the url ( url?var&var&var)
|
|
||||||
function print_GET() {
|
|
||||||
print_obj($_GET,"\$_GET");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
||||||
* Misc functions *
|
* Misc functions *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move a file from PHP's temporary area into shimmie's image storage
|
||||||
|
* heirachy, or throw an exception trying
|
||||||
|
*/
|
||||||
function move_upload_to_archive($event) {
|
function move_upload_to_archive($event) {
|
||||||
$hash = $event->hash;
|
$hash = $event->hash;
|
||||||
$ha = substr($hash, 0, 2);
|
$ha = substr($hash, 0, 2);
|
||||||
|
@ -816,6 +878,10 @@ function move_upload_to_archive($event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a full size pair of dimentions, return a pair scaled down to fit
|
||||||
|
* into the configured thumbnail square, with ratio intact
|
||||||
|
*/
|
||||||
function get_thumbnail_size($orig_width, $orig_height) {
|
function get_thumbnail_size($orig_width, $orig_height) {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* @package SCore
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data structure for holding all the bits of data that make up a page.
|
||||||
|
*
|
||||||
|
* The various extensions all add whatever they want to this structure,
|
||||||
|
* then layout.class.php turns it into HTML
|
||||||
|
*/
|
||||||
class GenericPage {
|
class GenericPage {
|
||||||
var $mode = "page";
|
var $mode = "page";
|
||||||
var $type = "text/html";
|
var $type = "text/html";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set what this page should do; page, data, or redirect.
|
||||||
|
*/
|
||||||
public function set_mode($mode) {
|
public function set_mode($mode) {
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the page's MIME type
|
||||||
|
*/
|
||||||
public function set_type($type) {
|
public function set_type($type) {
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
}
|
}
|
||||||
|
@ -18,10 +34,16 @@ class GenericPage {
|
||||||
var $data = "";
|
var $data = "";
|
||||||
var $filename = null;
|
var $filename = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "data" mode, this will set the data to be sent
|
||||||
|
*/
|
||||||
public function set_data($data) {
|
public function set_data($data) {
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "data" mode, this will set the recommended download filename
|
||||||
|
*/
|
||||||
public function set_filename($filename) {
|
public function set_filename($filename) {
|
||||||
$this->filename = $filename;
|
$this->filename = $filename;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +54,9 @@ class GenericPage {
|
||||||
// redirect
|
// redirect
|
||||||
var $redirect = "";
|
var $redirect = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "redirect" mode, this will set where to redirect to
|
||||||
|
*/
|
||||||
public function set_redirect($redirect) {
|
public function set_redirect($redirect) {
|
||||||
$this->redirect = $redirect;
|
$this->redirect = $redirect;
|
||||||
}
|
}
|
||||||
|
@ -47,29 +72,47 @@ class GenericPage {
|
||||||
var $headers = array();
|
var $headers = array();
|
||||||
var $blocks = array();
|
var $blocks = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "page" mode, set the window title
|
||||||
|
*/
|
||||||
public function set_title($title) {
|
public function set_title($title) {
|
||||||
$this->title = $title;
|
$this->title = $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "page" mode, set the main heading
|
||||||
|
*/
|
||||||
public function set_heading($heading) {
|
public function set_heading($heading) {
|
||||||
$this->heading = $heading;
|
$this->heading = $heading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "page" mode, set the sub heading
|
||||||
|
*/
|
||||||
public function set_subheading($subheading) {
|
public function set_subheading($subheading) {
|
||||||
$this->subheading = $subheading;
|
$this->subheading = $subheading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "page" mode, add a line to the HTML head section
|
||||||
|
*/
|
||||||
public function add_header($line, $position=50) {
|
public function add_header($line, $position=50) {
|
||||||
while(isset($this->headers[$position])) $position++;
|
while(isset($this->headers[$position])) $position++;
|
||||||
$this->headers[$position] = $line;
|
$this->headers[$position] = $line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the page is in "page" mode, add a block of data
|
||||||
|
*/
|
||||||
public function add_block($block) {
|
public function add_block($block) {
|
||||||
$this->blocks[] = $block;
|
$this->blocks[] = $block;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==============================================
|
// ==============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* display the page according to the mode and data given
|
||||||
|
*/
|
||||||
public function display() {
|
public function display() {
|
||||||
global $page;
|
global $page;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* @package SCore
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function _new_user($row) {
|
function _new_user($row) {
|
||||||
return new User($row);
|
return new User($row);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* An object representing a row in the "users" table.
|
* An object representing a row in the "users" table.
|
||||||
|
*
|
||||||
|
* The currently logged in user will always be accessable via the global variable $user
|
||||||
*/
|
*/
|
||||||
class User {
|
class User {
|
||||||
var $config;
|
var $config;
|
||||||
|
@ -25,6 +34,10 @@ class User {
|
||||||
* $user = User::by_name("bob"); *
|
* $user = User::by_name("bob"); *
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One will very rarely construct a user directly, more common
|
||||||
|
* would be to use User::by_id, User::by_session, etc
|
||||||
|
*/
|
||||||
public function User($row) {
|
public function User($row) {
|
||||||
$this->id = int_escape($row['id']);
|
$this->id = int_escape($row['id']);
|
||||||
$this->name = $row['name'];
|
$this->name = $row['name'];
|
||||||
|
@ -78,12 +91,21 @@ class User {
|
||||||
* useful user object functions start here
|
* useful user object functions start here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if this user is anonymous (not logged in)
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
public function is_anonymous() {
|
public function is_anonymous() {
|
||||||
global $config;
|
global $config;
|
||||||
return ($this->id == $config->get_int('anon_id'));
|
return ($this->id == $config->get_int('anon_id'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if this user is an administrator
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
public function is_admin() {
|
public function is_admin() {
|
||||||
return $this->admin;
|
return $this->admin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,36 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* @package SCore
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
||||||
* Input / Output Sanitising *
|
* Input / Output Sanitising *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make some data safe for printing into HTML
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
function html_escape($input) {
|
function html_escape($input) {
|
||||||
return htmlentities($input, ENT_QUOTES, "UTF-8");
|
return htmlentities($input, ENT_QUOTES, "UTF-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure some data is safe to be used in integer context
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
function int_escape($input) {
|
function int_escape($input) {
|
||||||
return (int)$input;
|
return (int)$input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure some data is safe to be used in URL context
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
function url_escape($input) {
|
function url_escape($input) {
|
||||||
$input = str_replace('^', '^^', $input);
|
$input = str_replace('^', '^^', $input);
|
||||||
$input = str_replace('/', '^s', $input);
|
$input = str_replace('/', '^s', $input);
|
||||||
|
@ -19,11 +38,21 @@ function url_escape($input) {
|
||||||
return $input;
|
return $input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure some data is safe to be used in SQL context
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
function sql_escape($input) {
|
function sql_escape($input) {
|
||||||
global $database;
|
global $database;
|
||||||
return $database->db->Quote($input);
|
return $database->db->Quote($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn a human readable filesize into an integer, eg 1KB -> 1024
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
function parse_shorthand_int($limit) {
|
function parse_shorthand_int($limit) {
|
||||||
if(is_numeric($limit)) {
|
if(is_numeric($limit)) {
|
||||||
return (int)$limit;
|
return (int)$limit;
|
||||||
|
@ -45,6 +74,11 @@ function parse_shorthand_int($limit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn an integer into a human readable filesize, eg 1024 -> 1KB
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
function to_shorthand_int($int) {
|
function to_shorthand_int($int) {
|
||||||
if($int >= pow(1024, 3)) {
|
if($int >= pow(1024, 3)) {
|
||||||
return sprintf("%.1fGB", $int / pow(1024, 3));
|
return sprintf("%.1fGB", $int / pow(1024, 3));
|
||||||
|
@ -65,6 +99,12 @@ function to_shorthand_int($int) {
|
||||||
* HTML Generation *
|
* HTML Generation *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figure out the correct way to link to a page, taking into account
|
||||||
|
* things like the nice URLs setting
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
function make_link($page=null, $query=null) {
|
function make_link($page=null, $query=null) {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
|
@ -103,6 +143,9 @@ function theme_file($filepath) {
|
||||||
* Misc *
|
* Misc *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function version_check() {
|
function version_check() {
|
||||||
if(version_compare(PHP_VERSION, "5.0.0") == -1) {
|
if(version_compare(PHP_VERSION, "5.0.0") == -1) {
|
||||||
print <<<EOD
|
print <<<EOD
|
||||||
|
@ -114,6 +157,9 @@ EOD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function check_cli() {
|
function check_cli() {
|
||||||
if(isset($_SERVER['REMOTE_ADDR'])) {
|
if(isset($_SERVER['REMOTE_ADDR'])) {
|
||||||
print "This script is to be run from the command line only.";
|
print "This script is to be run from the command line only.";
|
||||||
|
@ -122,7 +168,11 @@ function check_cli() {
|
||||||
$_SERVER['REMOTE_ADDR'] = "127.0.0.1";
|
$_SERVER['REMOTE_ADDR'] = "127.0.0.1";
|
||||||
}
|
}
|
||||||
|
|
||||||
# $db is the connection object
|
/**
|
||||||
|
* $db is the connection object
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function _count_execs($db, $sql, $inputarray) {
|
function _count_execs($db, $sql, $inputarray) {
|
||||||
global $_execs;
|
global $_execs;
|
||||||
if(DEBUG) {
|
if(DEBUG) {
|
||||||
|
@ -143,6 +193,9 @@ function _count_execs($db, $sql, $inputarray) {
|
||||||
$null = null; return $null;
|
$null = null; return $null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the theme object for a given extension
|
||||||
|
*/
|
||||||
function get_theme_object(Extension $class, $fatal=true) {
|
function get_theme_object(Extension $class, $fatal=true) {
|
||||||
$base = get_class($class);
|
$base = get_class($class);
|
||||||
if(class_exists("Custom{$base}Theme")) {
|
if(class_exists("Custom{$base}Theme")) {
|
||||||
|
@ -157,6 +210,11 @@ function get_theme_object(Extension $class, $fatal=true) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two Block objects, used to sort them before being displayed
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
function blockcmp($a, $b) {
|
function blockcmp($a, $b) {
|
||||||
if($a->position == $b->position) {
|
if($a->position == $b->position) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -166,6 +224,11 @@ function blockcmp($a, $b) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figure out PHP's internal memory limit
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
function get_memory_limit() {
|
function get_memory_limit() {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
|
@ -190,6 +253,12 @@ function get_memory_limit() {
|
||||||
return $memory;
|
return $memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently active IP, masked to make it not change when the last
|
||||||
|
* octet or two change, for use in session cookies and such
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
function get_session_ip($config) {
|
function get_session_ip($config) {
|
||||||
$mask = $config->get_string("session_hash_mask", "255.255.0.0");
|
$mask = $config->get_string("session_hash_mask", "255.255.0.0");
|
||||||
$addr = $_SERVER['REMOTE_ADDR'];
|
$addr = $_SERVER['REMOTE_ADDR'];
|
||||||
|
@ -197,8 +266,12 @@ function get_session_ip($config) {
|
||||||
return $addr;
|
return $addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* Figure out the path to the shimmie install root.
|
||||||
|
*
|
||||||
* PHP really, really sucks.
|
* PHP really, really sucks.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
*/
|
*/
|
||||||
function get_base_href() {
|
function get_base_href() {
|
||||||
$possible_vars = array('SCRIPT_NAME', 'PHP_SELF', 'PATH_INFO', 'ORIG_PATH_INFO');
|
$possible_vars = array('SCRIPT_NAME', 'PHP_SELF', 'PATH_INFO', 'ORIG_PATH_INFO');
|
||||||
|
@ -215,6 +288,12 @@ function get_base_href() {
|
||||||
return $dir;
|
return $dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shorthand way to send a TextFormattingEvent and get the
|
||||||
|
* results
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
function format_text($string) {
|
function format_text($string) {
|
||||||
$tfe = new TextFormattingEvent($string);
|
$tfe = new TextFormattingEvent($string);
|
||||||
send_event($tfe);
|
send_event($tfe);
|
||||||
|
@ -246,6 +325,11 @@ function log_info($section, $message) {
|
||||||
* Things which should be in the core API *
|
* Things which should be in the core API *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an item from an array
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
function array_remove($array, $to_remove) {
|
function array_remove($array, $to_remove) {
|
||||||
$array = array_unique($array);
|
$array = array_unique($array);
|
||||||
$a2 = array();
|
$a2 = array();
|
||||||
|
@ -257,13 +341,22 @@ function array_remove($array, $to_remove) {
|
||||||
return $a2;
|
return $a2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an item to an array
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
function array_add($array, $element) {
|
function array_add($array, $element) {
|
||||||
$array[] = $element;
|
$array[] = $element;
|
||||||
$array = array_unique($array);
|
$array = array_unique($array);
|
||||||
return $array;
|
return $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
// case insensetive uniqueness
|
/**
|
||||||
|
* Return the unique elements of an array, case insensitively
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
function array_iunique($array) {
|
function array_iunique($array) {
|
||||||
$ok = array();
|
$ok = array();
|
||||||
foreach($array as $element) {
|
foreach($array as $element) {
|
||||||
|
@ -280,7 +373,13 @@ function array_iunique($array) {
|
||||||
return $ok;
|
return $ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// from http://uk.php.net/network
|
/**
|
||||||
|
* Figure out if an IP is in a specified range
|
||||||
|
*
|
||||||
|
* from http://uk.php.net/network
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
function ip_in_range($IP, $CIDR) {
|
function ip_in_range($IP, $CIDR) {
|
||||||
list ($net, $mask) = split ("/", $CIDR);
|
list ($net, $mask) = split ("/", $CIDR);
|
||||||
|
|
||||||
|
@ -294,8 +393,12 @@ function ip_in_range($IP, $CIDR) {
|
||||||
return ($ip_ip_net == $ip_net);
|
return ($ip_ip_net == $ip_net);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from a patch by Christian Walde; only intended for use in the
|
/**
|
||||||
// "extension manager" extension, but it seems to fit better here
|
* Delete an entire file heirachy
|
||||||
|
*
|
||||||
|
* from a patch by Christian Walde; only intended for use in the
|
||||||
|
* "extension manager" extension, but it seems to fit better here
|
||||||
|
*/
|
||||||
function deltree($f) {
|
function deltree($f) {
|
||||||
if (is_link($f)) {
|
if (is_link($f)) {
|
||||||
unlink($f);
|
unlink($f);
|
||||||
|
@ -312,7 +415,11 @@ function deltree($f) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from a comment on http://uk.php.net/copy
|
/**
|
||||||
|
* Copy an entire file heirachy
|
||||||
|
*
|
||||||
|
* from a comment on http://uk.php.net/copy
|
||||||
|
*/
|
||||||
function full_copy($source, $target) {
|
function full_copy($source, $target) {
|
||||||
if(is_dir($source)) {
|
if(is_dir($source)) {
|
||||||
@mkdir($target);
|
@mkdir($target);
|
||||||
|
@ -338,10 +445,16 @@ function full_copy($source, $target) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function stripslashes_r($arr) {
|
function stripslashes_r($arr) {
|
||||||
return is_array($arr) ? array_map('stripslashes_r', $arr) : stripslashes($arr);
|
return is_array($arr) ? array_map('stripslashes_r', $arr) : stripslashes($arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function sanitise_environment() {
|
function sanitise_environment() {
|
||||||
if(DEBUG) {
|
if(DEBUG) {
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
@ -358,6 +471,9 @@ function sanitise_environment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function weighted_random($weights) {
|
function weighted_random($weights) {
|
||||||
$total = 0;
|
$total = 0;
|
||||||
foreach($weights as $k => $w) {
|
foreach($weights as $k => $w) {
|
||||||
|
@ -377,8 +493,14 @@ function weighted_random($weights) {
|
||||||
* Event API *
|
* Event API *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
$_event_listeners = array();
|
$_event_listeners = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an Extension
|
||||||
|
*/
|
||||||
function add_event_listener(Extension $extension, $pos=50) {
|
function add_event_listener(Extension $extension, $pos=50) {
|
||||||
global $_event_listeners;
|
global $_event_listeners;
|
||||||
while(isset($_event_listeners[$pos])) {
|
while(isset($_event_listeners[$pos])) {
|
||||||
|
@ -387,7 +509,14 @@ function add_event_listener(Extension $extension, $pos=50) {
|
||||||
$_event_listeners[$pos] = $extension;
|
$_event_listeners[$pos] = $extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
$_event_count = 0;
|
$_event_count = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an event to all registered Extensions
|
||||||
|
*/
|
||||||
function send_event(Event $event) {
|
function send_event(Event $event) {
|
||||||
global $_event_listeners, $_event_count;
|
global $_event_listeners, $_event_count;
|
||||||
$my_event_listeners = $_event_listeners; // http://bugs.php.net/bug.php?id=35106
|
$my_event_listeners = $_event_listeners; // http://bugs.php.net/bug.php?id=35106
|
||||||
|
@ -399,15 +528,90 @@ function send_event(Event $event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
||||||
|
* Debugging functions *
|
||||||
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
function get_debug_info() {
|
||||||
|
global $config, $_event_count;
|
||||||
|
|
||||||
|
if(function_exists('memory_get_usage')) {
|
||||||
|
$i_mem = sprintf("%5.2f", ((memory_get_usage()+512)/1024)/1024);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$i_mem = "???";
|
||||||
|
}
|
||||||
|
if(function_exists('getrusage')) {
|
||||||
|
$ru = getrusage();
|
||||||
|
$i_utime = sprintf("%5.2f", ($ru["ru_utime.tv_sec"]*1e6+$ru["ru_utime.tv_usec"])/1000000);
|
||||||
|
$i_stime = sprintf("%5.2f", ($ru["ru_stime.tv_sec"]*1e6+$ru["ru_stime.tv_usec"])/1000000);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$i_utime = "???";
|
||||||
|
$i_stime = "???";
|
||||||
|
}
|
||||||
|
$i_files = count(get_included_files());
|
||||||
|
global $_execs;
|
||||||
|
global $database;
|
||||||
|
$hits = $database->cache->get_hits();
|
||||||
|
$miss = $database->cache->get_misses();
|
||||||
|
$debug = "<br>Took $i_utime + $i_stime seconds and {$i_mem}MB of RAM";
|
||||||
|
$debug .= "; Used $i_files files and $_execs queries";
|
||||||
|
$debug .= "; Sent $_event_count events";
|
||||||
|
$debug .= "; $hits cache hits and $miss misses";
|
||||||
|
|
||||||
|
return $debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print_obj ($object, $title, $return)
|
||||||
|
function print_obj($object,$title="Object Information", $return=false) {
|
||||||
|
global $user;
|
||||||
|
if(DEBUG && isset($_GET['debug']) && $user->is_admin()) {
|
||||||
|
$pr = print_r($object,true);
|
||||||
|
$count = substr_count($pr,"\n")<=25?substr_count($pr,"\n"):25;
|
||||||
|
$pr = "<textarea rows='".$count."' cols='80'>$pr</textarea>";
|
||||||
|
|
||||||
|
if($return) {
|
||||||
|
return $pr;
|
||||||
|
} else {
|
||||||
|
global $page;
|
||||||
|
$page->add_block(new Block($title,$pr,"main",1000));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// preset tests.
|
||||||
|
|
||||||
|
// Prints the contents of $event->args, even though they are clearly visible in
|
||||||
|
// the URL bar.
|
||||||
|
function print_url_args() {
|
||||||
|
global $event;
|
||||||
|
print_obj($event->args,"URL Arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints all the POST data.
|
||||||
|
function print_POST() {
|
||||||
|
print_obj($_POST,"\$_POST");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints GET, though this is also visible in the url ( url?var&var&var)
|
||||||
|
function print_GET() {
|
||||||
|
print_obj($_GET,"\$_GET");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
||||||
* Request initialisation stuff *
|
* Request initialisation stuff *
|
||||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Turn ^^ into ^ and ^s into /
|
* Turn ^^ into ^ and ^s into /
|
||||||
*
|
*
|
||||||
* Necessary because various servers and various clients
|
* Necessary because various servers and various clients
|
||||||
* think that / is special...
|
* think that / is special...
|
||||||
|
*
|
||||||
|
* @ignore
|
||||||
*/
|
*/
|
||||||
function _decaret($str) {
|
function _decaret($str) {
|
||||||
$out = "";
|
$out = "";
|
||||||
|
@ -424,6 +628,9 @@ function _decaret($str) {
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function _get_query_parts() {
|
function _get_query_parts() {
|
||||||
if(isset($_GET["q"])) {
|
if(isset($_GET["q"])) {
|
||||||
$path = $_GET["q"];
|
$path = $_GET["q"];
|
||||||
|
@ -453,6 +660,9 @@ function _get_query_parts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function _get_page_request() {
|
function _get_page_request() {
|
||||||
global $config;
|
global $config;
|
||||||
$args = _get_query_parts();
|
$args = _get_query_parts();
|
||||||
|
@ -464,6 +674,9 @@ function _get_page_request() {
|
||||||
return new PageRequestEvent($args);
|
return new PageRequestEvent($args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
function _get_user() {
|
function _get_user() {
|
||||||
global $config, $database;
|
global $config, $database;
|
||||||
$user = null;
|
$user = null;
|
||||||
|
|
Reference in a new issue