diff --git a/core/block.class.php b/core/block.class.php index f672df9f..7e39b6ec 100644 --- a/core/block.class.php +++ b/core/block.class.php @@ -15,7 +15,7 @@ class Block { var $section; var $position; - public function Block($header, $body, $section="main", $position=50) { + public function __construct($header, $body, $section="main", $position=50) { $this->header = $header; $this->body = $body; $this->section = $section; @@ -29,11 +29,8 @@ class Block { * because "new NavBlock()" is easier than "new Block('Navigation', ..." */ class NavBlock extends Block { - public function NavBlock() { - $this->header = "Navigation"; - $this->body = "Index"; - $this->section = "left"; - $this->position = 0; + public function __construct() { + parent::__construct("Navigation", "Index", "left", 0); } } ?> diff --git a/core/database.class.php b/core/database.class.php index e2021974..deedf6d7 100644 --- a/core/database.class.php +++ b/core/database.class.php @@ -191,6 +191,22 @@ class Database { return $result; } + public function get_row($query, $args=array()) { + $result = $this->db->GetRow($query, $args); + if($result === False) { + print "SQL Error: " . $this->db->ErrorMsg(); + print "
Query: $query"; + print "
Args: "; print_r($args); + exit; + } + if(count($result) == 0) { + return null; + } + else { + return $result; + } + } + public function upgrade_schema($filename) { $this->install_schema($filename); } diff --git a/core/event.class.php b/core/event.class.php index 870091e5..9cb021d2 100644 --- a/core/event.class.php +++ b/core/event.class.php @@ -3,12 +3,11 @@ * Event: * generic parent class */ -class Event { - var $vetoed = false, $veto_reason = null; +abstract class Event { + var $context; - public function veto($reason="") { - $this->vetoed = true; - $this->veto_reason = $reason; + public function __construct(RequestContext $context) { + $this->context = $context; } } @@ -114,13 +113,7 @@ class ImageDeletionEvent extends Event { * InitExtEvent: * A wake-up call for extensions */ -class InitExtEvent extends Event { - var $context; - - public function InitExtEvent($context) { - $this->context = $context; - } -} +class InitExtEvent extends Event {} /* @@ -148,6 +141,23 @@ class PageRequestEvent extends Event { $this->user = $context->user; } + public function page_matches($name) { + $parts = explode("/", $name); + + if(count($parts) > count($this->args)) { + return false; + } + + for($i=0; $iargs[$i]) { + return false; + } + } + + return true; + } + + public function get_arg($n) { return isset($this->args[$n]) ? $this->args[$n] : null; } diff --git a/core/exceptions.class.php b/core/exceptions.class.php new file mode 100644 index 00000000..aeb3bd53 --- /dev/null +++ b/core/exceptions.class.php @@ -0,0 +1,4 @@ + diff --git a/core/extension.class.php b/core/extension.class.php index 1ee2a79f..f6d059fa 100644 --- a/core/extension.class.php +++ b/core/extension.class.php @@ -2,7 +2,23 @@ /* * A generic extension class, for subclassing */ -class Extension { - public function receive_event($event) {} +interface Extension { + public function receive_event(Event $event); +} + + +/* + * Several extensions have this in common, make a common API + */ +abstract class FormatterExtension implements Extension { + public function receive_event(Event $event) { + if($event instanceof TextFormattingEvent) { + $event->formatted = $this->format($event->formatted); + $event->stripped = $this->strip($event->stripped); + } + } + + abstract public function format($text); + abstract public function strip($text); } ?> diff --git a/core/user.class.php b/core/user.class.php index 08519f0a..698c400b 100644 --- a/core/user.class.php +++ b/core/user.class.php @@ -3,25 +3,73 @@ * An object representing a row in the "users" table. */ class User { + var $config; + var $database; + var $id; var $name; var $email; var $join_date; var $days_old; var $admin; - - public function User($row) { + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Initialisation * + * * + * User objects shouldn't be created directly, they should be * + * fetched from the database like so: * + * * + * $user = User::by_name($config, $database, "bob"); * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + public function User(Config $config, Database $database, $row) { + $this->config = $config; + $this->database = $database; + $this->id = int_escape($row['id']); $this->name = $row['name']; $this->email = $row['email']; $this->join_date = $row['joindate']; - $this->days_old = $row['days_old']; + $this->days_old = 0; // $row['days_old']; $this->admin = ($row['admin'] == 'Y'); } + public static function by_session(Config $config, Database $database, $name, $session) { + $row = $database->get_row( + "SELECT * FROM user WHERE name = ? AND md5(concat(pass, ?)) = ?", + array($name, get_session_ip($config), $session) + ); + return is_null($row) ? null : new User($config, $database, $row); + } + + public static function by_id(Config $config, Database $database, $id) { + assert(is_numeric($id)); + $row = $database->get_row("SELECT * FROM user WHERE id = ?", array($id)); + return is_null($row) ? null : new User($config, $database, $row); + } + + public static function by_name(Config $config, Database $database, $name) { + assert(is_string($name)); + $row = $database->get_row("SELECT * FROM user WHERE name = ?", array($name)); + return is_null($row) ? null : new User($config, $database, $row); + } + + public static function by_name_and_hash(Config $config, Database $database, $name, $hash) { + assert(is_string($name)); + assert(is_string($hash)); + assert(strlen($hash) == 32); + $row = $database->get_row("SELECT * FROM user WHERE name = ? AND pass = ?", array($name, $hash)); + return is_null($row) ? null : new User($config, $database, $row); + } + + + /* + * useful user object functions start here + */ + + public function is_anonymous() { - global $config; - return ($this->id == $config->get_int('anon_id')); + return ($this->id == $this->config->get_int('anon_id')); } public function is_admin() { @@ -29,17 +77,14 @@ class User { } public function set_admin($admin) { - global $database; - + assert(is_bool($admin)); $yn = $admin ? 'Y' : 'N'; - $database->Execute("UPDATE users SET admin=? WHERE id=?", array($yn, $this->id)); + $this->database->Execute("UPDATE users SET admin=? WHERE id=?", array($yn, $this->id)); } public function set_password($password) { - global $database; - $hash = md5(strtolower($this->name) . $password); - $database->Execute("UPDATE users SET pass=? WHERE id=?", array($hash, $this->id)); + $this->database->Execute("UPDATE users SET pass=? WHERE id=?", array($hash, $this->id)); } public function get_days_old() { diff --git a/core/util.inc.php b/core/util.inc.php index 02e6b31d..0645c68d 100644 --- a/core/util.inc.php +++ b/core/util.inc.php @@ -501,7 +501,6 @@ function send_event($event) { ksort($my_event_listeners); foreach($my_event_listeners as $listener) { $listener->receive_event($event); - if($event->vetoed) break; } $_event_count++; } @@ -526,31 +525,6 @@ function _get_query_parts() { $path = substr($path, 1); } - /* - * Split post/list/fate//stay_night/1 - * into post list fate/stay_night 1 - */ - /* - $parts = array(); - $n = 0; - $lastsplit = 0; - while($n<=strlen($path)) { - if( - $n == strlen($path) || - ( - $path[$n] == '/' && - ($n < strlen($path) && $path[$n+1] != '/') - && ($n > 0 && $path[$n-1] != '/') - ) - ) { - $part = substr($path, $lastsplit, $n-$lastsplit); - $part = str_replace('//', '/', $part); - $parts[] = $part; - $lastsplit = $n+1; - } - $n++; - } - */ $path = str_replace('/', '%%', $path); $path = str_replace('%%%%', '/', $path); $parts = split('%%', $path); @@ -579,20 +553,17 @@ function _get_page_request($context) { return new PageRequestEvent($context, $page_name, $args); } -function _get_user() { - global $database; - global $config; - +function _get_user($config, $database) { $user = null; if(isset($_COOKIE["shm_user"]) && isset($_COOKIE["shm_session"])) { - $tmp_user = $database->get_user_session($_COOKIE["shm_user"], $_COOKIE["shm_session"]); + $tmp_user = User::by_session($config, $database, $_COOKIE["shm_user"], $_COOKIE["shm_session"]); if(!is_null($tmp_user)) { $user = $tmp_user; } } if(is_null($user)) { - $user = $database->get_user_by_id($config->get_int("anon_id", 0)); + $user = User::by_id($config, $database, $config->get_int("anon_id", 0)); } assert(!is_null($user)); return $user; diff --git a/index.php b/index.php index 3de6db2d..17cf4e8b 100644 --- a/index.php +++ b/index.php @@ -48,7 +48,7 @@ if($custom_themelets) { // start the page generation waterfall $page = new Page(); -$user = _get_user(); +$user = _get_user($config, $database); $context = new RequestContext(); $context->page = $page; $context->user = $user;