Page MenuHomeDevCentral

No OneTemporary

diff --git a/includes/core.php b/includes/core.php
index 7d9bb32..2171b4a 100644
--- a/includes/core.php
+++ b/includes/core.php
@@ -1,385 +1,385 @@
<?php
/*
* Keruald, core libraries for Pluton and Xen engines.
* (c) 2010, Sébastien Santoro aka Dereckson, some rights reserved
* Released under BSD license
*
* Core
*
* 0.1 2010-02-27 2:04 DcK
*/
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Configures PHP and loads site-wide used libraries ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//Disables register globals
ini_set('register_globals', 'off');
//Reports all errors, help notices (including STRICT in PHP 6)
error_reporting(E_ALL & ~E_NOTICE);
//Load libraries
include_once("config.php"); //Site config
include_once("error.php"); //Error management
include_once("mysqli.php"); //MySQL layer
include_once("session.php"); //Sessions handler
include_once("autoload.php"); //Autoloader
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Information helper functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Gets the username matching specified user id
* @param string $user_id the user ID
* @return string the username
*/
function get_username ($user_id) {
- global $db;
+ $db = sql_db::load();
$user_id = $db->sql_escape($user_id);
$sql = 'SELECT username FROM '. TABLE_USERS . " WHERE user_id = '$userid'";
return $db->sql_query_express($sql, "Can't get username from specified user id");
}
/*
* Gets the user id matching specified username
* @param string $username the username
* @return string the user ID
*/
function get_userid ($username) {
- global $db;
+ $db = sql_db::load();
$username = $db->sql_escape($username);
$sql = 'SELECT user_id FROM '. TABLE_USERS . " WHERE username LIKE '$username'";
return $db->sql_query_express($sql, "Can't get user id from specified username");
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Misc helper functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
//Plural management
/*
* Gets a "s" if the specified amount requests the plural
* @param mixed $amount the quantity (should be numeric)
* @return string 's' if the amount is greater or equal than 2 ; otherwise, ''
*/
function s ($amount) {
if ($amount >= 2 || $amount <= -2 ) return 's';
}
/*
* Prints human-readable information about a variable, wrapped in a <pre> block
* @param mixed $mixed the variable to dump
*/
function dprint_r ($mixed) {
echo '<pre>';
print_r($mixed);
echo '</pre>';
}
/*
* Generates a new GUID
* @return string a guid (without {})
*/
function new_guid () {
//The guid chars
$chars = explode(',', 'a,b,c,d,e,f,0,1,2,3,4,5,6,7,8,9');
//Let's build our 36 characters string
//e.g. 68ed40c6-f5bb-4a4a-8659-3adf23536b75
$guid = "";
for ($i = 0 ; $i < 36 ; $i++) {
if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
//Dashes at position 9, 14, 19 and 24
$guid .= "-";
} else {
//0-f hex digit elsewhere
$guid .= $chars[mt_rand() % sizeof($characters)];
}
}
return $guid;
}
/*
* Determines if the expression is a valid guid (in uuid notation, without {})
* @param string $expression the guid to check
* @return true if the expression is a valid guid ; otherwise, false
*/
function is_guid ($expression) {
//We avoid regexp to speed up the check
//A guid is a 36 characters string
if (strlen($expression) != 36) return false;
$expression = strtolower($expression);
for ($i = 0 ; $i < 36 ; $i++) {
if ($i == 8 || $i == 13 || $i == 18 || $i == 23) {
//with dashes
if ($expression[$i] != '-') return false;
} else {
//and hex numbers
if (!is_numeric($expression[$i]) && $expression[$i] != 'a' && $expression[$i] != 'b' && $expression[$i] != 'c' && $expression[$i] != 'd' && $expression[$i] != 'e' && $expression[$i] != 'f' ) return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Files, extensions and directories ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Gets files in a directory
*
* @param string $dir The directory files are located (optional, by default the current directory)
* @param string $extension The extension to lookup without initial dot (optional, return every file if omitted)
* @return array the files in the specified directory optionally filtered by extension
*/
function get_files ($dir = '.', $extension = NULL) {
$handle = opendir($dir);
$files = [];
while ($file = readdir($handle)) {
if ($file == '.' || $file == '..' || is_dir($file)) {
continue;
}
if ($extension === NULL || get_extension($file) == $extension) {
$files[] = $file;
}
}
return $files;
}
/**
* Gets file extension
*
* @param string $file the file to get the extension
*/
function get_extension ($file) {
return pathinfo($file, PATHINFO_EXTENSION);
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// Strings manipulation ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/**
* Determines if a string starts with specified substring
*
* @param string $haystack the string to check
* @param string $needle the substring to determines if it's the start
* @param boolean $case_sensitive determines if the search must be case sensitive
* @return boolean true if $haystack starts with $needle ; otherwise, false.
*/
function string_starts_with ($haystack, $needle, $case_sensitive = true) {
if (!$case_sensitive) {
$haystack = strtoupper($haystack);
$needle = strtoupper($needle);
}
if ($haystack == $needle) return true;
return strpos($haystack, $needle) === 0;
}
/**
* Gets the portion of the string between $includeFrom and $includeTo
*/
function string_between ($haystack, $from, $to, $includeFrom = false, $includeTo = false) {
//Gets start position
$pos1 = strpos($haystack, $from);
if ($pos1 === false) {
return "";
}
if (!$includeFrom) $pos1 += strlen($from);
//Gets end position
$pos2 = strpos($haystack, $to, $pos1 + strlen($from));
if ($pos2 === false) {
return substr($haystack, $pos1);
}
if ($includeTo) $pos2 += strlen($to);
//Gets middle part
return substr($haystack, $pos1, $pos2 - $pos1);
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// URL helpers functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Gets URL
* @return string URL
*/
function get_url () {
global $Config;
if (func_num_args() > 0) {
$pieces = func_get_args();
return $Config['BaseURL'] . '/' . implode('/', $pieces);
} elseif ($Config['BaseURL'] == "" || $Config['BaseURL'] == "/index.php") {
return "/";
} else {
return $Config['BaseURL'];
}
}
/*
* Gets page URL
* @return string URL
*/
function get_page_url () {
$url = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO'];
if (substr($url, -10) == "/index.php") {
return substr($url, 0, -9);
}
return $url;
}
/*
* Gets server URL
* @todo find a way to detect https:// on non standard port
* @return string the server URL
*/
function get_server_url () {
switch ($port = $_SERVER['SERVER_PORT']) {
case '80':
return "http://$_SERVER[SERVER_NAME]";
case '443':
return "https://$_SERVER[SERVER_NAME]";
default:
return "http://$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]";
}
}
/*
* Gets $_SERVER['PATH_INFO'] or computes the equivalent if not defined.
* @return string the relevant URL part
*/
function get_current_url () {
global $Config;
//Gets relevant URL part from relevant $_SERVER variables
if (array_key_exists('PATH_INFO', $_SERVER)) {
//Without mod_rewrite, and url like /index.php/controller
//we use PATH_INFO. It's the easiest case.
return $_SERVER["PATH_INFO"];
}
//In other cases, we'll need to get the relevant part of the URL
$current_url = get_server_url() . $_SERVER['REQUEST_URI'];
//Relevant URL part starts after the site URL
$len = strlen($Config['SiteURL']);
//We need to assert it's the correct site
if (substr($current_url, 0, $len) != $Config['SiteURL']) {
dieprint_r(GENERAL_ERROR, "Edit includes/config.php and specify the correct site URL<br /><strong>Current value:</strong> $Config[SiteURL]<br /><strong>Expected value:</strong> a string starting by " . get_server_url(), "Setup");
}
//Last possibility: use REQUEST_URI or REDIRECT_URL, but remove QUERY_STRING
//TODO: handle the case of a nginx misconfiguration, where the query_string have been removed.
// e.g. 'fastcgi_param SCRIPT_FILENAME $document_root/index.php;' will remove the QS.
// (a working could be $document_root/index.php?$query_string);
$url = array_key_exists('REDIRECT_URL', $_SERVER) ? $_SERVER["REDIRECT_URL"] : $_SERVER["REQUEST_URI"];
$url = substr(get_server_url() . $url, $len);
if ($_SERVER['QUERY_STRING']) {
return substr($url, 0, strlen($url) - strlen($_SERVER['QUERY_STRING']) - 1);
}
return $url;
}
/*
* Gets an array of url fragments to be processed by controller
* @return array an array containing URL fragments
*/
function get_current_url_fragments () {
$url_source = get_current_url();
if ($url_source == '/index.php') return array();
return explode('/', substr($url_source, 1));
}
/**
* Gets the URL for the specified resources
*
* @param ... string a arbitray number of path info
*/
function get_url_for () {
global $Config;
$url = get_server_url() . '/' . $Config[BaseURL];
if (func_num_args()) {
$url .= implode('/', func_get_args());
}
return $url;
}
/**
* Gets directory relative to the site root
*
* @param string $dir the absolute path
* @return string the relative directory to the site root
*/
function get_directory ($dir) {
$rootPath = dirname(__DIR__);
$rootPathLen = strlen($rootPath);
if (substr($dir, 0, $rootPathLen) != $rootPath) {
throw new InvalidArgumentException("Directory $dir doesn't start by root directory $rootPath.");
}
return substr($dir, ++$rootPathLen);
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// URL xmlHttpRequest helpers functions ///
/// ///
////////////////////////////////////////////////////////////////////////////////
/*
* Gets an hash value to check the integrity of URLs in /do.php calls
* @param array $args the args to compute the hash
* @return the hash paramater for your xmlHttpRequest url
*/
function get_xhr_hash ($args) {
global $Config;
array_shift($args);
return md5($_SESSION['ID'] . $Config['SecretKey'] . implode('', $args));
}
/*
* Gets the URL to call do.php, the xmlHttpRequest controller
* @return string the xmlHttpRequest url, with an integrity hash
*/
function get_xhr_hashed_url () {
global $Config;
$args = func_get_args();
$args[] = get_xhr_hash($args);
return $Config['DoURL'] . '/' . implode('/', $args);
}
/*
* Gets the URL to call do.php, the xmlHttpRequest controller
* @return string the xmlHttpRequest url
*/
function get_xhr_url () {
global $Config;
$args = func_get_args();
return $Config['DoURL'] . '/' .implode('/', $args);
}
diff --git a/includes/document.php b/includes/document.php
index 8c8b5fb..da99d1e 100644
--- a/includes/document.php
+++ b/includes/document.php
@@ -1,363 +1,363 @@
<?php
/*
* Keruald, core libraries for Pluton and Xen engines.
* (c) 2010, Sébastien Santoro aka Dereckson, some rights reserved
* Released under BSD license
*
* @package Pluton
* @subpackage Pluton
* @copyright Copyright (c) 2010-2011, Sébastien Santoro aka Dereckson
* @license Released under BSD license
* @version 0.1
*/
class Document {
/**
* URL, before any treatment
*/
public $url;
/**
* Topic, with - as topic seperator
*/
public $topic;
/**
* Article, without extension
*/
public $article;
/**
* Extension, without .
*/
public $extension;
/**
* HTTP status code (200, 404, etC.)
*/
public $status;
/**
* Document title
*/
public $title;
/**
* Document description
*/
public $description;
/**
* Content to write in <head> block
*/
public $head;
/**
* Content to write at the end of the document.
* This is after the site footer.
* To write something before, use a local _footer.php file.
*/
public $footer;
/**
* If true, doesn't print the header
* @var boolean
*/
public $noheader = false;
/**
* If true, doesn't print the footer
* @var boolean
*/
public $nofooter = false;
/**
* Initializes a new instance of Session object
*/
public function __construct ($url) {
$this->url = self::clean_url($url);
$this->get_document();
}
/**
* Finds the document
*/
private function find_document () {
//URL matches an existing file or directory
if (file_exists($this->url)) {
if (is_dir($this->url)) {
//Ensures we've a trailing /
$url = (substr($this->url, -1) == '/') ? $this->url : $this->url . '/';
if (file_exists($url . 'index.html')) {
$this->url = $url . 'index.html';
} elseif (file_exists($url . 'index.php')) {
$this->url = $url . 'index.php';
} else {
return false; //empty directory
}
}
return true;
}
//Application known extensions
$extension = get_extension($this->url);
if ($extension == "query") {
$file = $this->url . ".php";
if (file_exists($file)) {
$this->url = $file;
$this->noheader = true;
$this->nofooter = true;
return true;
}
}
//Tries other extensions
$extensions_to_try = array('html', 'php');
$pathinfo = pathinfo($this->url);
foreach ($extensions_to_try as $ext) {
$file = "$pathinfo[dirname]/$pathinfo[filename].$ext";
if (file_exists($file)) {
$this->url = $file;
return true;
}
}
//Handles homepages
if ($this->is_homepage($this->url)) {
$this->url = "_index/index.html";
return true;
}
return false;
}
/**
* Gets the URL of the entry point script
*/
static function get_entry_point_url () {
$backtrace = debug_backtrace();
$entry_point = array_pop($backtrace)['file'];
return substr($entry_point, strlen(getcwd()));
}
/**
* Gets the document matching the URL
*/
private function get_document () {
global $Config;
//Finds the document
if ($this->find_document()) {
$this->status = 200;
} else {
$this->url = $Config['Pages']['Error404']; //TODO: choose and document error implementation
$this->status = 404;
}
//Fills info from URL
$pathinfo = pathinfo($this->url);
if (!$this->is_homepage()) {
$this->topic = str_replace('/', '-', $pathinfo['dirname']);
$this->article = $pathinfo['filename']; //PHP 5.2.0+
}
$this->extension = strtolower($pathinfo['extension']);
$this->title = "[$this->article]";
//Fills info from _documents.xml
$this->get_description();
}
/**
* Cleans specified URL
*
* @param string $url the URL to clean
* @return string clean URL
*/
public static function clean_url ($url) {
global $Config;
if ($Config['AllowTopicArticleRequest'] && self::hasTopicArticleRequest()) {
//This legacy mode allows site with 2001 Pluton version like
//espace-win.net to make a smoother transition.
//Cf. www.w3.org/Provider/Style/URI.html Cool URIs don't change
//Topic (?Topic=...)
if (array_key_exists('Topic', $_REQUEST)) {
$url = str_replace('-', '/', $_REQUEST['Topic']) . '/';
}
//Article (&Article=...)
if (array_key_exists('Article', $_REQUEST)) {
$url .= $_REQUEST['Article'];
} else {
$url .= 'index';
}
//Extension (&ext=...)
if (array_key_exists('ext', $_REQUEST)) {
$url .= '.';
$url .= $_REQUEST['ext'];
} else {
$url .= '.html';
}
return $url;
}
//Homepage?
if ($url == '' || $url == '/' || $url == $Config['BaseURL'] || $url == $Config['BaseURL'] . '/') {
return $Config['Homepage'];
}
return substr($url, 1);
}
/**
* Determines if the HTTP request contains Topic, Article or ext parameters
*
* @return bool true if the HTTP request contains Topic, Article or ext parameters ; otherwise, false
*/
public static function hasTopicArticleRequest () {
return array_key_exists('Topic', $_REQUEST) || array_key_exists('Article', $_REQUEST) || array_key_exists('ext', $_REQUEST);
}
/**
* Determines if the current document is the homepage.
*
* @return bool true if the current document is the homepage ; otherwise, false.
*/
public function is_homepage () {
global $Config;
//return $this->url == $Config['Homepage'];
if ( $this->url == $Config['Homepage']) return true;
if ($this->topic == "_index" && substr($this->article, 0, 5) == "index") return true;
return false;
}
/**
* Gets footer file (_footer.php) path in the current or parent directories
*
* @return string the path to the current footer if found ; otherwise, null. (or null if no footer is found)
*/
public function get_footer () {
$dirs = explode('-', $this->topic);
for ($i = count($dirs) ; $i > 0 ; $i--) {
$footer = join($dirs, '/') . '/_footer.php';
if (file_exists($footer)) {
return $footer;
}
array_pop($dirs);
}
return null;
}
/**
* Prints the document body
*/
public function render_body () {
- global $db, $Config, $Session, $CurrentUser;
+ global $Config, $Session, $CurrentUser;
$document = $this;
//404 header
if ($this->status == 404) {
header("Status: 404 Not Found");
}
//Header content
if (!$this->noheader) {
$header = $this->get_directory() . '/_header.php';
if (file_exists($header)) {
include($header);
}
}
//Includes file
switch ($this->extension) {
case 'txt':
echo "<pre>";
include($this->url);
echo "</pre>";
break;
case 'png':
case 'jpg':
case 'gif':
case 'svg':
case 'bmp':
echo "<div align=center><img src=\"$this->url\" /></div>";
break;
default:
include($this->url);
}
//Footer
if (!$nofooter && $footer = $this->get_footer()) {
include($footer);
}
}
/**
* Prints the document
*
* Use this method if you don't wish to have access to any other global
- * variables than $db, $Config, $Session and $CurrentUser.
+ * variables than $Config, $Session and $CurrentUser.
*
* A more flexible method is the body of this method in _includes/body.php
* and to add in your skin <?php include('_includes/body.php'); ?>
*/
function render () {
//Global variables for the header and the footer
- global $db, $Config, $Session, $CurrentUser;
+ global $Config, $Session, $CurrentUser;
$document = $this;
//HTML output
$theme = $Config['Theme'];
if (!$this->noheader) include("themes/$theme/header.php");
$this->render_body();
if (!$this->nofooter) include("themes/$theme/footer.php");
}
/**
* Gets the document description
*/
function get_description () {
if ($this->status == 404) {
$this->title = "404 Not Found";
$this->description = "The requested resource hasn't been found.";
return;
}
if ($description = self::get_description_from_documentsXml($this->topic, $this->article)) {
$variables = [ 'title', 'description', 'head', 'footer' ];
foreach ($variables as $variable) {
if (isset($description->$variable)) {
$this->$variable = (string)$description->$variable;
}
}
$shortTags = [ 'noheader', 'nofooter' ];
foreach ($shortTags as $shortTag) {
if (isset($description->$shortTag)) {
$this->$shortTag = true;
}
}
}
}
public static function get_description_from_documentsXml ($topic, $article) {
$topicDocuments = str_replace('-', '/', $topic) . '/_documents.xml';
if (file_exists($topicDocuments)) {
$xml = simplexml_load_file($topicDocuments, null, LIBXML_NOCDATA);
foreach($xml->document as $document) {
if ($document->article == $article) {
return $document;
}
}
return null;
}
}
public function get_directory () {
return str_replace('-', '/', $this->topic);
}
}
diff --git a/includes/error.php b/includes/error.php
index ab9abde..ffc1a8b 100644
--- a/includes/error.php
+++ b/includes/error.php
@@ -1,108 +1,108 @@
<?php
/*
* Keruald, core libraries for Pluton and Xen engines.
* (c) 2010, Sébastien Santoro aka Dereckson, some rights reserved
* Released under BSD license
*
* Error handling
*
* 0.1 2010-02-27 16:00 DcK
*
* @todo add exception handling facilities
*
* There are 3 standard error types:
* - SQL_ERROR error during a sql query
* - HACK_ERROR error trying to access a protected resource
* - GENERAL_ERROR miscelleanous error
*
* The message_die/SQL_ERROR idea were found in phpBB 2 code.
*
* Tip: use HACK_ERROR when an user can't access a page, and edit message_die
* to output a login/pass form if the user isn't logged in, so the user
* will be invited to log in properly and legetimely access to the page.
* (cf. the Pluton's error.php for a sample)
*
* Tip: if you use a MVC model or at least templates, message_die should calls
* an error template but only if the template engine is initialized.
* (cf. the Xen's error.php for a sample)
*
* Tip: evaluate the cost/benefit to output a SQL error to the user and consider
* not to output the sql query or the error code to standard users.
*
* Tip: if you need more help to understand where exactly the error have occured
* consider Advanced PHP debugger: www.php.net/manual/en/book.apd.php
*/
//Error code constants
define ("SQL_ERROR", 65);
define ("HACK_ERROR", 99);
define ("GENERAL_ERROR", 117);
/*
* Prints human-readable information about a variable
* wrapped in a general error and dies
* @param mixed $mixed the variable to dump
*/
function dieprint_r ($var, $title = '') {
if (!$title) $title = 'Debug';
//GENERAL_ERROR with print_r call as message
message_die(GENERAL_ERROR, '<pre>' . print_r($var, true) .'</pre>', $title);
}
/*
* Prints an error message and dies
* @param int $code A constant identifying the type of error (SQL_ERROR, HACK_ERROR or GENERAL_ERROR)
* @param string $text the error description
* @param string $text the error title
* @param int $line the file line the error have occured (typically __LINE__)
* @param string $file the file the error have occured (typically __FILE__)
* @param string $sql the sql query which caused the error
*/
function message_die ($code, $text = '', $title = '', $line = '', $file = '', $sql = '') {
//Ensures we've an error text
$text = $text ? $text : "An error have occured";
//Adds file and line information to error text
if ($file) {
$text .= " — $file";
if ($line) {
$text .= ", line $line";
}
}
//Ensures we've an error title and adds relevant extra information
switch ($code) {
case HACK_ERROR:
$title = $title ? $title : "Access non authorized";
break;
case SQL_ERROR:
- global $db;
+ $db = sql_db::load();
$title = $title ? $title : "SQL error";
//Gets SQL error information
$sqlError = $db->sql_error();
if ($sqlError['message'] != '') {
$text .= "<br />Error n° $sqlError[code]: $sqlError[message]";
}
$text .= '<br />&nbsp;<br />Query: ';
$text .= $sql;
break;
default:
//TODO: here can be added code to handle error error ;-)
//Falls to GENERAL_ERROR
case GENERAL_ERROR:
$title = $title ? $title : "General error";
break;
}
//HTML output of $title and $text variables
echo '<div class="FatalError"><p class="FatalErrorTitle">', $title,
'</p><p>', $text, '</p></div>';
exit;
}
diff --git a/includes/mysqli.php b/includes/mysqli.php
index cc82615..d6cfca6 100644
--- a/includes/mysqli.php
+++ b/includes/mysqli.php
@@ -1,149 +1,168 @@
<?php
/**
* Keruald, core libraries for Pluton and Xen engines.
* (c) 2010, 2014, Sébastien Santoro aka Dereckson, some rights reserved
* Released under BSD license
*
* MySQLi layer and helper class
*/
if (!defined('SQL_LAYER')) {
define('SQL_LAYER', 'MySQL');
/**
* SQL layer and helper class: MySQLi
*
* @package Keruald
* @subpackage Keruald
* @copyright Copyright (c) 2010, Sébastien Santoro aka Dereckson
* @license Released under BSD license
* @version 0.1
*/
class sql_db {
/*
* @var int the connection identifier
*/
private $db;
+ /**
+ * Singleton instance
+ *
+ * @var sql_db
+ */
+ private static $instance = null;
+
/**
* Initializes a new instance of the database abstraction class, for MySQLi engine
*/
function __construct($host = 'localhost', $username = '', $password = '', $database = '') {
//Connects to MySQL server
$this->db = new mysqli($host, $username, $password) or $this->sql_die();
//Selects database
if ($database != '') {
$this->db->select_db($database);
}
+
+ $db->set_charset('utf8');
+ }
+
+ static function load() {
+ if (self::$instance === null) {
+ self::makeSingletonInstance();
+ }
+
+ return self::$instance;
+ }
+
+ private static function makeSingletonInstance() {
+ global $Config;
+
+ self::$instance = new sql_db(
+ $Config['sql']['host'], $Config['sql']['username'],
+ $Config['sql']['password'], $Config['sql']['database']
+ );
+
+ unset($Config['sql']);
}
/**
* Outputs a can't connect to the SQL server message and exits.
* It's called on connect failure
*/
private function sql_die () {
//You can custom here code when you can't connect to SQL server
//e.g. in a demo or appliance context, include('start.html'); exit;
die ("Can't connect to SQL server.");
}
/**
* Sends a unique query to the database
*
* @return mixed if the query is successful, a mysqli_result instance ; otherwise, false
*/
function sql_query ($query) {
return $this->db->query($query);
}
/**
* Fetches a row of result into an associative array
*
* @return array an associative array with columns names as keys and row values as values
*/
function sql_fetchrow ($result) {
return $result->fetch_array();
}
/**
* Gets last SQL error information
*
* @return array an array with two keys, code and message, containing error information
*/
function sql_error () {
return [
'code' => $this->db->errno,
'message' => $this->db->error
];
}
/**
* Gets the number of rows affected or returned by a query
*
* @return int the number of rows affected (delete/insert/update) or the number of rows in query result
*/
function sql_numrows ($result) {
return $result->num_rows;
}
/**
* Gets the primary key value of the last query (works only in INSERT context)
*
* @return int the primary key value
*/
function sql_nextid () {
return $this->db->insert_id;
}
/**
* Express query method, returns an immediate and unique result
*
* @param string $query the query to execute
* @param string $error_message the error message
* @param boolean $return_as_string return result as string, and not as an array
* @return mixed the row or the scalar result
*/
function sql_query_express ($query = '', $error_message = "Impossible d'exécuter cette requête.", $return_as_string = true) {
if ($query === '' || $query === false || $query === null) {
//No query, no value
return '';
} elseif (!$result = $this->sql_query($query)) {
//An error have occured
message_die(SQL_ERROR, $error_message, '', '', '', $query);
} else {
//Fetches row
$row = $this->sql_fetchrow($result);
//If $return_as_string is true, returns first query item (scalar mode) ; otherwise, returns row
return $return_as_string ? $row[0] : $row;
}
}
/*
* Escapes a SQL expression
* @param string expression The expression to escape
* @return string The escaped expression
*/
function sql_escape ($expression) {
return $this->db->real_escape_string($expression);
}
/**
* Sets charset
*/
function set_charset ($encoding) {
$this->db->set_charset($encoding);
}
}
-
- //Creates an instance of this database class with configuration values
- $db = new sql_db($Config['sql']['host'], $Config['sql']['username'], $Config['sql']['password'], $Config['sql']['database']);
-
- //To improve security, we unset sql parameters
- unset($Config['sql']);
-
- //Sets SQL connexion in UTF-8.
- $db->set_charset('utf8');
}
diff --git a/includes/objects/user.php b/includes/objects/user.php
index fb56438..41a8ffa 100644
--- a/includes/objects/user.php
+++ b/includes/objects/user.php
@@ -1,192 +1,194 @@
<?php
/*
* Keruald, core libraries for Pluton and Xen engines.
* (c) 2010, Sébastien Santoro aka Dereckson, some rights reserved
* Released under BSD license
*
* User class
*
* 0.1 2010-02-27 20:51 DcK
*
* @package Keruald
* @subpackage Keruald
* @copyright Copyright (c) 2010, Dereckson
* @license Released under BSD license
* @version 0.1
*
*/
class User {
public $id;
public $name;
public $password;
public $active = 0;
public $email;
public $regdate;
-
+
/*
* Initializes a new instance
* @param int $id the primary key
*/
function __construct ($id = null) {
if ($id) {
$this->id = $id;
$this->load_from_database();
}
}
-
+
/*
* Loads the object User (ie fill the properties) from the $_POST array
*/
function load_from_form () {
if (array_key_exists('name', $_POST)) $this->name = $_POST['name'];
if (array_key_exists('password', $_POST)) $this->password = $_POST['password'];
if (array_key_exists('active', $_POST)) $this->active = $_POST['active'];
if (array_key_exists('actkey', $_POST)) $this->actkey = $_POST['actkey'];
if (array_key_exists('email', $_POST)) $this->email = $_POST['email'];
if (array_key_exists('regdate', $_POST)) $this->regdate = $_POST['regdate'];
}
-
+
/*
* Loads the object User (ie fill the properties) from the database
*/
function load_from_database () {
- global $db;
+ $db = sql_db::load();
$sql = "SELECT * FROM " . TABLE_USERS . " WHERE user_id = '" . $this->id . "'";
if ( !($result = $db->sql_query($sql)) ) message_die(SQL_ERROR, "Unable to query users", '', __LINE__, __FILE__, $sql);
if (!$row = $db->sql_fetchrow($result)) {
$this->lastError = "User unkwown: " . $this->id;
return false;
}
-
+
$this->load_from_row($row);
-
+
return true;
}
-
+
/*
* Loads the object User (ie fill the properties) from the database row
*/
function load_from_row ($row) {
$this->id = $row['user_id'];
$this->name = $row['username'];
$this->password = $row['user_password'];
$this->active = $row['user_active'] ? true : false;
$this->email = $row['user_email'];
$this->regdate = $row['user_regdate'];
}
-
+
/*
* Saves to database
*/
function save_to_database () {
- global $db;
-
+ $db = sql_db::load();
+
$id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL';
$name = $db->sql_escape($this->name);
$password = $db->sql_escape($this->password);
$active = $this->active ? 1 : 0;
$email = $db->sql_escape($this->email);
$regdate = $this->regdate ? "'" . $db->sql_escape($this->regdate) . "'" : 'NULL';
//Updates or inserts
$sql = "REPLACE INTO " . TABLE_USERS . " (`user_id`, `username`, `user_password`, `user_active`, `user_email`, `user_regdate`) VALUES ($id, '$name', '$password', $active, '$email', $regdate)";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save user", '', __LINE__, __FILE__, $sql);
}
-
+
if (!$this->id) {
//Gets new record id value
$this->id = $db->sql_nextid();
}
}
-
+
/*
* Updates the specified field in the database record
*/
function save_field ($field) {
- global $db;
+ $db = sql_db::load();
if (!$this->id) {
message_die(GENERAL_ERROR, "You're trying to update a record not yet saved in the database");
}
$id = $db->sql_escape($this->id);
$value = $db->sql_escape($this->$field);
$sql = "UPDATE " . TABLE_USERS . " SET `$field` = '$value' WHERE user_id = '$id'";
if (!$db->sql_query($sql)) {
message_die(SQL_ERROR, "Unable to save $field field", '', __LINE__, __FILE__, $sql);
}
}
-
+
/*
* Generates a unique user id
*/
function generate_id () {
- global $db;
-
+ $db = sql_db::load();
+
do {
$this->id = mt_rand(2001, 9999);
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE user_id = $this->id";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't check if a user id is free", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
- } while ($row[0]);
+ } while ($row[0]);
}
-
+
/*
* Fills password field with encrypted version
* of the specified clear password
*/
public function set_password ($newpassword) {
$this->password = md5($newpassword);
}
/*
* Checks if a login is available
* @param string $login the login to check
* @return boolean true if the login is avaiable ; otherwise, false.
*/
public static function is_available_login ($login) {
- global $db;
+ $db = sql_db::load();
+
$sql = "SELECT COUNT(*) FROM " . TABLE_USERS . " WHERE username = '$login'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't check if the specified login is available", '', __LINE__, __FILE__, $sql);
}
$row = $db->sql_fetchrow($result);
return ($row[0] == 0);
}
-
+
/*
* Initializes a new User instance ready to have its property filled
- * @return User the new user instance
+ * @return User the new user instance
*/
public static function create () {
$user = new User();
$user->generate_id();
$user->active = true;
return $user;
}
-
+
/*
* Gets user from specified e-mail
* @return User the user matching the specified e-mail ; null, if the mail were not found.
*/
public static function get_user_from_email ($mail) {
- global $db;
+ $db = sql_db::load();
+
$sql = "SELECT username FROM " . TABLE_USERS . " WHERE user_email = '$mail'";
if (!$result = $db->sql_query($sql)) {
message_die(SQL_ERROR, "Can't get user", '', __LINE__, __FILE__, $sql);
}
-
+
if ($row = $db->sql_fetchrow($result)) {
//E-mail found.
$user = new User();
$user->load_from_row($row);
return $user;
}
-
+
//E-mail not found.
return null;
}
}
diff --git a/includes/session.php b/includes/session.php
index ae3763e..12cc55a 100644
--- a/includes/session.php
+++ b/includes/session.php
@@ -1,248 +1,251 @@
<?php
/*
* Keruald, core libraries for Pluton and Xen engines.
* (c) 2010, Sébastien Santoro aka Dereckson, some rights reserved
* Released under BSD license
*
* Session
*
* 0.1 2010-02-26 18:06 DcK
*
* This class uses a singleton pattern, as we only need one single instance.
* Cf. http://www.php.net/manual/en/language.oop5.patterns.php
*
* @package Keruald
* @subpackage Keruald
* @copyright Copyright (c) 2010, Sébastien Santoro aka Dereckson
* @license Released under BSD license
* @version 0.1
*/
class Session {
/*
* @var Session current session instance
*/
private static $instance;
/*
* Gets or initializes current session instance
* @return Session current session instance
*/
public static function load () {
if (!isset(self::$instance)) {
//Creates new session instance
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
/*
* @var string session ID
*/
public $id;
/*
* @var string remote client IP
*/
public $ip;
/*
* Initializes a new instance of Session object
*/
private function __construct () {
//Starts PHP session, and gets id
session_start();
$_SESSION['ID'] = session_id();
$this->id = $_SESSION['ID'];
//Gets remote client IP
$this->ip = self::get_ip();
//Updates or creates the session in database
$this->update();
}
/*
* Gets remote client IP address
* @return string IP
*/
public static function get_ip () {
//mod_proxy + mod_rewrite (old pluton url scheme) will define 127.0.0.1
//in REMOTE_ADDR, and will store ip in HTTP_X_FORWARDED_FOR variable.
//Some ISP/orgz proxies also use this setting.
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
return $_SERVER['HTTP_X_FORWARDED_FOR'];
}
//Standard cases
return $_SERVER['REMOTE_ADDR'];
}
/*
* Cleans up session
* i. deletes expired session
* ii. sets offline relevant sessions
*/
public static function clean_old_sessions () {
- global $db, $Config;
+ global $Config;
+ $db = sql_db::load();
//Gets session and online status lifetime (in seconds)
//If not specified in config, sets default 5 and 120 minutes values
$onlineDuration = array_key_exists('OnlineDuration', $Config) ? $Config['OnlineDuration'] : 300;
$sessionDuration = array_key_exists('SessionDuration', $Config) ? $Config['SessionDuration'] : 7200;
$resource = array_key_exists('ResourceID', $Config) ? '\'' . $db->sql_escape($Config['ResourceID']) . '\'' : 'default';
//Deletes expired sessions
$sql = "DELETE FROM " . TABLE_SESSIONS . " WHERE session_resource = $resource AND TIMESTAMPDIFF(SECOND, session_updated, NOW()) > $sessionDuration";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, "Can't delete expired sessions", '', __LINE__, __FILE__, $sql);
//Online -> offline
$sql = "UPDATE " . TABLE_SESSIONS . " SET session_online = 0 WHERE TIMESTAMPDIFF(SECOND, session_updated, NOW()) > $onlineDuration AND session_resource = $resource";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, 'Can\'t update sessions online statuses', '', __LINE__, __FILE__, $sql);
}
/*
* Updates or creates a session in the database
*/
public function update () {
- global $db, $Config;
+ global $Config;
+ $db = sql_db::load();
//Cleans up session
//To boost SQL performances, try a random trigger
// e.g. if (rand(1, 100) < 3) self::clean_old_sessions();
//or comment this line and execute a cron script you launch each minute.
self::clean_old_sessions();
//Saves session in database.
//If the session already exists, it updates the field online and updated.
$id = $db->sql_escape($this->id);
$resource = array_key_exists('ResourceID', $Config) ? '\'' . $db->sql_escape($Config['ResourceID']) . '\'' : 'default';
$user_id = $db->sql_escape(ANONYMOUS_USER);
$sql = "INSERT INTO " . TABLE_SESSIONS . " (session_id, session_ip, session_resource, user_id) VALUES ('$id', '$this->ip', $resource, '$user_id') ON DUPLICATE KEY UPDATE session_online = 1";
if (!$db->sql_query($sql)) message_die(SQL_ERROR, 'Can\'t save current session', '', __LINE__, __FILE__, $sql);
}
/*
* Gets the number of online users
* @return int the online users count
*/
public function count_online () {
//Keeps result for later method call
static $count = -1;
if ($count == -1) {
//Queries sessions table
- global $db, $Config;
+ global $Config;
+ $db = sql_db::load();
$resource = array_key_exists('ResourceID', $Config) ? '\'' . $db->sql_escape($Config['ResourceID']) . '\'' : 'default';
$sql = "SELECT count(*) FROM " . TABLE_SESSIONS . " WHERE session_resource = $resource AND session_online = 1";
$count = (int)$db->sql_query_express($sql, "Can't count online users");
}
//Returns number of users online
return $count;
}
/*
* Gets the value of a custom session table field
* @param string $info the field to get
* @return string the session specified field's value
*/
public function get_info ($info) {
- global $db;
+ $db = sql_db::load();
$id = $db->sql_escape($this->id);
$sql = "SELECT `$info` FROM " . TABLE_SESSIONS . " WHERE session_id = '$id'";
return $db->sql_query_express($sql, "Can't get session $info info");
}
/*
* Sets the value of a custom session table field to the specified value
* @param string $info the field to update
* @param string $value the value to set
*/
public function set_info ($info, $value) {
- global $db;
+ $db = sql_db::load();
$value = ($value === null) ? 'NULL' : "'" . $db->sql_escape($value) . "'";
$id = $db->sql_escape($this->id);
$sql = "UPDATE " . TABLE_SESSIONS . " SET `$info` = $value WHERE session_id = '$id'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't set session $info info", '', __LINE__, __FILE__, $sql);
}
/*
* Gets logged user information
* @return User the logged user information
*/
public function get_logged_user () {
- global $db;
+ $db = sql_db::load();;
//Gets session information
$id = $db->sql_escape($this->id);
$sql = "SELECT * FROM " . TABLE_SESSIONS . " WHERE session_id = '$id'";
if (!$result = $db->sql_query($sql))
message_die(SQL_ERROR, "Can't query session information", '', __LINE__, __FILE__, $sql);
$row = $db->sql_fetchrow($result);
//Gets user instance
require_once('includes/objects/user.php');
$user = new User($row['user_id']);
//Adds session property to this user instance
$user->session = $row;
//Returns user instance
return $user;
}
/*
* Cleans session
* This method is to be called when an event implies a session destroy
*/
public function clean () {
//Destroies $_SESSION array values, help ID
foreach ($_SESSION as $key => $value) {
if ($key != 'ID') unset($_SESSION[$key]);
}
}
/*
* Updates the session in an user login context
* @param string $user_id the user ID
*/
public function user_login ($user_id) {
- global $db;
+ $db = sql_db::load();
//Sets specified user ID in sessions table
$user_id = $db->sql_escape($user_id);
$id = $db->sql_escape($this->id);
$sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$user_id' WHERE session_id = '$id'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't set logged in status", '', __LINE__, __FILE__, $sql);
}
/*
* Updates the session in an user logout context
*/
public function user_logout () {
- global $db;
+ $db = sql_db::load();
//Sets anonymous user in sessions table
$user_id = $db->sql_escape(ANONYMOUS_USER);
$id = $db->sql_escape($this->id);
$sql = "UPDATE " . TABLE_SESSIONS . " SET user_id = '$user_id' WHERE session_id = '$id'";
if (!$db->sql_query($sql))
message_die(SQL_ERROR, "Can't set logged out status", '', __LINE__, __FILE__, $sql);
//Cleans session
$this->clean();
}
}
//The user_id matching anonymous user
if (!defined('ANONYMOUS_USER')) define('ANONYMOUS_USER', -1);

File Metadata

Mime Type
text/x-diff
Expires
Sat, Mar 7, 02:44 (14 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3494978
Default Alt Text
(49 KB)

Event Timeline