Merge branch 'develop'
This commit is contained in:
122
source/lib/SihnonFramework/Auth.class.php
Normal file
122
source/lib/SihnonFramework/Auth.class.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth {
|
||||
|
||||
protected $config;
|
||||
protected $session;
|
||||
|
||||
protected $backend;
|
||||
protected $user;
|
||||
protected $authenticated;
|
||||
|
||||
public function __construct(Sihnon_Config $config, Sihnon_Session $session) {
|
||||
$this->config = $config;
|
||||
$this->session = $session;
|
||||
$this->authenticated = false;
|
||||
|
||||
$this->init($this->config->get('auth'));
|
||||
}
|
||||
|
||||
protected function init($backend) {
|
||||
$this->backend = Sihnon_Auth_PluginFactory::create($this->config, $backend);
|
||||
$this->restoreSession();
|
||||
}
|
||||
|
||||
public function isAuthenticated() {
|
||||
return $this->authenticated;
|
||||
}
|
||||
|
||||
public function authenticatedUser() {
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function saveSession() {
|
||||
if ($this->user) {
|
||||
$this->session->set('user.id', $this->user->username());
|
||||
}
|
||||
}
|
||||
|
||||
public function clearSession() {
|
||||
$this->session->delete('user.id');
|
||||
}
|
||||
|
||||
public function restoreSession() {
|
||||
if ($this->session->exists('user.id')) {
|
||||
$this->user = $this->backend->authenticateSession($this->session->get('user.id'));
|
||||
$this->authenticated = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function register($username, $password) {
|
||||
$this->user = $this->addUser($username, $password);
|
||||
$this->authenticated = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* IPlugin methods
|
||||
*/
|
||||
|
||||
public function listUsers() {
|
||||
return $this->backend->listUsers();
|
||||
}
|
||||
|
||||
public function authenticate($username, $password) {
|
||||
$this->user = $this->backend->authenticate($username, $password);
|
||||
$this->authenticated = true;
|
||||
|
||||
$this->session->securityLeveLChanged();
|
||||
$this->saveSession();
|
||||
}
|
||||
|
||||
public function deauthenticate() {
|
||||
$this->user = null;
|
||||
$this->authenticated = false;
|
||||
|
||||
$this->clearSession();
|
||||
}
|
||||
|
||||
/*
|
||||
* IUpdateable methods
|
||||
*/
|
||||
|
||||
public function addUser($username, $password) {
|
||||
return $this->backend->addUser($username, $password);
|
||||
}
|
||||
|
||||
public function removeUser() {
|
||||
$this->backend->removeUser($this->user);
|
||||
$this->user = null;
|
||||
$this->authenticated = false;
|
||||
}
|
||||
|
||||
public function changePassword($new_password) {
|
||||
$this->backend->changePassword($this->user, $new_password);
|
||||
}
|
||||
|
||||
/*
|
||||
* IPermissionable methods
|
||||
*/
|
||||
|
||||
public function isAdministrator() {
|
||||
if ( ! $this->user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->backend->isAdministrator($this->user);
|
||||
}
|
||||
|
||||
/*
|
||||
* IFinelyPermissionable methods
|
||||
*/
|
||||
|
||||
public function hasPermission($permission) {
|
||||
if ( ! $this->user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->backend->hasPermission($this->user, $permission);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_Auth_IFinelyPermissionable extends Sihnon_Auth_IPermissionable {
|
||||
|
||||
public function hasPermission(Sihnon_Auth_IUser $user, $permission);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_Auth_IPermissionable {
|
||||
|
||||
public function isAdministrator(Sihnon_Auth_IUser $user);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
23
source/lib/SihnonFramework/Auth/IPlugin.class.php
Normal file
23
source/lib/SihnonFramework/Auth/IPlugin.class.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_Auth_IPlugin extends Sihnon_IPlugin {
|
||||
|
||||
/**
|
||||
* Creates a new instance of the Auth Plugin
|
||||
*
|
||||
* @param SihnonFramework_Config $config Config option to retrieve plugin configuration
|
||||
* @return SihnonFramework_Auth_IPlugin
|
||||
*/
|
||||
public static function create(SihnonFramework_Config $config);
|
||||
|
||||
public function userExists($username);
|
||||
|
||||
public function listUsers();
|
||||
|
||||
public function authenticate($username, $password);
|
||||
|
||||
public function authenticateSession($username);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
13
source/lib/SihnonFramework/Auth/IUpdateable.class.php
Normal file
13
source/lib/SihnonFramework/Auth/IUpdateable.class.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_Auth_IUpdateable {
|
||||
|
||||
public function addUser($username, $password);
|
||||
|
||||
public function removeUser(Sihnon_Auth_IUser $user);
|
||||
|
||||
public function changePassword(Sihnon_Auth_IUser $user, $new_password);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
11
source/lib/SihnonFramework/Auth/IUser.class.php
Normal file
11
source/lib/SihnonFramework/Auth/IUser.class.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
interface SihnonFramework_Auth_IUser {
|
||||
|
||||
public function username();
|
||||
|
||||
public function checkPassword($password);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
87
source/lib/SihnonFramework/Auth/Plugin/Database.class.php
Normal file
87
source/lib/SihnonFramework/Auth/Plugin/Database.class.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_Database
|
||||
extends Sihnon_PluginBase
|
||||
implements Sihnon_Auth_IPlugin,
|
||||
Sihnon_Auth_IUpdateable,
|
||||
Sihnon_Auth_IFinelyPermissionable {
|
||||
|
||||
protected $config;
|
||||
protected $database;
|
||||
|
||||
protected function __construct($config) {
|
||||
$this->config = $config;
|
||||
$this->database = SihnonFramework_Main::instance()->database();
|
||||
}
|
||||
|
||||
/*
|
||||
* IPlugin methods
|
||||
*/
|
||||
|
||||
public static function create(SihnonFramework_Config $config) {
|
||||
return new self($config);
|
||||
}
|
||||
|
||||
public function userExists($username) {
|
||||
return Sihnon_Auth_Plugin_Database_User::exists($username);
|
||||
}
|
||||
|
||||
public function listUsers() {
|
||||
return Sihnon_Auth_Plugin_Database_User::all();
|
||||
}
|
||||
|
||||
public function authenticate($username, $password) {
|
||||
try {
|
||||
$user = Sihnon_Auth_Plugin_Database_User::from('username', $username);
|
||||
} catch (Sihnon_Exception_ResultCountMismatch $e) {
|
||||
throw new Sihnon_Exception_UnknownUser();
|
||||
}
|
||||
|
||||
if ( ! $user->checkPassword($password)) {
|
||||
throw new Sihnon_Exception_IncorrectPassword();
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function authenticateSession($username) {
|
||||
return Sihnon_Auth_Plugin_Database_User::from('username', $username);
|
||||
}
|
||||
|
||||
/*
|
||||
* IUpdateable methods
|
||||
*/
|
||||
|
||||
public function addUser($username, $password) {
|
||||
return Sihnon_Auth_Plugin_Database_User::add($username, $password);
|
||||
}
|
||||
|
||||
public function removeUser(Sihnon_Auth_IUser $user) {
|
||||
$user->delete();
|
||||
}
|
||||
|
||||
public function changePassword(Sihnon_Auth_IUser $user, $new_password) {
|
||||
$user->changePassword($new_password);
|
||||
}
|
||||
|
||||
/*
|
||||
* IPermissionable methods
|
||||
*/
|
||||
|
||||
public function isAdministrator(Sihnon_Auth_IUser $user) {
|
||||
// As this class supports fine-grained permissions, map the isAdministrator function to the Superadmin privilege
|
||||
// to fallback for badly written applications
|
||||
return $user->hasPermission(Sihnon_Auth_Plugin_Database_Permission::PERM_Administrator);
|
||||
}
|
||||
|
||||
/*
|
||||
* IFinelyPermissionable methods
|
||||
*/
|
||||
|
||||
public function hasPermission(Sihnon_Auth_IUser $user, $permission) {
|
||||
return $user->hasPermission($permission);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_Database_Group extends Sihnon_DatabaseObject {
|
||||
|
||||
protected static $table = 'group';
|
||||
|
||||
protected $_db_id;
|
||||
protected $_db_name;
|
||||
protected $_db_description;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_Database_GroupPermission extends Sihnon_DatabaseObject {
|
||||
|
||||
protected static $table = 'grouppermission';
|
||||
|
||||
protected $_db_id;
|
||||
protected $_db_group;
|
||||
protected $_db_permission;
|
||||
protected $_db_added;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_Database_Permission extends Sihnon_DatabaseObject {
|
||||
|
||||
/*
|
||||
* Built-in permissions
|
||||
*/
|
||||
|
||||
// The Administrator permission always exists, and is always offers the most functionality
|
||||
// This maps to the isAdministrator method for coarse-grained permissions.
|
||||
const PERM_Administrator = 1;
|
||||
|
||||
protected static $table = 'permission';
|
||||
|
||||
protected $_db_id;
|
||||
protected $_db_name;
|
||||
protected $_db_description;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_Database_User extends Sihnon_DatabaseObject implements Sihnon_Auth_IUser {
|
||||
|
||||
protected static $table = 'user';
|
||||
|
||||
protected $_db_id;
|
||||
protected $_db_username;
|
||||
protected $_db_password;
|
||||
protected $_db_fullname;
|
||||
protected $_db_email;
|
||||
protected $_db_last_login;
|
||||
protected $_db_last_password_change;
|
||||
|
||||
protected $groups = null;
|
||||
protected $permissions = null;
|
||||
|
||||
public static function exists($username) {
|
||||
return parent::exists('username', $username);
|
||||
}
|
||||
|
||||
public static function add($username, $password) {
|
||||
$user = new self();
|
||||
$user->username = $username;
|
||||
$user->password = sha1($password);
|
||||
$user->last_password_change = time();
|
||||
$user->create();
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function username() {
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
public function checkPassword($password) {
|
||||
return ($this->password == sha1($password));
|
||||
}
|
||||
|
||||
public function changePassword($new_password) {
|
||||
$this->password = sha1($new_password);
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function groups($ignore_cache = false) {
|
||||
if ($this->groups === null || $ignore_cache) {
|
||||
$this->groups = Sihnon_Auth_Plugin_Database_Group::allFor('user', $this->id, 'groups_by_user');
|
||||
}
|
||||
|
||||
return $this->groups;
|
||||
}
|
||||
|
||||
public function permissions($ignore_cache = false) {
|
||||
if ($this->permissions === null || $ignore_cache) {
|
||||
$this->permissions = Sihnon_Auth_Plugin_Database_Permission::allFor('user', $this->id, 'permissions_by_user');
|
||||
}
|
||||
|
||||
return $this->permissions;
|
||||
}
|
||||
|
||||
public function hasPermission($permission) {
|
||||
$permissions = $this->permissions();
|
||||
foreach ($permissions as $has_permission) {
|
||||
if ($permission == $has_permission->id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_Database_UserGroup extends Sihnon_DatabaseObject {
|
||||
|
||||
protected static $table = 'uergroup';
|
||||
|
||||
protected $_db_id;
|
||||
protected $_db_user;
|
||||
protected $_db_group;
|
||||
protected $_db_added;
|
||||
|
||||
|
||||
}
|
||||
71
source/lib/SihnonFramework/Auth/Plugin/FlatFile.class.php
Normal file
71
source/lib/SihnonFramework/Auth/Plugin/FlatFile.class.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_FlatFile
|
||||
extends Sihnon_PluginBase
|
||||
implements Sihnon_Auth_IPlugin,
|
||||
Sihnon_Auth_IUpdateable,
|
||||
Sihnon_Auth_IPermissionable {
|
||||
|
||||
protected $config;
|
||||
|
||||
protected function __construct($config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/*
|
||||
* IPlugin methods
|
||||
*/
|
||||
|
||||
public static function create(SihnonFramework_Config $config) {
|
||||
return new self($config);
|
||||
}
|
||||
|
||||
public function userExists($username) {
|
||||
return Sihnon_Auth_Plugin_FlatFile_User::exists($username);
|
||||
}
|
||||
|
||||
public function listUsers() {
|
||||
return Sihnon_Auth_Plugin_FlatFile_User::all();
|
||||
}
|
||||
|
||||
public function authenticate($username, $password) {
|
||||
$user = Sihnon_Auth_Plugin_FlatFile_User::load($username);
|
||||
|
||||
if ( ! $user->checkPassword($password)) {
|
||||
throw new Sihnon_Exception_IncorrectPassword();
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function authenticateSession($username) {
|
||||
return Sihnon_Auth_Plugin_FlatFile_User::load($username);
|
||||
}
|
||||
|
||||
/*
|
||||
* IUpdateable methods
|
||||
*/
|
||||
|
||||
public function addUser($username, $password) {
|
||||
return Sihnon_Auth_Plugin_Database_User::add($username, $password);
|
||||
}
|
||||
|
||||
public function removeUser(Sihnon_Auth_IUser $user) {
|
||||
$user->delete();
|
||||
}
|
||||
|
||||
public function changePassword(Sihnon_Auth_IUser $user, $new_password) {
|
||||
$user->changePassword($new_password);
|
||||
}
|
||||
|
||||
/*
|
||||
* IPermissionable methods
|
||||
*/
|
||||
|
||||
public function isAdministrator(Sihnon_Auth_IUser $user) {
|
||||
return $user->isAdministrator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_Plugin_FlatFile_User implements Sihnon_Auth_IUser {
|
||||
|
||||
public static function exists($username) {
|
||||
throw new SihnonFramework_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
public static function load($username) {
|
||||
throw new SihnonFramework_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
public static function add($username, $password) {
|
||||
throw new SihnonFramework_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
public function username() {
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
public function checkPassword($password) {
|
||||
return ($this->password == sha1($password));
|
||||
}
|
||||
|
||||
public function changePassword($new_password) {
|
||||
throw new SihnonFramework_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
public function isAdministrator() {
|
||||
throw new SihnonFramework_Exception_NotImplemented();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
30
source/lib/SihnonFramework/Auth/PluginFactory.class.php
Normal file
30
source/lib/SihnonFramework/Auth/PluginFactory.class.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Auth_PluginFactory extends Sihnon_PluginFactory {
|
||||
|
||||
protected static $plugin_prefix = 'Sihnon_Auth_Plugin_';
|
||||
protected static $plugin_interface = 'SihnonFramework_Auth_IPlugin';
|
||||
protected static $plugin_dir = array(
|
||||
SihnonFramework_Lib => 'SihnonFramework/Auth/Plugin/',
|
||||
Sihnon_Lib => 'Sihnon/Auth/Plugin/',
|
||||
);
|
||||
|
||||
public static function init() {
|
||||
|
||||
}
|
||||
|
||||
public static function create(SihnonFramework_Config $config, $plugin) {
|
||||
self::ensureScanned();
|
||||
|
||||
if (! self::isValidPlugin($plugin)) {
|
||||
throw new Sihnon_Exception_InvalidPluginName($plugin);
|
||||
}
|
||||
|
||||
$classname = self::classname($plugin);
|
||||
|
||||
return call_user_func(array($classname, 'create'), $config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -6,10 +6,10 @@ class SihnonFramework_BackgroundTask {
|
||||
|
||||
}
|
||||
|
||||
public static function run($command) {
|
||||
public static function run($command, $cwd=null, $env=null) {
|
||||
SihnonFramework_LogEntry::debug(SihnonFramework_Main::instance()->log(), "Running background task: {$command} &", 'default');
|
||||
$pipes = array();
|
||||
$pid = proc_open($command . ' &', array(), $pipes);
|
||||
$pid = proc_open($command . ' &', array(), $pipes, $cwd, $env);
|
||||
proc_close($pid);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ class SihnonFramework_Config {
|
||||
*/
|
||||
const TYPE_STRING_LIST = 'array(string)';
|
||||
|
||||
/**
|
||||
* Hash type with string keys and mixed-type values
|
||||
* @var array(string=>mixed)
|
||||
*/
|
||||
const TYPE_HASH = 'hash';
|
||||
|
||||
/**
|
||||
* Backend to be used for this Config object
|
||||
* @var Sihnon_Config_IPlugin
|
||||
@@ -58,9 +64,11 @@ class SihnonFramework_Config {
|
||||
|
||||
protected static function pack($type, $value) {
|
||||
switch ($type) {
|
||||
case static::TYPE_STRING_LIST: {
|
||||
case static::TYPE_STRING_LIST:
|
||||
return join("\n", $value);
|
||||
} break;
|
||||
|
||||
case static::TYPE_HASH:
|
||||
return join("\n", array_map(function($k, $v) { return "{$k}:{$v}"; }, array_keys($value), array_values($value)));
|
||||
|
||||
default: {
|
||||
return $value;
|
||||
@@ -70,9 +78,17 @@ class SihnonFramework_Config {
|
||||
|
||||
protected static function unpack($type, $value) {
|
||||
switch ($type) {
|
||||
case self::TYPE_STRING_LIST:
|
||||
case static::TYPE_STRING_LIST:
|
||||
// foo
|
||||
// bar
|
||||
return array_map('trim', explode("\n", $value));
|
||||
|
||||
case static::TYPE_HASH:
|
||||
// foo:bar
|
||||
// baz:quz
|
||||
preg_match_all("/^([^:]+):(.+)$/m", $value, $pairs);
|
||||
return array_combine($pairs[1], $pairs[2]);
|
||||
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
|
||||
50
source/lib/SihnonFramework/Daemon.class.php
Normal file
50
source/lib/SihnonFramework/Daemon.class.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Daemon {
|
||||
|
||||
protected $config;
|
||||
|
||||
protected $lock_file;
|
||||
protected $lock;
|
||||
protected $locked;
|
||||
|
||||
public function __construct(SihnonFramework_Config $config) {
|
||||
$this->config = $config;
|
||||
$this->lock_file = $config->get('daemon.lock-file');
|
||||
$this->lock = null;
|
||||
$this->locked = false;
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->teardown();
|
||||
}
|
||||
|
||||
protected function init() {
|
||||
$this->lock = fopen($this->lock_file, 'w');
|
||||
$wouldBlock = false;
|
||||
|
||||
$result = flock($this->lock, LOCK_EX|LOCK_NB, $wouldBlock);
|
||||
if ($wouldBlock) {
|
||||
// Another instance is already running
|
||||
throw new SihnonFramework_Exception_AlreadyRunning();
|
||||
} else if ( ! $result) {
|
||||
throw new SihnonFramework_Exception_LockingFailed();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected function teardown() {
|
||||
if ( ! $this->locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
flock($this->lock, LOCK_UN);
|
||||
fclose($this->lock);
|
||||
unlink($this->lock_file);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -68,7 +68,7 @@ class SihnonFramework_Database {
|
||||
}
|
||||
|
||||
private function query($sql, $count = 0) {
|
||||
$results = $this->dbh->query($sql);
|
||||
$results = $this->dbh->query($sql, PDO::FETCH_ASSOC);
|
||||
if (! $results) {
|
||||
list($std_code, $driver_code, $message) = $this->dbh->errorInfo();
|
||||
|
||||
@@ -123,7 +123,7 @@ class SihnonFramework_Database {
|
||||
}
|
||||
}
|
||||
|
||||
return $stmt->fetchAll();
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
} else {
|
||||
$results = array();
|
||||
|
||||
227
source/lib/SihnonFramework/DatabaseObject.class.php
Normal file
227
source/lib/SihnonFramework/DatabaseObject.class.php
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
abstract class SihnonFramework_DatabaseObject {
|
||||
|
||||
protected static $table;
|
||||
|
||||
protected static function table() {
|
||||
return static::$table;
|
||||
}
|
||||
|
||||
protected function setDatabaseProperties(array $properties) {
|
||||
foreach($properties as $property => $value) {
|
||||
if (property_exists(get_called_class(), '_db_' . $property)) {
|
||||
$this->{'_db_' . $property} = $value;
|
||||
} else {
|
||||
throw new Sihnon_Exception_InvalidProperty($property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function fromDatabaseRow($row) {
|
||||
$object = new static();
|
||||
$object->setDatabaseProperties($row);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a DatabaseObject given its ID
|
||||
*
|
||||
* @param int $id
|
||||
* @return SihnonFramework_DatabaseObject
|
||||
*/
|
||||
public static function fromId($id) {
|
||||
$database = SihnonFramework_Main::instance()->database();
|
||||
|
||||
$object = self::fromDatabaseRow(
|
||||
$database->selectOne('SELECT * FROM `'.static::table().'` WHERE id=:id', array(
|
||||
array('name' => 'id', 'value' => $id, 'type' => PDO::PARAM_INT)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a DatabaseObject given a field name and value
|
||||
*
|
||||
* @param string $name Name of the field to match on
|
||||
* @param mixed $value Value of the field to match on
|
||||
*/
|
||||
public static function from($field, $value) {
|
||||
$database = SihnonFramework_Main::instance()->database();
|
||||
|
||||
$object = self::fromDatabaseRow(
|
||||
$database->selectOne("SELECT * FROM `".static::table()."` WHERE `{$field}`=:{$field}", array(
|
||||
array('name' => $field, 'value' => $value, 'type' => PDO::PARAM_STR)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a list of all objects
|
||||
*
|
||||
* @return SihnonFramework_DatabaseObject
|
||||
*/
|
||||
public static function all($view = null, $additional_conditions = null, $additional_params = null) {
|
||||
$database = SihnonFramework_Main::instance()->database();
|
||||
|
||||
if ($view === null) {
|
||||
$view = static::table();
|
||||
}
|
||||
|
||||
$class = new ReflectionClass(get_called_class());
|
||||
$properties = $class->getproperties();
|
||||
|
||||
$fields = array();
|
||||
foreach ($properties as $property) {
|
||||
$matches = array();
|
||||
if (preg_match('/^_db_(.*)/', $property->name, $matches)) {
|
||||
$fields[] = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
$field_list = join(', ', array_map(function($v) { return "`{$v}`"; }, $fields));
|
||||
|
||||
$params = array();
|
||||
if ($additional_params) {
|
||||
$params = array_merge($params, $additional_params);
|
||||
}
|
||||
|
||||
$conditions = '';
|
||||
if ($additional_conditions) {
|
||||
$conditions = "AND ({$additional_conditions}) ";
|
||||
}
|
||||
|
||||
$objects = array();
|
||||
$sql = "SELECT {$field_list} FROM `{$view}` WHERE `id` > 0 {$conditions} ORDER BY `id` DESC";
|
||||
foreach ($database->selectList($sql, $params) as $row) {
|
||||
$objects[] = static::fromDatabaseRow($row);
|
||||
}
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
public static function allFor($field, $value, $view = null, $additional_conditions = null, $additional_params = null) {
|
||||
$conditions = "`{$field}`=:{$field} ";
|
||||
if ($additional_conditions) {
|
||||
$conditions .= "AND ({$additional_conditions}) ";
|
||||
}
|
||||
|
||||
$params = array(
|
||||
array('name' => $field, 'value' => $value, 'type' => PDO::PARAM_STR),
|
||||
);
|
||||
if ($additional_params) {
|
||||
$params = array_merge($params, $additional_params);
|
||||
}
|
||||
|
||||
return static::all($view, $conditions, $params);
|
||||
}
|
||||
|
||||
public static function exists($field, $value, $view = null) {
|
||||
$database = Sihnon_Main::instance()->database();
|
||||
|
||||
return $database->selectOne('SELECT COUNT(*) FROM `'.static::table().'` "WHERE `{$field}`=:{$field} LIMIT 1', array(
|
||||
array('name' => $field, 'value' => $value, 'type' => PDO::PARAM_STR),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function create() {
|
||||
$database = SihnonFramework_Main::instance()->database();
|
||||
|
||||
$class = new ReflectionClass(get_called_class());
|
||||
$properties = $class->getproperties();
|
||||
|
||||
$fields = array();
|
||||
$params = array();
|
||||
foreach ($properties as $property) {
|
||||
$matches = array();
|
||||
if (preg_match('/^_db_(.*)/', $property->name, $matches)) {
|
||||
$fields[] = $matches[1];
|
||||
|
||||
$params[] = array(
|
||||
'name' => $matches[1],
|
||||
'value' => ($matches[1] == 'id') ? 'NULL' : $this->{"_db_{$matches[1]}"},
|
||||
'type' => PDO::PARAM_STR
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$id_list = join(', ', array_map(function($v) { return "`{$v}`"; }, $fields));
|
||||
$value_list = join(', ', array_map(function($v) { return ":{$v}"; }, $fields));
|
||||
|
||||
$database->insert("INSERT INTO `".static::table()."` ({$id_list}) VALUES({$value_list})", $params);
|
||||
|
||||
$this->id = $database->lastInsertId();
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$database = SihnonFramework_Main::instance()->database();
|
||||
|
||||
$class = new ReflectionClass(get_called_class());
|
||||
$properties = $class->getproperties();
|
||||
|
||||
$fields = array();
|
||||
$params = array();
|
||||
foreach ($properties as $property) {
|
||||
$matches = array();
|
||||
if (preg_match('/^_db_(.*)/', $property->name, $matches)) {
|
||||
if ($matches[1] != 'id') {
|
||||
$fields[] = $matches[1];
|
||||
}
|
||||
|
||||
$params[] = array(
|
||||
'name' => $matches[1],
|
||||
'value' => $this->{"_db_{$matches[1]}"},
|
||||
'type' => PDO::PARAM_STR
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$id_list = join(', ', array_map(function($v) { return "`{$v}`=:{$v}"; }, $fields));
|
||||
$value_list = join(', ', array_map(function($v) { return ":{$v}"; }, $fields));
|
||||
|
||||
$database->update("UPDATE `".static::table()."` SET {$id_list} WHERE `id`=:id", $params);
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
$database = SihnonFramework_Main::instance()->database();
|
||||
|
||||
$database->update(
|
||||
'DELETE FROM `'.static::table().'` WHERE `id`=:id LIMIT 1',
|
||||
array(
|
||||
array('name' => 'id', 'value' => $this->id, 'type' => PDO::PARAM_INT),
|
||||
)
|
||||
);
|
||||
|
||||
$this->id = null;
|
||||
}
|
||||
|
||||
public function __set($name, $value) {
|
||||
$fullname = "_db_{$name}";
|
||||
if ( ! property_exists(get_called_class(), $fullname)){
|
||||
throw new SihnonFramework_Exception_InvalidProperty($name);
|
||||
}
|
||||
|
||||
$this->{$fullname} = $value;
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
$fullname = "_db_{$name}";
|
||||
if ( ! property_exists(get_called_class(), $fullname)){
|
||||
throw new SihnonFramework_Exception_InvalidProperty($name);
|
||||
}
|
||||
|
||||
return $this->{$fullname};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
119
source/lib/SihnonFramework/DateTime.class.php
Normal file
119
source/lib/SihnonFramework/DateTime.class.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_DateTime {
|
||||
|
||||
const MINUTE = 60;
|
||||
const HOUR = 3600;
|
||||
const DAY = 86400;
|
||||
const WEEK = 604800;
|
||||
const MONTH = 2629744;
|
||||
const YEAR = 31556926;
|
||||
|
||||
/**
|
||||
* Formats the time in a fuzzy way
|
||||
*
|
||||
* Taken from http://byteinn.com/res/426/Fuzzy_Time_function/ and reformatted for use in a class.
|
||||
* "An online free resource for developers who believe in reuse of code and do not waste time to reinvent the wheel."
|
||||
* info@byteinn.com
|
||||
*
|
||||
* @param mixed $time The time to be formatted
|
||||
* @return string
|
||||
*/
|
||||
public static function fuzzyTime($time) {
|
||||
if ( ! preg_match('/^\d+$/', $time)) {
|
||||
if (($time = strtotime($time)) == false) {
|
||||
return 'an unknown time';
|
||||
}
|
||||
}
|
||||
|
||||
$now = time();
|
||||
|
||||
// sod = start of day :)
|
||||
$sod = mktime(0, 0, 0, date('m', $time), date('d', $time), date('Y', $time));
|
||||
$sod_now = mktime(0, 0, 0, date('m', $now), date('d', $now), date('Y', $now));
|
||||
|
||||
// used to convert numbers to strings
|
||||
$convert = array(
|
||||
1 => 'one',
|
||||
2 => 'two',
|
||||
3 => 'three',
|
||||
4 => 'four',
|
||||
5 => 'five',
|
||||
6 => 'six',
|
||||
7 => 'seven',
|
||||
8 => 'eight',
|
||||
9 => 'nine',
|
||||
10 => 'ten',
|
||||
11 => 'eleven'
|
||||
);
|
||||
|
||||
// today
|
||||
if ($sod_now == $sod) {
|
||||
if ($time > $now - (self::MINUTE * 3)) {
|
||||
return 'just a moment ago';
|
||||
} else if ($time > $now - (self::MINUTE * 7)) {
|
||||
return 'a few minutes ago';
|
||||
} else if ($time > $now - (self::HOUR)) {
|
||||
return 'less than an hour ago';
|
||||
}
|
||||
return 'today at ' . date('g:ia', $time);
|
||||
}
|
||||
|
||||
// yesterday
|
||||
if (($sod_now - $sod) <= self::DAY) {
|
||||
if (date('i', $time) > (self::MINUTE + 30)) {
|
||||
$time += self::HOUR / 2;
|
||||
}
|
||||
return 'yesterday around ' . date('ga', $time);
|
||||
}
|
||||
|
||||
// within the last 5 days
|
||||
if (($sod_now - $sod) <= (self::DAY * 5)) {
|
||||
$str = date('l', $time);
|
||||
$hour = date('G', $time);
|
||||
if ($hour < 12) {
|
||||
$str .= ' morning';
|
||||
} else if ($hour < 17) {
|
||||
$str .= ' afternoon';
|
||||
} else if ($hour < 20) {
|
||||
$str .= ' evening';
|
||||
} else {
|
||||
$str .= ' night';
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
// number of weeks (between 1 and 3)...
|
||||
if (($sod_now-$sod) < (self::WEEK * 3.5)) {
|
||||
if (($sod_now-$sod) < (self::WEEK * 1.5)) {
|
||||
return 'about a week ago';
|
||||
} else if (($sod_now-$sod) < (self::DAY * 2.5)) {
|
||||
return 'about two weeks ago';
|
||||
} else {
|
||||
return 'about three weeks ago';
|
||||
}
|
||||
}
|
||||
|
||||
// number of months (between 1 and 11)...
|
||||
if (($sod_now-$sod) < (self::MONTH * 11.5)) {
|
||||
for ($i = (self::WEEK * 3.5), $m=0; $i < self::YEAR; $i += self::MONTH, $m++) {
|
||||
if ( ($sod_now-$sod) <= $i ) {
|
||||
return 'about ' . $convert[$m] . ' month' . (($m>1)?'s':'') . ' ago';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// number of years...
|
||||
for ($i = (self::MONTH * 11.5), $y=0; $i < (self::YEAR * 10); $i += self::YEAR, $y++) {
|
||||
if (($sod_now-$sod) <= $i) {
|
||||
return 'about ' . $convert[$y] . ' year' . (($y>1)?'s':'') . ' ago';
|
||||
}
|
||||
}
|
||||
|
||||
// more than ten years...
|
||||
return 'more than ten years ago';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -13,6 +13,7 @@ class SihnonFramework_Exception_TemplateException extends SihnonFramework_E
|
||||
class SihnonFramework_Exception_AbortEntirePage extends SihnonFramework_Exception_TemplateException {};
|
||||
class SihnonFramework_Exception_Unauthorized extends SihnonFramework_Exception_TemplateException {};
|
||||
class SihnonFramework_Exception_FileNotFound extends SihnonFramework_Exception_TemplateException {};
|
||||
class SihnonFramework_Exception_NotAuthorised extends SihnonFramework_Exception_TemplateException {};
|
||||
class SihnonFramework_Exception_InvalidParameters extends SihnonFramework_Exception_TemplateException {};
|
||||
|
||||
class SihnonFramework_Exception_DatabaseException extends SihnonFramework_Exception {};
|
||||
@@ -21,6 +22,7 @@ class SihnonFramework_Exception_DatabaseConnectFailed extends SihnonFramework_E
|
||||
class SihnonFramework_Exception_NoDatabaseConnection extends SihnonFramework_Exception_DatabaseException {};
|
||||
class SihnonFramework_Exception_DatabaseQueryFailed extends SihnonFramework_Exception_DatabaseException {};
|
||||
class SihnonFramework_Exception_ResultCountMismatch extends SihnonFramework_Exception_DatabaseException {};
|
||||
class SihnonFramework_Exception_InvalidProperty extends SihnonFramework_Exception_DatabaseException {};
|
||||
|
||||
class SihnonFramework_Exception_ConfigException extends SihnonFramework_Exception {};
|
||||
class SihnonFramework_Exception_UnknownSetting extends SihnonFramework_Exception_ConfigException {};
|
||||
@@ -38,4 +40,16 @@ class SihnonFramework_Exception_LogException extends SihnonFramework_E
|
||||
class SihnonFramework_Exception_LogFileNotWriteable extends SihnonFramework_Exception_LogException {};
|
||||
class SihnonFramework_Exception_InvalidLog extends SihnonFramework_Exception_LogException {};
|
||||
|
||||
class SihnonFramework_Exception_AuthException extends SihnonFramework_Exception {};
|
||||
class SihnonFramework_Exception_UnknownUser extends SihnonFramework_Exception_AuthException {};
|
||||
class SihnonFramework_Exception_IncorrectPassword extends SihnonFramework_Exception_AuthException {};
|
||||
|
||||
class SihnonFramework_Exception_ValidationException extends SihnonFramework_Exception {};
|
||||
class SihnonFramework_Exception_InvalidContent extends SihnonFramework_Exception_ValidationException {};
|
||||
class SihnonFramework_Exception_InvalidLength extends SihnonFramework_Exception_ValidationException {};
|
||||
|
||||
class SihnonFramework_Exception_DaemonException extends SihnonFramework_Exception {};
|
||||
class SihnonFramework_Exception_AlreadyRunning extends SihnonFramework_Exception_DaemonException {};
|
||||
class SihnonFramework_Exception_LockingFailed extends SihnonFramework_Exception_DaemonException {};
|
||||
|
||||
?>
|
||||
|
||||
@@ -35,7 +35,7 @@ class SihnonFramework_ForegroundTask {
|
||||
);
|
||||
|
||||
$pipes = array();
|
||||
$process = proc_open($command, $descriptors, $pipes);
|
||||
$process = proc_open($command, $descriptors, $pipes, $cwd, $env);
|
||||
|
||||
stream_set_blocking($pipes[self::PIPE_STDIN], 0); // Make stdin/stdout/stderr non-blocking
|
||||
stream_set_blocking($pipes[self::PIPE_STDOUT], 0);
|
||||
|
||||
22
source/lib/SihnonFramework/Formatting.class.php
Normal file
22
source/lib/SihnonFramework/Formatting.class.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Formatting {
|
||||
|
||||
public static function filesize($bytes) {
|
||||
return SihnonFramework_Main::formatFilesize($bytes);
|
||||
}
|
||||
|
||||
public static function duration($seconds, $fuzziness) {
|
||||
return SihnonFramework_Main::formatDuration($seconds, $fuzziness);
|
||||
}
|
||||
|
||||
public static function pluralise($count, $singular, $multiple) {
|
||||
if ($count == 1) {
|
||||
return $singular;
|
||||
} else{
|
||||
return $multiple;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
@@ -34,6 +34,7 @@ class SihnonFramework_Log_Plugin_Console extends SihnonFramework_Log_PluginBase
|
||||
|
||||
// Make some alterations for ease of display
|
||||
$fields_map['timestamp'] = date('d/m/y H:i:s', $fields_map['ctime']);
|
||||
$fields_map['shortfile'] = basename($fields_map['file']);
|
||||
|
||||
// split the map back out again now the modifications have been made
|
||||
$fields = array_keys($fields_map);
|
||||
|
||||
@@ -17,11 +17,14 @@ class SihnonFramework_Main {
|
||||
protected $database;
|
||||
protected $log;
|
||||
protected $cache;
|
||||
protected $session;
|
||||
protected $auth;
|
||||
|
||||
protected $base_uri;
|
||||
|
||||
protected function __construct() {
|
||||
$this->base_uri = dirname($_SERVER['SCRIPT_NAME']) . '/';
|
||||
$dirname = dirname($_SERVER['SCRIPT_NAME']);
|
||||
$this->base_uri = $dirname == '/' ? '/' : $dirname . '/';
|
||||
}
|
||||
|
||||
protected function init() {
|
||||
@@ -38,6 +41,9 @@ class SihnonFramework_Main {
|
||||
$this->log = new Sihnon_Log($this->config);
|
||||
|
||||
$this->cache = new Sihnon_Cache($this->config);
|
||||
|
||||
$this->session = new Sihnon_Session($this->config);
|
||||
$this->auth = new Sihnon_Auth($this->config, $this->session);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,6 +92,22 @@ class SihnonFramework_Main {
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SihnonFramework_Session
|
||||
*/
|
||||
public function session() {
|
||||
return $this->session;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SihnonFramework_Auth
|
||||
*/
|
||||
public function auth() {
|
||||
return $this->auth;
|
||||
}
|
||||
|
||||
public function baseUri() {
|
||||
return $this->base_uri;
|
||||
}
|
||||
@@ -333,32 +355,74 @@ class SihnonFramework_Main {
|
||||
return $default;
|
||||
}
|
||||
|
||||
public static function formatDuration($time) {
|
||||
if (is_null($time)) {
|
||||
return 'unknown';
|
||||
}
|
||||
public static function formatDuration($seconds, $fuzziness = 0) {
|
||||
if (is_null($seconds)) {
|
||||
return 'indeterminate time';
|
||||
}
|
||||
|
||||
$labels = array('seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years');
|
||||
$limits = array(1, 60, 3600, 86400, 604800, 2592000, 31556926, PHP_INT_MAX);
|
||||
$labels = array('second', 'minute', 'hour', 'day', 'week', 'month', 'year');
|
||||
$pluralLabels = array('seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'years');
|
||||
$limits = array(1, 60, 3600, 86400, 604800, 2592000, 31556926, PHP_INT_MAX);
|
||||
$components = array(0, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
$working_time = $time;
|
||||
$workingTime = $seconds;
|
||||
|
||||
$result = "";
|
||||
$ptr = count($labels) - 1;
|
||||
$result = "";
|
||||
$ptr = count($labels) - 1;
|
||||
|
||||
while ($ptr >= 0 && $working_time < $limits[$ptr]) {
|
||||
--$ptr;
|
||||
}
|
||||
while ($ptr >= 0 && $workingTime < $limits[$ptr]) {
|
||||
--$ptr;
|
||||
}
|
||||
$mostSignificantPtr = $ptr;
|
||||
|
||||
while ($ptr >= 0) {
|
||||
$unit_time = floor($working_time / $limits[$ptr]);
|
||||
$working_time -= $unit_time * $limits[$ptr];
|
||||
$result = $result . ' ' . $unit_time . ' ' . $labels[$ptr];
|
||||
--$ptr;
|
||||
}
|
||||
// Convert the value into components using the remaining labels
|
||||
while ($ptr >= 0) {
|
||||
$unitTime = floor($workingTime / $limits[$ptr]);
|
||||
$workingTime -= $unitTime * $limits[$ptr];
|
||||
$components[$ptr] = $unitTime;
|
||||
--$ptr;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
$componentsUsed = 0;
|
||||
$approximate = false;
|
||||
$lastComponent = false;
|
||||
$ptr = $mostSignificantPtr;
|
||||
while ($ptr >= 0) {
|
||||
if ($fuzziness && $componentsUsed >= $fuzziness) {
|
||||
break;
|
||||
} elseif ($ptr == 0 || ($fuzziness && $componentsUsed == $fuzziness-1)) {
|
||||
$lastComponent = true;
|
||||
}
|
||||
|
||||
$component = $components[$ptr];
|
||||
if ($component) {
|
||||
// If we're going to hide the next value, take its component into account here
|
||||
if ($lastComponent && $ptr > 0) {
|
||||
$component += round($components[$ptr-1] / $limits[$ptr]);
|
||||
$approximate = true;
|
||||
}
|
||||
|
||||
if ($lastComponent && $ptr < $mostSignificantPtr) {
|
||||
$result .= ' and';
|
||||
}
|
||||
|
||||
$result .= ' ' . $component . ' ' . ($component == 1 ? $labels[$ptr] : $pluralLabels[$ptr]);
|
||||
|
||||
}
|
||||
|
||||
// Increment even if we've hidden this component because it's zero
|
||||
// Then we don't end up with overly precise times like '2 years and 1 second'
|
||||
++$componentsUsed;
|
||||
|
||||
--$ptr;
|
||||
}
|
||||
|
||||
if ($approximate) {
|
||||
$result = 'approximately ' . $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function formatFilesize($bytes) {
|
||||
if (is_null($bytes)) {
|
||||
|
||||
@@ -7,10 +7,14 @@ class SihnonFramework_Page {
|
||||
|
||||
private $page;
|
||||
|
||||
public function __construct(Smarty $smarty, SihnonFramework_RequestParser $request) {
|
||||
public function __construct(Smarty $smarty, SihnonFramework_RequestParser $request, $page = null) {
|
||||
$this->smarty = $smarty;
|
||||
$this->request = $request;
|
||||
$this->page = $request->page();
|
||||
$this->page = $page;
|
||||
|
||||
if ($page === null) {
|
||||
$this->page = $request->page();
|
||||
}
|
||||
}
|
||||
|
||||
public function page() {
|
||||
@@ -21,22 +25,33 @@ class SihnonFramework_Page {
|
||||
return $this->page . '.tpl';
|
||||
}
|
||||
|
||||
public function code_filename() {
|
||||
return $this->page . '.php';
|
||||
}
|
||||
|
||||
public function evaluate($template_variables = array()) {
|
||||
$code_filename = $this->page . '.php';
|
||||
$code_filename = $this->code_filename();
|
||||
$template_filename = $this->template_filename();
|
||||
|
||||
$content = '';
|
||||
try {
|
||||
$this->render($template_filename, $code_filename, $template_variables);
|
||||
$this->smarty->assign('page', $this);
|
||||
$this->smarty->assign('requested_page', $this->page);
|
||||
$content = $this->render($template_filename, $code_filename, $template_variables);
|
||||
} catch (SihnonFramework_Exception_AbortEntirePage $e) {
|
||||
return false;
|
||||
} catch (SihnonFramework_Exception_FileNotFound $e) {
|
||||
$this->render('errors/404.tpl', 'errors/404.php');
|
||||
$content = $this->render('errors/404.tpl', 'errors/404.php');
|
||||
} catch (SihnonFramework_Exception_NotAuthorised $e) {
|
||||
$content = $this->render('errors/401.tpl', 'errors/404.php');
|
||||
} catch (SihnonFramework_Exception $e) {
|
||||
$this->render('errors/unhandled-exception.tpl', 'errors/unhandled-exception.php', array(
|
||||
$content = $this->render('errors/unhandled-exception.tpl', 'errors/unhandled-exception.php', array(
|
||||
'exception' => $e,
|
||||
));
|
||||
}
|
||||
|
||||
$this->smarty->assign('page_content', $content);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,10 +72,13 @@ class SihnonFramework_Page {
|
||||
include $real_code_filename;
|
||||
}
|
||||
|
||||
$this->smarty->assign('requested_page', $this->page);
|
||||
|
||||
// Now execute the template itself, which will render the results of the code file
|
||||
$this->smarty->assign('page_content', $this->smarty->fetch($template_filename));
|
||||
return $this->smarty->fetch($template_filename);
|
||||
}
|
||||
|
||||
public function include_template($page, $template_variables = array()) {
|
||||
$subpage = new Sihnon_Page($this->smarty, $this->request, $page);
|
||||
return $subpage->render($subpage->template_filename(), $subpage->code_filename(), $template_variables);
|
||||
}
|
||||
|
||||
public static function redirect($relative_url) {
|
||||
|
||||
80
source/lib/SihnonFramework/Session.class.php
Normal file
80
source/lib/SihnonFramework/Session.class.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Session {
|
||||
|
||||
protected $config;
|
||||
|
||||
protected $enabled;
|
||||
protected $state;
|
||||
protected $dirty;
|
||||
|
||||
public function __construct(Sihnon_Config $config) {
|
||||
$this->config = $config;
|
||||
$this->enabled = false;
|
||||
$this->dirty = false;
|
||||
|
||||
if ($this->config->exists('sessions') && $this->config->get('sessions')) {
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->teardown();
|
||||
}
|
||||
|
||||
protected function init() {
|
||||
if ($this->enabled) {
|
||||
session_start();
|
||||
$this->state = $_SESSION;
|
||||
|
||||
// Override the session parameters if configured
|
||||
$params = session_get_cookie_params();
|
||||
$lifetime = $this->config->exists('sessions.lifetime') ? $this->config->get('sessions.lifetime') : $params['lifetime'];
|
||||
$path = $this->config->exists('sessions.path') ? $this->config->get('sessions.path') : $params['path'];
|
||||
$domain = $this->config->exists('sessions.domain') ? $this->config->get('sessions.domain') : $params['domain'];
|
||||
$secure = $this->config->exists('sessions.secure') ? $this->config->get('sessions.secure') : $params['secure'];
|
||||
$httponly = $this->config->exists('sessions.http-only') ? $this->config->get('sessions.http-only') : $params['httponly'];
|
||||
session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly);
|
||||
}
|
||||
}
|
||||
|
||||
protected function teardown() {
|
||||
if ($this->enabled && $this->dirty) {
|
||||
$_SESSION = $this->state;
|
||||
session_write_close();
|
||||
}
|
||||
}
|
||||
|
||||
public function set($name, $value) {
|
||||
$this->state[$name] = $value;
|
||||
$this->dirty = true;
|
||||
}
|
||||
|
||||
public function get($name, $default = null) {
|
||||
if ( ! $this->exists($name)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $this->state[$name];
|
||||
}
|
||||
|
||||
public function exists($name) {
|
||||
return isset($this->state[$name]);
|
||||
}
|
||||
|
||||
public function delete($name) {
|
||||
unset($this->state[$name]);
|
||||
$this->dirty = true;
|
||||
}
|
||||
|
||||
public function securityLeveLChanged() {
|
||||
if ($this->enabled) {
|
||||
session_regenerate_id(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
9
source/lib/SihnonFramework/Validation.class.php
Normal file
9
source/lib/SihnonFramework/Validation.class.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
abstract class SihnonFramework_Validation {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
19
source/lib/SihnonFramework/Validation/Enum.class.php
Normal file
19
source/lib/SihnonFramework/Validation/Enum.class.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
Class SihnonFramework_Validation_Enum extends SihnonFramework_Validation {
|
||||
|
||||
public static function validate($inputs, $class, $prefix) {
|
||||
if ( ! is_array($inputs)) {
|
||||
$inputs = array($inputs);
|
||||
}
|
||||
|
||||
foreach ($inputs as $input) {
|
||||
if ( ! SihnonFramework_Main::isClassConstantValue($class, $prefix, $input)) {
|
||||
throw new SihnonFramework_Exception_InvalidContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
67
source/lib/SihnonFramework/Validation/Text.class.php
Normal file
67
source/lib/SihnonFramework/Validation/Text.class.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
class SihnonFramework_Validation_Text extends SihnonFramework_Validation {
|
||||
|
||||
const Defaults = 0xff;
|
||||
const Alphabetical = 0x01;
|
||||
const Digit = 0x02;
|
||||
const Numeric = 0x04;
|
||||
const Symbol = 0x08;
|
||||
const Whitespace = 0x16;
|
||||
|
||||
protected static $contents = array(
|
||||
self::Alphabetical => '[:alpha:]',
|
||||
self::Digit => '[:digit:]',
|
||||
self::Numeric => '[:digit:]\.-',
|
||||
self::Symbol => '[:punct:]',
|
||||
self::Whitespace => '[:space:]',
|
||||
);
|
||||
|
||||
public static function content($inputs, $content = self::Defaults) {
|
||||
static::pattern($inputs, static::buildContentPattern($content));
|
||||
}
|
||||
|
||||
public static function length($inputs, $min_length = null, $max_length = null) {
|
||||
if ( ! is_array($inputs)) {
|
||||
$inputs = array($inputs);
|
||||
}
|
||||
|
||||
foreach ($inputs as $input) {
|
||||
$length = strlen($input);
|
||||
|
||||
if ($min_length !== null && $length < $min_length) {
|
||||
throw new SihnonFramework_Exception_InvalidLength();
|
||||
}
|
||||
|
||||
if ($max_length !== null && $length > $max_length) {
|
||||
throw new SihnonFramework_Exception_InvalidLength();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function pattern($inputs, $pattern) {
|
||||
if ( ! is_array($inputs)) {
|
||||
$inputs = array($inputs);
|
||||
}
|
||||
|
||||
foreach ($inputs as $input) {
|
||||
if ( ! preg_match($pattern, $input)) {
|
||||
throw new SihnonFramework_Exception_InvalidContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static function buildContentPattern($contents) {
|
||||
$classes = '';
|
||||
foreach (static::$contents as $set => $class) {
|
||||
if ($contents & $set) {
|
||||
$classes .= $class;
|
||||
}
|
||||
}
|
||||
|
||||
return "/^[{$classes}]*$/";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user