Page MenuHomeDevCentral

No OneTemporary

diff --git a/apps/documents/DocumentsApplication.php b/apps/documents/DocumentsApplication.php
index daaf4cc..acf5c31 100644
--- a/apps/documents/DocumentsApplication.php
+++ b/apps/documents/DocumentsApplication.php
@@ -1,110 +1,110 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Documents application class
*
* @package ObsidianWorkspaces
* @subpackage HelloWorld
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
/**
* Documents application class
*/
class DocumentsApplication extends Application {
/**
* @var string the application name
*/
public static $name = "Documents";
/**
* Gets path to a document file
*/
private function getFilePath ($file) {
global $Config;
return $Config['Content']['Workspaces']
. DIRECTORY_SEPARATOR
. $this->context->workspace->code
. DIRECTORY_SEPARATOR
. $this->context->configuration->path
. DIRECTORY_SEPARATOR
. $file;
}
/**
* Gets documents list
*
* @return array The documents list
*/
public function getDocumentsList () {
$dir = $this->getFilePath('');
$files = scandir($dir);
$documents = [];
foreach ($files as $file) {
if (get_extension($file) == 'json') {
$documents[] = get_filename($file);
}
}
return $documents;
}
/**
* Gets document
*
* @param string $docId the document identifier
* @return stdClass the document JSON representation
*/
public function getDocument ($docId) {
$file = $this->getFilePath($docId . '.json');
$data = file_get_contents($file);
return json_decode($data);
}
public static function getDocumentType ($type) {
$key = 'DocumentType' . ucfirst(strtolower($type));
- return lang_get($key);
+ return Language::get($key);
}
/**
* Handles controller request
*/
public function handleRequest () {
//Reference to URL fragments and Smarty engine
$url = $this->context->url;
$smarty = $this->context->templateEngine;
//Gets resources for HTML output
if (count($url) == 1) {
//Prints the list of the documents
$documents = $this->getDocumentsList();
$smarty->assign('documents', $documents);
$template = 'documents_list.tpl';
} else {
//Prints a document
$docId = $url[1];
$document = $this->getDocument($docId);
$smarty->assign('documentId', $docId);
$smarty->assign('documentType', self::getDocumentType($document->type));
$smarty->assign('document', $document);
$template = 'documents_view.tpl';
}
//Serves header
$smarty->assign('PAGE_TITLE', "Documents");
HeaderController::run($this->context);
//Serves body
$smarty->display('apps/documents/' . $template);
//Serves footer
FooterController::run($this->context);
}
}
diff --git a/controllers/anonymous.php b/controllers/anonymous.php
index 853921f..c58fb1c 100755
--- a/controllers/anonymous.php
+++ b/controllers/anonymous.php
@@ -1,179 +1,179 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Controller to handle the pages for not logged in users.
*
* It recognizes the following URLs:
* /invite the page to claim the invites.
*
* In all other cases, it prints the login form.
*
* @package ObsidianWorkspaces
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*
*/
//
// Prepares the page
//
switch ($url[0]) {
case 'invite':
echo "You have been invited to use Obsidian. This feature is currently disabled. Please ask the person who invited you to contact our support desk to create your account.";
/* Code from Zed
//Invite form
if ($_POST['form'] == 'account.create') {
//User tries to claim its invite to create an account
require_once('includes/objects/invite.php');
require_once('includes/objects/user.php');
//Gets invite
$invite = new Invite($_POST['invite_code']);
if ($invite->lastError != '') {
//Not existant invite.
- $smarty->assign('NOTIFY', lang_get("IncorrectInviteCode"));
+ $smarty->assign('NOTIFY', Language::get("IncorrectInviteCode"));
} elseif ($invite->is_claimed()) {
//The invitation have already claimed by someone else.
- $smarty->assign('NOTIFY', lang_get("InviteCodeAlreadyClaimed"));
+ $smarty->assign('NOTIFY', Language::get("InviteCodeAlreadyClaimed"));
} else {
//Checks if the given information is correct
//We ignore bad mails. All we really need is a login and a pass.
//We fill our array $errors with all the errors
$errors = array();
if (!$_POST['username']) {
- $errors[] = lang_get('MissingUsername');
+ $errors[] = Language::get('MissingUsername');
} elseif (!User::is_available_login($_POST['username'])) {
- $errors[] = lang_get('LoginUnavailable');
+ $errors[] = Language::get('LoginUnavailable');
}
if (User::get_username_from_email($_POST['email']) !== false) {
$errors[] = "There is already an account with this e-mail.";
}
if (!$_POST['passwd']) {
- $errors[] = lang_get('MissingPassword');
+ $errors[] = Language::get('MissingPassword');
}
if (count($errors)) {
$smarty->assign('WAP', join('<br />', $errors));
} else {
//Creates account
$user = new User();
$user->regdate = time();
$user->generate_id();
$user->name = $_POST['username'];
$user->active = 1;
$user->email = $_POST['email'];
$user->set_password($_POST['passwd']);
$user->save_to_database();
//Updates invite
$invite->to_user_id = $user->id;
$invite->save_to_database();
//Notifies inviter
require_once('includes/objects/message.php');
$message = new Message();
$message->from = 0;
$message->to = $invite->from_perso_id;
- $message->text = sprintf(lang_get('InviteHaveBeenClaimed'), $invite->code);
+ $message->text = sprintf(Language::get('InviteHaveBeenClaimed'), $invite->code);
$message->send();
//Logs in user
login($user->id, $user->name);
//Prints confirm message
- $smarty->assign('WAP', lang_get("AccountCreated"));
+ $smarty->assign('WAP', Language::get("AccountCreated"));
//Redirects users to homepage
header('refresh: 5; url=' . get_url());
//Calls void controller
$smarty->assign('screen', 'user.create');
define('NO_FOOTER_EXTRA', true);
include("void.php");
exit;
}
}
//Keeps username, email, invite code printed on account create form
$smarty->assign('username', $_POST['username']);
$smarty->assign('invite_code', $_POST['invite_code']);
$smarty->assign('email', $_POST['email']);
}
//If the invite code is specified, checks format
if ($url[1]) {
if (preg_match("/^([A-Z]){3}([0-9]){3}$/i", $url[1])) {
$smarty->assign('invite_code', strtoupper($url[1]));
} else {
- $smarty->assign('NOTIFY', lang_get("IncorrectInviteCode"));
+ $smarty->assign('NOTIFY', Language::get("IncorrectInviteCode"));
}
}
$template = 'account_create.tpl';
*/
break;
default:
//Login
if ($context->workspace == null) {
$useInternalLogin = true;
} else {
$useInternalLogin = $context->workspace->configuration->allowInternalAuthentication;
$authenticationMethodsTemplateInformation = [];
$authenticationMethodsLoginErrors = [];
foreach ($context->workspace->configuration->authenticationMethods as $method) {
$authenticationMethodsNav[] = [
'text' => (string)$method->loginMessage,
'href' => $method->getAuthenticationLink()
];
if ($method->loginError) {
$authenticationMethodsLoginErrors[] = (string)$method->loginError;
}
}
$smarty->assign('ExternalAuthenticationMethodsNav', $authenticationMethodsNav);
$smarty->assign('ExternalLoginErrors', $authenticationMethodsLoginErrors);
$smarty->assign('WorkspaceName', $context->workspace->name);
}
//Internal login form
if ($useInternalLogin) {
if (array_key_exists('LastUsername', $_COOKIE)) {
$smarty->assign('username', $_COOKIE['LastUsername']);
}
if (array_key_exists('LastOpenID', $_COOKIE)) {
$smarty->assign('OpenID', $_COOKIE['LastOpenID']);
}
$action = $context->workspace ? get_url($context->workspace->code) . '/' : get_url();
$action .= implode('/', $context->url);
$smarty->assign('LoginError', $LoginError);
$smarty->assign('PostURL', $action);
$smarty->assign('PrintInternalLogin', true);
} else {
$smarty->assign('PrintInternalLogin', false);
}
$template = 'login.tpl';
break;
}
//
// HTML output
//
if ($template) {
$smarty->display($template);
}
diff --git a/controllers/home.php b/controllers/home.php
index 1843fdf..ec8dd15 100644
--- a/controllers/home.php
+++ b/controllers/home.php
@@ -1,84 +1,84 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Controller for homepage content
*
* @package ObsidianWorkspaces
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*
*/
/**
* Homepage controller
*/
class HomepageController extends Controller {
/**
* Handles controller request
*/
public function handleRequest () {
$smarty = $this->context->templateEngine;
$workspace = $this->context->workspace;
if ($workspace == null) {
//We need a list of workspaces to allow user
//to select the one he wishes to access.
//The header has already grabbed it for us.
if (array_key_exists('workspaces', $smarty->tpl_vars)) {
$workspaces = $smarty->tpl_vars['workspaces']->value;
} else {
$workspaces = $this->context->user->get_workspaces();
$smarty->assign('workspaces', $workspaces);
}
switch (count($workspaces)) {
case 0:
//No workspace error message
- $smarty->assign('PAGE_TITLE', lang_get("Home"));
+ $smarty->assign('PAGE_TITLE', Language::get("Home"));
$template = "home_noworkspace.tpl";
break;
case 1:
//Autoselect workspace
$this->context->workspace = $workspaces[0];
$workspace = $workspaces[0];
$this->context->workspace->loadConfiguration($this->context);
break;
default:
//Select workspace template
- $smarty->assign('PAGE_TITLE', lang_get("PickWorkspace"));
+ $smarty->assign('PAGE_TITLE', Language::get("PickWorkspace"));
$template = "home_pickworkspace.tpl";
}
}
if ($workspace != null) {
$smarty->assign('PAGE_TITLE', $workspace->name);
$template = "home_workspace.tpl";
if (count($workspace->configuration->disclaimers)) {
$disclaimers = [];
foreach ($workspace->configuration->disclaimers as $disclaimer) {
$disclaimers[] = Disclaimer::get($disclaimer);
}
$smarty->assign('disclaimers', $disclaimers);
}
}
//Serves header
HeaderController::run($this->context);
//Serves relevant template
$smarty->display($template);
//Serves footer
FooterController::run($this->context);
}
}
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index b067b2d..3f8151a 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -1,457 +1,328 @@
<?php
////////////////////////////////////////////////////////////////////////////////
/// ///
/// 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;
$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;
$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");
}
/**
* Gets the resource ID from an identifier
*
* @param $resource_type the resource type
* @param $identifier resource identifier
* @return mixed the resource ID (as integer), or NULL if unknown
*/
function get_resource_id ($resource_type, $identifier) {
//Trivial cases: already an ID, null or void ID
if (is_numeric($identifier)) {
return $identifier;
}
if (!$identifier) {
return NULL;
}
//Searches identifier
switch ($resource_type) {
case 'U':
return get_user_id($identifier);
case 'G':
$group = UserGroup::fromCode($identifier);
return $group->id;
case 'W':
$workspace = Workspace::fromCode($identifier);
return $workspace->id;
default:
throw new Exception("Unknown resource type: $resource_type", E_USER_ERROR);
}
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// 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;
}
/**
* Gets file extension
* @param string $file the file to get the extension
* @return string the file extension
*/
function get_extension ($file) {
$dotPosition = strrpos($file, ".");
return substr($file, $dotPosition + 1);
}
/**
* Gets file name
* @param string $file the file to get the extension
* @return string the file name
*/
function get_filename ($file) {
//TODO: clear directory
$dotPosition = strrpos($file, ".");
return substr($file, 0, $dotPosition);
}
/*
* 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;
}
-////////////////////////////////////////////////////////////////////////////////
-/// ///
-/// Localization (l10n) ///
-/// ///
-////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Defines the LANG constant, to lang to print
- *
- * This information is contained in the session, or if not yet defined,
- * it's to determine according the user's browser preferences.
- * @see find_lang
- */
-function initialize_lang () {
- //If $_SESSION['lang'] doesn't exist yet, find a common language
- if (!array_key_exists('lang', $_SESSION)) {
- $lang = find_lang();
- $_SESSION['lang'] = $lang ? $lang : '-';
- }
-
- if ($_SESSION['lang'] != '-')
- define('LANG', $_SESSION['lang']);
-}
-
-/**
- * Gets a common lang spoken by the site and the user's browser
- * @see get_http_accept_languages
- *
- * @return string the language
- */
-function find_lang () {
- if (file_exists('lang') && is_dir('lang')) {
- //Gets lang/ subdirectories: this is the list of available languages
- $handle = opendir('lang');
- while ($file = readdir($handle)) {
- if ($file != '.' && $file != '..' && is_dir("lang/$file")) {
- $langs[] = $file;
- }
- }
-
- //The array $langs contains now the language available.
- //Gets the langs the user should want:
- if (!$userlangs = get_http_accept_languages())
- return;
-
- //Gets the intersection between the both languages arrays
- //If it matches, returns first result
- $intersect = array_intersect($userlangs, $langs);
- if (count($intersect)) {
- return $intersect[0];
- }
-
- //Now it's okay with Opera and Firefox but Internet Explorer will
- //by default return en-US and not en or fr-BE and not fr, so second pass
- foreach ($userlangs as $userlang) {
- $lang = explode('-', $userlang);
- if (count($lang) > 1)
- $userlangs2[] = $lang[0];
- }
- $intersect = array_intersect($userlangs2, $langs);
- if (count($intersect)) {
- return $intersect[0];
- }
- }
-}
-
-/**
- * Gets the languages accepted by the browser, by order of priority.
- *
- * This will read the HTTP_ACCEPT_LANGUAGE variable sent by the browser in the
- * HTTP request.
- *
- * @return Array an array of string, each item a language accepted by browser
- */
-function get_http_accept_languages () {
- //What language to print is sent by browser in HTTP_ACCEPT_LANGUAGE var.
- //This will be something like en,fr;q=0.8,fr-fr;q=0.5,en-us;q=0.3
-
- if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
- return null;
- }
-
- $http_accept_language = explode(',', $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
- foreach ($http_accept_language as $language) {
- $userlang = explode(';q=', $language);
- if (count($userlang) == 1) {
- $userlangs[] = array(1, $language);
- } else {
- $userlangs[] = array($userlang[1], $userlang[0]);
- }
- }
- rsort($userlangs);
- foreach ($userlangs as $userlang) {
- $result[] = $userlang[1];
- }
- return $result;
-}
-
-/**
- * Loads specified language Smarty configuration file
- *
- * @param string $file the file to load
- * @param mixed $sections array of section names, single section or null
- */
-function lang_load ($file, $sections = null) {
- global $smarty;
-
- //Loads English file as fallback if some parameters are missing
- if (file_exists("lang/en/$file"))
- $smarty->configLoad("lang/en/$file", $sections);
-
- //Loads wanted file (if it exists and a language have been defined)
- if (defined('LANG') && LANG != 'en' && file_exists('lang/' . LANG . '/' . $file))
- $smarty->configLoad('lang/' . LANG . '/' . $file, $sections);
-}
-
-/**
- * Gets a specified language expression defined in configuration file
- *
- * @param string $key the configuration key matching the value to get
- * @return string The value in the configuration file
- */
-function lang_get ($key) {
- global $smarty;
-
- $smartyConfValue = $smarty->config_vars[$key];
- return $smartyConfValue ? $smartyConfValue : "#$key#";
-}
-
////////////////////////////////////////////////////////////////////////////////
/// ///
/// 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");
}
if (array_key_exists('REDIRECT_URL', $_SERVER)) {
//With mod_rewrite, we can use REDIRECT_URL
//We takes the end of the URL, ie *FROM* $len position
return substr(get_server_url() . $_SERVER["REDIRECT_URL"], $len);
}
//Last possibility: use REQUEST_URI, but remove QUERY_STRING
//If you need to edit here, use $_SERVER['REQUEST_URI']
//but you need to discard $_SERVER['QUERY_STRING']
//We takes the end of the URL, ie *FROM* $len position
$url = substr(get_server_url() . $_SERVER["REQUEST_URI"], $len);
//But if there are a query string (?action=... we need to discard it)
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));
}
////////////////////////////////////////////////////////////////////////////////
/// ///
/// 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/auth/AuthenticationMethod.php b/includes/auth/AuthenticationMethod.php
index 030915e..bbe0cda 100644
--- a/includes/auth/AuthenticationMethod.php
+++ b/includes/auth/AuthenticationMethod.php
@@ -1,241 +1,241 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Authentication method class
*
* @package ObsidianWorkspaces
* @subpackage Auth
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
/**
* Authentication method class
*
* This class has to be extended to implement custom authentication methods.
*/
abstract class AuthenticationMethod implements ObjectDeserializable {
/**
* @var User The local user matching the authentication
*/
public $localUser;
/**
* @var string The username
*/
public $name;
/**
* @var string The e-mail address
*/
public $email;
/**
* @var string The authentication method identifiant
*/
public $id;
/**
* @var string The remote identity provider user identifiant
*/
public $remoteUserId;
/**
* @var Message The localized authentication login message
*/
public $loginMessage;
/**
* @var boolean Determines if the authentication method could be used to register new users
*/
public $canCreateUser = false;
/**
* @var Array Actions to execute if an user is created, eacth instance a member of UserAction
*/
public $createUserActions = [];
/**
* @var Context The site context
*/
public $context;
/**
* @var Message The localized authentication error message
*/
public $loginError;
/**
* Gets authentication link for this method
*/
public abstract function getAuthenticationLink();
/**
* Handles request
*/
public abstract function handleRequest();
/**
* Runs actions planned on user create
*/
protected function runCreateUserActions () {
foreach ($this->createUserActions as $action) {
$action->targetUser = $this->localUser;
$action->run();
}
}
/**
* Finds user from available data
*
* @return User the user if an user has been found; otherwise, false.
*/
private function findUser () {
if ($this->remoteUserId != '') {
$user = User::getUserFromRemoteIdentity(
$this->id, $this->remoteUserId
);
if ($user !== null) return $user;
}
if ($this->email != '') {
$user = User::get_user_from_email($this->email);
if ($user !== null) return $user;
}
return null;
}
/**
* Signs in or creates a new user
*
* @return boolean true if user has been successfully logged in; otherwise, false.
*/
public function signInOrCreateUser () {
// At this stage, if we don't already have an user instance,
// we're fetching it by remote user id or mail.
//
// If no result is returned, we're creating a new user if needed.
//
// Finally, we proceed to log in.
if ($this->localUser === null) {
$this->localUser = $this->findUser();
}
if ($this->localUser === null) {
if (!$this->canCreateUser) {
- $this->loginError = lang_get("ExternalLoginCantCreateAccount");
+ $this->loginError = Language::get("ExternalLoginCantCreateAccount");
return false;
} else {
$this->createUser();
if ($this->localUser === null) {
throw new Exception("Can't sign in: after correct remote authentication, an error occured creating locally a new user.");
}
}
}
$this->signIn($this->localUser);
return true;
}
/**
* Signs in the specified user
*
* @param User The user to log in
*/
public function signIn(User $user) {
$this->context->session->user_login($user->id);
}
/**
* Creates a new user based on the authentication provisionning information
*
* @return User The user created
*/
public function createUser () {
if (!$this->canCreateUser) {
throw new Exception("Can't create user: the canCreateUser property is set at false.");
}
$user = User::create();
$user->name = $this->name;
$user->email = $this->email;
$user->save_to_database();
$user->setRemoteIdentity(
$this->id, $this->remoteUserId
);
$this->localUser = $user;
$this->runCreateUserActions();
}
/**
* Gets authentication method from ID
*
* @param string $id The authentication method id
* @param Context $context The site context
* @return AuthenticationMethod The authentication method matching the id
*/
public static function getFromId ($id, $context) {
if ($context->workspace != null) {
foreach ($context->workspace->configuration->authenticationMethods as $authenticationMethod) {
if ($authenticationMethod->id == $id) {
return $authenticationMethod;
}
}
}
return null;
}
/**
* Loads a AuthenticationMethod instance from a generic object. Typically used to deserialize a JSON document.
*
* @param object $data The object to deserialize
* @return AuthenticationMethod The deserialized instance
*/
public static function loadFromObject ($data) {
$instance = new static;
if (!property_exists($data, 'id')) {
throw new InvalidArgumentException("Authentication method id is required.");
}
$instance->id = $data->id;
if (property_exists($data, 'loginMessage')) {
$instance->loginMessage = new Message($data->loginMessage);
} else {
- $instance->loginMessage = new Message(lang_get("SignIn"));
+ $instance->loginMessage = new Message(Language::get("SignIn"));
}
if (property_exists($data, 'createUser')) {
if (property_exists($data->createUser, 'enabled')) {
$instance->canCreateUser = ($data->createUser->enabled == true);
}
if (property_exists($data->createUser, 'addToGroups')) {
foreach ($data->createUser->addToGroups as $actionData) {
$instance->createUserActions[] = AddToGroupUserAction::loadFromObject($actionData);
}
}
if (property_exists($data->createUser, 'givePermissions')) {
foreach ($data->createUser->givePermissions as $actionData) {
$instance->createUserActions[] = GivePermissionUserAction::loadFromObject($actionData);
}
}
}
return $instance;
}
}
diff --git a/includes/auth/AzharProvider.php b/includes/auth/AzharProvider.php
index 2049061..c9ed916 100644
--- a/includes/auth/AzharProvider.php
+++ b/includes/auth/AzharProvider.php
@@ -1,205 +1,205 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Azhàr provider authentication method class
*
* @package ObsidianWorkspaces
* @subpackage Auth
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
/**
* Azhàr provider authentication method class
*
* Azhàr sends a document providing authentication and registration of new users.
* It's signed by a shared secret key.
*/
class AzharProvider extends AuthenticationMethod {
/**
* @var string Shared secret key
*/
public $secretKey;
/**
* @var string Client key, to identify the consumer application.
*/
public $clientKey;
/**
* @var string The Azhàr identity provider login URL
*/
public $url;
/**
* Handles user login request
*/
public function handleRequest () {
$action = array_key_exists('action', $_GET) ? $_GET['action'] : '';
$sessionKey = array_key_exists('sessionKey', $_GET) ? $GET['sessionKey'] : '';
if ($action == "user.login.azhar.initialize") {
//Redirects user to Azhàr SSO service
$callbackUrl = get_server_url() . get_url($this->context->workspace->code)
. '?action=user.login.azhar.success&authenticationMethodId=' . $this->id;
$url = $this->url . '?mode=provider&key=' . $this->clientKey
. '&sessionKey=' . $this->getSessionKey()
. '&url=' . urlencode($callbackUrl);
header('Location: ' . $url);
exit;
} elseif ($action == "user.login.azhar.success") {
//User claims to have logged in, we can get authentication information
$reply = $this->fetchInformation();
if (!$this->isDocumentLegit($reply)) {
- $this ->loginError = lang_get('ExternalLoginNotLegitReply');
+ $this ->loginError = Language::get('ExternalLoginNotLegitReply');
return;
}
if ($reply->status == "SUCCESS") {
//Creates user or login
$this->name = $reply->username;
$this->email = $reply->email;
$this->remoteUserId = $reply->localUserId;
$this->signInOrCreateUser();
return;
} elseif ($reply->status == "ERROR_USER_SIDE") {
switch ($reply->code) {
case 'NO_USER_VISIT':
case 'NOT_LOGGED_IN':
- $this ->loginError = lang_get('ExternalLoginNotRemotelyLoggedIn');
+ $this ->loginError = Language::get('ExternalLoginNotRemotelyLoggedIn');
return;
}
} elseif ($reply->status == "ERROR_BETWEEN_US") {
switch ($reply->code) {
case 'SESSION_BADSECRET':
- $this->loginError = sprintf(lang_get('ExternalLoginTechnicalDifficulty'), $reply->code);
+ $this->loginError = sprintf(Language::get('ExternalLoginTechnicalDifficulty'), $reply->code);
return;
}
}
$this->loginError = '<p>An unknown error has been received:</p><pre>' . print_r($reply, true) . '</pre><p>Please notify technical support about this new error message, so we can handle it in the future.</p>';
} else {
$this ->loginError = '<p>Unknown action: $action</p>';
}
}
/**
* Gets Azhàr provider session key
*
* This key allows us as consumer to fetch information, and Azhàr as provider to store it.
*
* @return string the session key
*/
public function getSessionKey () {
$hash = md5($this->id);
if (!isset($_SESSION['Auth-$hash']['SessionKey'])) {
$url = $this->url . '?mode=provider.announce&key=' . $this->clientKey
. '&url=n/a';
$reply = self::query($url);
$this->setSessionSecret($reply->sessionSecret);
$_SESSION['Auth-$hash']['SessionKey'] = $reply->sessionKey;
}
return $_SESSION['Auth-$hash']['SessionKey'];
}
/**
* Gets Azhàr provider session secret
*
* @return string the session secret
*/
private function getSessionSecret () {
$hash = md5($this->id);
return $_SESSION['Auth-$hash']['SessionSecret'];
}
/**
* Sets Azhàr provider session secret
*
* @param string $secret the session secret
*/
private function setSessionSecret ($secret) {
$hash = md5($this->id);
$_SESSION['Auth-$hash']['SessionSecret'] = $secret;
}
/**
* Gets Azhàr external authentication link
*
* @retrun string the login link
*/
public function getAuthenticationLink() {
$url = get_server_url() . get_url($this->context->workspace->code)
. '?action=user.login.azhar.initialize&authenticationMethodId=' . $this->id;
return $url;
}
/**
* Determines if the document received has been signed by the correct shared secret key.
*
* @return boolean true if the document is legit; otherwise, false.
*/
function isDocumentLegit ($document) {
$hash = '';
$claimedHash = NULL;
foreach ($document as $key => $value) {
if ($key == 'hash') {
$claimedHash = $value;
continue;
}
$hash .= md5($key . $value);
}
$salt = '$2y$10$' . substr($this->secretKey, 0, 22);
$computedHash = crypt($hash, $salt);
return $claimedHash === $computedHash;
}
/**
* Fetches information document
*
* @return stdClass The Azhàr identity provider information about the current login operation
*/
function fetchInformation () {
$url = $this->url . '?mode=provider.fetch&key=' . $this->clientKey
. '&sessionSecret=' . $this->getSessionSecret()
. '&sessionKey=' . $this->getSessionKey()
. '&url=n/a';
return self::query($url);
}
/**
* Gets the contents of the specified URL and decode the JSON reply
*
* @param string $url The URL to the JSON document to query.
* @return stdClass The reply
*/
public static function query ($url) {
$data = file_get_contents($url);
return json_decode($data);
}
/**
* Loads a AzharProvider instance from a generic object. Typically used to deserialize a JSON document.
*
* @param object $data The object to deserialize
* @return AzharProvider The deserialized instance
*/
public static function loadFromObject ($data) {
$instance = parent::loadFromObject($data);
$instance->url = $data->url;
$instance->secretKey = $data->secretKey;
$instance->clientKey = $data->clientKey;
return $instance;
}
}
diff --git a/includes/autoload.php b/includes/autoload.php
index 66e526e..fe2ed68 100644
--- a/includes/autoload.php
+++ b/includes/autoload.php
@@ -1,91 +1,92 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Classes and interfaces auto loader
*
* @package ObsidianWorkspaces
* @filesource
*/
/**
* This SPL autoloader method is called when a class or an interface can't be loaded.
*/
function obsidian_autoload ($name) {
$dir = dirname(__DIR__);
///
/// Applications
///
if ($name == 'DocumentsApplication') { require $dir . '/apps/documents/DocumentsApplication.php'; return true; }
if ($name == 'DocumentsApplicationConfiguration') { require $dir . '/apps/documents/DocumentsApplicationConfiguration.php'; return true; }
if ($name == 'HelloWorldApplication') { require $dir . '/apps/helloworld/HelloWorldApplication.php'; return true; }
if ($name == 'MediaWikiMirrorApplication') { require $dir . '/apps/mediawikimirror/MediaWikiMirrorApplication.php'; return true; }
if ($name == 'MediaWikiMirrorApplicationConfiguration') { require $dir . '/apps/mediawikimirror/MediaWikiMirrorApplicationConfiguration.php'; return true; }
if ($name == 'StaticContentApplication') { require $dir . '/apps/staticcontent/StaticContentApplication.php'; return true; }
if ($name == 'StaticContentApplicationConfiguration') { require $dir . '/apps/staticcontent/StaticContentApplicationConfiguration.php'; return true; }
///
/// Core controllers
///
if ($name == 'ErrorPageController') { require $dir . '/controllers/errorpage.php'; return true; }
if ($name == 'FooterController') { require $dir . '/controllers/footer.php'; return true; }
if ($name == 'HeaderController') { require $dir . '/controllers/header.php'; return true; }
if ($name == 'HomepageController') { require $dir . '/controllers/home.php'; return true; }
///
/// Keruald and Obsidian Workspaces libraries
///
if ($name == 'LoadableWithContext') { require $dir . '/includes/LoadableWithContext.php'; return true; }
if ($name == 'ObjectDeserializable') { require $dir . '/includes/ObjectDeserializable.php'; return true; }
if ($name == 'ObjectDeserializableWithContext') { require $dir . '/includes/ObjectDeserializable.php'; return true; }
if ($name == 'Application') { require $dir . '/includes/apps/Application.php'; return true; }
if ($name == 'ApplicationConfiguration') { require $dir . '/includes/apps/ApplicationConfiguration.php'; return true; }
if ($name == 'ApplicationContext') { require $dir . '/includes/apps/ApplicationContext.php'; return true; }
if ($name == 'AddToGroupUserAction') { require $dir . '/includes/auth/AddToGroupUserAction.php'; return true; }
if ($name == 'AuthenticationMethod') { require $dir . '/includes/auth/AuthenticationMethod.php'; return true; }
if ($name == 'AzharProvider') { require $dir . '/includes/auth/AzharProvider.php'; return true; }
if ($name == 'GivePermissionUserAction') { require $dir . '/includes/auth/GivePermissionUserAction.php'; return true; }
if ($name == 'UserAction') { require $dir . '/includes/auth/UserAction.php'; return true; }
if ($name == 'Cache') { require $dir . '/includes/cache/cache.php'; return true; }
if ($name == 'CacheMemcached') { require $dir . '/includes/cache/memcached.php'; return true; }
if ($name == 'CacheVoid') { require $dir . '/includes/cache/void.php'; return true; }
if ($name == 'Collection') { require $dir . '/includes/collection/Collection.php'; return true; }
if ($name == 'CollectionDocument') { require $dir . '/includes/collection/CollectionDocument.php'; return true; }
if ($name == 'FilesCollection') { require $dir . '/includes/collection/FilesCollection.php'; return true; }
if ($name == 'MongoDBCollection') { require $dir . '/includes/collection/MongoDBCollection.php'; return true; }
if ($name == 'MongoDBCollectionIterator') { require $dir . '/includes/collection/MongoDBCollectionIterator.php'; return true; }
if ($name == 'Context') { require $dir . '/includes/controller/Context.php'; return true; }
if ($name == 'Controller') { require $dir . '/includes/controller/Controller.php'; return true; }
if ($name == 'RunnableWithContext') { require $dir . '/includes/controller/RunnableWithContext.php'; return true; }
+ if ($name == 'Language') { require $dir . '/includes/i18n/Language.php'; return true; }
if ($name == 'Message') { require $dir . '/includes/i18n/Message.php'; return true; }
if ($name == 'TextFileMessage') { require $dir . '/includes/i18n/TextFileMessage.php'; return true; }
if ($name == 'Disclaimer') { require $dir . '/includes/objects/Disclaimer.php'; return true; }
if ($name == 'Permission') { require $dir . '/includes/objects/Permission.php'; return true; }
if ($name == 'User') { require $dir . '/includes/objects/user.php'; return true; }
if ($name == 'UserGroup') { require $dir . '/includes/objects/usergroup.php'; return true; }
if ($name == 'Workspace') { require $dir . '/includes/workspaces/Workspace.php'; return true; }
if ($name == 'WorkspaceConfiguration') { require $dir . '/includes/workspaces/WorkspaceConfiguration.php'; return true; }
return false;
}
spl_autoload_register('obsidian_autoload');
diff --git a/includes/controller/Context.php b/includes/controller/Context.php
index 2e57c9e..d0db197 100644
--- a/includes/controller/Context.php
+++ b/includes/controller/Context.php
@@ -1,48 +1,90 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Application context class
*
* @package ObsidianWorkspaces
* @subpackage Controller
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
/**
* Context class
*
* This class describes the site context.
*/
class Context {
/**
* @var WorkSpace the workspace currently enabled
*/
public $workspace;
+ /**
+ * @var array the configuration
+ */
+ public $config;
+
/**
* @var User the user currently logged in
*/
public $user;
/**
* @var Session the current session
*/
public $session;
/**
* @var Array the URL fragments
*/
public $url;
/**
* @var Smarty the template engine
*/
public $templateEngine;
+
+ ///
+ /// Helper methods
+ ///
+
+ /**
+ * Gets application root directory
+ *
+ * @return string the application root directory
+ */
+ public function getApplicationRootDirectory() {
+ return getcwd();
+ }
+
+ ///
+ /// Templates
+ ///
+
+ /**
+ * Initializes the template engine
+ */
+ public function initializeTemplateEngine () {
+ require('includes/smarty/Smarty.class.php');
+ define('SMARTY_SPL_AUTOLOAD', 1);
+
+ $smarty = new Smarty();
+
+ $current_dir = static::getApplicationRootDirectory();
+ $smarty->template_dir = $current_dir . '/skins/' . THEME;
+ $smarty->cache_dir = $this->config['Content']['Cache'];
+ $smarty->compile_dir = $smarty->cache_dir . '/compiled';
+ $smarty->config_dir = $current_dir;
+
+ $smarty->config_vars['StaticContentURL'] = $this->config['StaticContentURL'];
+
+ $this->templateEngine = $smarty;
+ }
}
diff --git a/includes/i18n/Language.php b/includes/i18n/Language.php
new file mode 100644
index 0000000..1edaff1
--- /dev/null
+++ b/includes/i18n/Language.php
@@ -0,0 +1,223 @@
+<?php
+
+/**
+ * _, __, _, _ __, _ _, _, _
+ * / \ |_) (_ | | \ | /_\ |\ |
+ * \ / |_) , ) | |_/ | | | | \|
+ * ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+ *
+ * Localization (l10n) language class
+ *
+ * @package ObsidianWorkspaces
+ * @subpackage I18n
+ * @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
+ * @filesource
+ */
+
+/**
+ * Gets a specified language expression defined in configuration file
+ *
+ * @param string $key the configuration key matching the value to get
+ * @return string The value in the configuration file
+ * @deprecated
+ */
+function lang_get ($key) {
+ trigger_error("The use of the L10n global functions is deprecated. Call Language::get('$key') instead.", E_USER_DEPRECATED);
+ return Language::get($key);
+}
+
+/**
+ * Language services
+ */
+class Language implements LoadableWithContext {
+ ///
+ /// Properties
+ ///
+
+ /**
+ * @var
+ */
+ const FALLBACK = 'en';
+
+ /**
+ * @var Smarty the template engine
+ */
+ private $templateEngine;
+
+ ///
+ /// Singleton pattern. Constructor.
+ ///
+
+ /**
+ * @var Language The loaded Language instance
+ */
+ private static $instance;
+
+ /**
+ * Loads an instance of the class
+ *
+ * @param Context $context The context
+ * @return Language An instance of the Language class
+ */
+ public static function Load (Context $context = null) {
+ if (static::$instance === null) {
+ //Initializes an instance
+ if ($context === null) {
+ throw new InvalidArgumentException("A context is required to load this class for the first time.");
+ }
+
+ if ($context->templateEngine === null) {
+ throw new InvalidArgumentException("A context is required to load this class for the first time. You provided one, but the template engine isn't initiliazed. This is required, as the languages files are managed by the template engine.");
+ }
+
+ static::$instance = new static($context->templateEngine);
+ }
+
+ return static::$instance;
+ }
+
+ /**
+ * Initializes a new instance of the Language class
+ */
+ public function __construct ($templateEngine) {
+ $this->templateEngine = $templateEngine;
+ }
+
+ ///
+ /// Static helper methods
+ ///
+
+ /**
+ * Defines the LANG constant, to lang to print
+ *
+ * This information is contained in the session, or if not yet defined,
+ * it's to determine according the user's browser preferences.
+ * @see find_lang
+ */
+ public static function initialize () {
+ //If $_SESSION['lang'] doesn't exist yet, find a common language
+ if (!array_key_exists('lang', $_SESSION)) {
+ $lang = static::findLanguage();
+ $_SESSION['lang'] = $lang ? $lang : '-';
+ }
+
+ if ($_SESSION['lang'] != '-') {
+ define('LANG', $_SESSION['lang']);
+ }
+ }
+
+ /**
+ * Gets a common lang spoken by the site and the user's browser
+ * @see Language::get_http_accept_languages
+ *
+ * @return string the language
+ */
+ public static function findLanguage () {
+ if (file_exists('lang') && is_dir('lang')) {
+ //Gets lang/ subdirectories: this is the list of available languages
+ $handle = opendir('lang');
+ while ($file = readdir($handle)) {
+ if ($file != '.' && $file != '..' && is_dir("lang/$file")) {
+ $langs[] = $file;
+ }
+ }
+
+ //The array $langs contains now the language available.
+ //Gets the langs the user should want:
+ if (!$userlangs = static::getHttpAcceptLanguages())
+ return;
+
+ //Gets the intersection between the both languages arrays
+ //If it matches, returns first result
+ $intersect = array_intersect($userlangs, $langs);
+ if (count($intersect)) {
+ return $intersect[0];
+ }
+
+ //Now it's okay with Opera and Firefox but Internet Explorer will
+ //by default return en-US and not en or fr-BE and not fr, so second pass
+ foreach ($userlangs as $userlang) {
+ $lang = explode('-', $userlang);
+ if (count($lang) > 1)
+ $userlangs2[] = $lang[0];
+ }
+ $intersect = array_intersect($userlangs2, $langs);
+ if (count($intersect)) {
+ return $intersect[0];
+ }
+ }
+ }
+
+ /**
+ * Gets the languages accepted by the browser, by order of priority.
+ *
+ * This will read the HTTP_ACCEPT_LANGUAGE variable sent by the browser in the
+ * HTTP request.
+ *
+ * @return Array an array of string, each item a language accepted by browser
+ */
+ public static function getHttpAcceptLanguages () {
+ //What language to print is sent by browser in HTTP_ACCEPT_LANGUAGE var.
+ //This will be something like en,fr;q=0.8,fr-fr;q=0.5,en-us;q=0.3
+
+ if (!isset($_SERVER) || !array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
+ return null;
+ }
+
+ $http_accept_language = explode(',', $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
+ foreach ($http_accept_language as $language) {
+ $userlang = explode(';q=', $language);
+ if (count($userlang) == 1) {
+ $userlangs[] = array(1, $language);
+ } else {
+ $userlangs[] = array($userlang[1], $userlang[0]);
+ }
+ }
+ rsort($userlangs);
+ foreach ($userlangs as $userlang) {
+ $result[] = $userlang[1];
+ }
+ return $result;
+ }
+
+ public static function get ($key) {
+ return static::load()->getConfigVar($key);
+ }
+
+ ///
+ /// Methods
+ ///
+
+ /**
+ * Loads specified language Smarty configuration file
+ *
+ * @param Smarty $templateEngine the template engine
+ * @param string $file the file to load
+ * @param mixed $sections array of section names, single section or null
+ */
+ public function configLoad ($file, $sections = null) {
+ $fallback = static::FALLBACK;
+
+ //Loads English file as fallback if some parameters are missing
+ if (file_exists("lang/$fallback/$file")) {
+ $this->templateEngine->configLoad("lang/$fallback/$file", $sections);
+ }
+
+ //Loads wanted file (if it exists and a language have been defined)
+ if (defined('LANG') && LANG != '$fallback' && file_exists('lang/' . LANG . '/' . $file)) {
+ $smarty->configLoad('lang/' . LANG . '/' . $file, $sections);
+ }
+ }
+
+ /**
+ * Gets a specified language expression defined in configuration file
+ *
+ * @param string $key the configuration key matching the value to get
+ * @return string The value in the configuration file
+ */
+ private function getConfigVar ($key) {
+ $configValue = $this->templateEngine->config_vars[$key];
+ return $configValue ? $configValue : "#$key#";
+ }
+}
diff --git a/includes/i18n/Message.php b/includes/i18n/Message.php
index 7f551cd..5af2f12 100644
--- a/includes/i18n/Message.php
+++ b/includes/i18n/Message.php
@@ -1,71 +1,69 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Message class
*
* @package ObsidianWorkspaces
* @subpackage I18n
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*/
-define('MESSAGE_FALLBACK_LANG', 'en');
-
/**
* Represents a localizable message
*/
class Message {
/**
* @var Array the localized message
*/
public $localizations = [];
/**
* Initializes a new instance of the Message class
*
* @param mixed $expression unique string or localizations Array
*/
public function __construct ($expression) {
if (is_array($expression)) {
if (count($expression) && is_array($expression[0])) {
foreach ($expression as $msg) {
$this->localizations[$msg[0]] = $msg[1];
}
} else {
$this->localizations = $expression;
}
} elseif (is_string($expression)) {
$this->localizations = [
- MESSAGE_FALLBACK_LANG => $expression
+ Language::FALLBACK => $expression
];
} else {
throw new Exception("Expression must be a string or a l10n array");
}
}
/**
* Gets a string representation of the message
*
* @return string The message string representation
*/
public function __toString () {
if (!count($this->localizations)) {
return "";
}
if (!defined('LANG') || !array_key_exists(LANG, $this->localizations)) {
- if (array_key_exists(MESSAGE_FALLBACK_LANG, $this->localizations)) {
- return $this->localizations[MESSAGE_FALLBACK_LANG];
+ if (array_key_exists(Language::FALLBACK, $this->localizations)) {
+ return $this->localizations[Language::FALLBACK];
}
return array_values($this->localizations)[0];
}
return $this->localizations[LANG];
}
}
diff --git a/includes/objects/Disclaimer.php b/includes/objects/Disclaimer.php
index 6fa6e35..6ddec2a 100644
--- a/includes/objects/Disclaimer.php
+++ b/includes/objects/Disclaimer.php
@@ -1,58 +1,58 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Disclaimer class
*
* @package ObsidianWorkspaces
* @subpackage Model
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*
*/
/**
* Disclaimer class
*/
class Disclaimer {
public $id;
public $title;
public $text;
public function __construct ($id) {
$this->id = $id;
}
public static function get ($id) {
global $Config;
$instance = new Disclaimer($id);
try {
$message = new TextFileMessage(
$Config['Content']['Disclaimers'],
$id
);
$data = (string)$message;
$pos = strpos($data, "\n");
if ($pos !== false) {
$instance->title = substr($data, 0, $pos);
$instance->text = trim(substr($data, $pos));
} else {
$instance->title = ucfirst($id);
$instance->text = $data;
}
} catch (Exception $ex) {
$instance->title = ucfirst($id);
- $instance->text = lang_get('NoSuchDisclaimer');
+ $instance->text = Language::get('NoSuchDisclaimer');
}
return $instance;
}
}
\ No newline at end of file
diff --git a/index.php b/index.php
index a66ece0..21452d4 100755
--- a/index.php
+++ b/index.php
@@ -1,114 +1,103 @@
<?php
/**
* _, __, _, _ __, _ _, _, _
* / \ |_) (_ | | \ | /_\ |\ |
* \ / |_) , ) | |_/ | | | | \|
* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
*
* Main web application entry point
*
* @package ObsidianWorkspaces
* @subpackage Controllers
* @author Sébastien Santoro aka Dereckson <dereckson@espace-win.org>
* @license http://www.opensource.org/licenses/bsd-license.php BSD
* @filesource
*
*/
////////////////////////////////////////////////////////////////////////////////
///
/// Initialization
///
//Keruald and Obsidian Workspaces libraries
include('includes/core.php');
$session = Session::load();
////////////////////////////////////////////////////////////////////////////////
///
/// Template/L10n engine
///
define('THEME', 'bluegray');
-require('includes/smarty/Smarty.class.php');
-define('SMARTY_SPL_AUTOLOAD', 1);
-
-$smarty = new Smarty();
-$current_dir = dirname(__FILE__);
-$smarty->template_dir = $current_dir . '/skins/' . THEME;
-
-$smarty->compile_dir = $Config['Content']['Cache'] . '/compiled';
-$smarty->cache_dir = $Config['Content']['Cache'];
-$smarty->config_dir = $current_dir;
-
-$smarty->config_vars['StaticContentURL'] = $Config['StaticContentURL'];
-
-//Loads language files
-initialize_lang();
-lang_load('core.conf');
-
////////////////////////////////////////////////////////////////////////////////
///
/// Session and context
///
//Prepares the site context
$context = new ApplicationContext();
$context->session = $session;;
$context->url = get_current_url_fragments();
-$context->templateEngine = $smarty;
+$context->config = $Config;
+$context->initializeTemplateEngine();
+
+//Loads language files
+$smarty = $context->templateEngine;
+Language::initialize();
+Language::load($context)->configLoad('core.conf');
if (Workspace::is_workspace($context->url[0])) {
$context->workspace = Workspace::fromCode(array_shift($context->url));
$context->workspace->loadConfiguration($context);
}
//Handles login or logout
include("includes/login.php");
//Gets current user information
$context->user = $context->session->get_logged_user();
////////////////////////////////////////////////////////////////////////////////
///
/// Serves the requested page
///
//If the user isn't logged in (is anonymous), prints login/invite page & dies.
if ($context->user->id == ANONYMOUS_USER) {
//Anonymous user
include('controllers/anonymous.php');
exit;
}
switch ($controller = $context->url[0]) {
case '':
//Calls homepage controller
HomepageController::run($context);
break;
case 'help':
case 'reports':
//Calls requested controller
include("controllers/$controller.php");
break;
default:
//Current workspace application controller?
$workspaceConfig = $context->workspace->configuration;
$applicationConfiguration = NULL;
if ($workspaceConfig != NULL && $workspaceConfig->hasControllerBind($controller, $applicationConfiguration)) {
//Runs controller
$controllerClass = $applicationConfiguration->name;
$appContext = ApplicationContext::loadFromContext($context, $applicationConfiguration);
$controllerClass::run($appContext);
break;
}
//Not a workspace, nor a controller toponomy
ErrorPageController::show($context, 404);
exit;
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, May 3, 05:50 (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3677699
Default Alt Text
(66 KB)

Event Timeline