wootook-reloaded/application/code/core/Wootook.php
Gregory PLANCHAT 66805034a6 Configuration & Layout architecture updates
Fixed production bug
Fixed styles
Updated Action Controller

Signed-off-by: Gregory PLANCHAT <g.planchat@gmail.com>
2012-01-13 23:36:03 +01:00

765 lines
No EOL
23 KiB
PHP

<?php
/**
* This file is part of Wootook
*
* @license http://www.gnu.org/licenses/agpl-3.0.txt
* @see http://www.wootook.com/
*
* Copyright (c) 2011-Present, Grégory PLANCHAT <g.planchat@gmail.com>
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --> NOTICE <--
* This file is part of the core development branch, changing its contents will
* make you unable to use the automatic updates manager. Please refer to the
* documentation for further information about customizing Wootook.
*
*/
/**
* Bootstrap class, used to access main and global functionalities
*
* @package Wootook
* @category core
*/
class Wootook
{
/**
* Static list of application event listeners
*
* @var array
*/
private static $_listeners = array();
/**
* Static list of all locale translators
*
* @var array
*/
private static $_translators = array();
/**
* HTTP request management object
*
* @var Legacies_Core_Controller_Request_Http
*/
private static $_request = null;
/**
* HTTP response management object
*
* @var Legacies_Core_Controller_Response
*/
private static $_response = null;
/**
* The current timestamp
*
* @var int
*/
private static $_now = null;
/**
* Default locale identifier
*
* @var string
*/
private static $_defaultLocale = 'fr_FR';
/**
*
* Enter description here ...
* @var Wootook_Core_Config_Adapter_Abstract
*/
private static $_config = null;
/**
*
* Enter description here ...
* @var Wootook_Core_Config_Adapter_Abstract
*/
private static $_globalConfig = null;
/**
*
* Enter description here ...
* @var array
*/
private static $_websiteConfigs = array();
/**
*
* Enter description here ...
* @var array
*/
private static $_gameConfigs = array();
/**
*
* Enter description here ...
* @var array
*/
private static $_ignoreDatabaseConfig = false;
private static $_defaultWebsite = null;
private static $_defaultGame = null;
private static $_websitesById = array();
private static $_websitesByCode = array();
private static $_gamesById = array();
private static $_gamesByCode = array();
public static $isInstalled = true;
/**
* Registers an event listener to be called later in the application.
*
* @param string $event The event identifier
* @param callback $listener The event callback to be called
*/
public static function registerListener($event, $listener)
{
if (!isset(self::$_listeners[$event])) {
self::$_listeners[$event] = array();
}
self::$_listeners[$event][] = $listener;
}
/**
* Clear all event listeners
*/
public static function clearAllListeners()
{
self::$_listeners = array();
}
/**
* Clear a specific event's listeners
*
* @param unknown_type $event
*/
public static function clearEventListeners($event)
{
if (isset(self::$_listeners[$event])) {
self::$_listeners[$event] = array();
}
}
/**
* Dispatches an event, calls all callbacks that were previously registered
*
* @param string $event The event identifier
* @param array $params The event params
*/
public static function dispatchEvent($event, $params)
{
$eventObject = new Wootook_Core_Event($params);
if (!isset(self::$_listeners[$event])) {
return $eventObject;
}
foreach (self::$_listeners[$event] as $listener) {
call_user_func($listener, $eventObject);
}
return $eventObject;
}
/**
*
* Enter description here ...
* @param unknown_type $namespace
* @return Legacies_Core_Model_Session
*/
public static function getSession($namespace)
{
return Wootook_Core_Model_Session::factory($namespace);
}
public static function getTranslator($locale = null)
{
if ($locale === null) {
$locale = self::getLocale();
}
if (!isset($translator[$locale])) {
$path = dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR . 'locale';
$translator[$locale] = new Wootook_Core_Model_Translator($path, $locale);
}
return $translator[$locale];
}
public static function translate($locale, $message, Array $args)
{
return self::getTranslator($locale)->translateArgs($message, $args);
}
public static function __($message, $_ = null)
{
$args = func_get_args();
array_shift($args);
return self::getTranslator(self::getLocale())->translateArgs($message, $args);
}
public static function getLocale()
{
$availableLocales = self::getWebsiteConfig('locales');
if ($availableLocales !== null) {
return self::getPreferredLocale($availableLocales->toArray());
}
return self::getPreferredLocale();
}
public static function setDefaultLocale($locale)
{
$oldLocale = self::$_defaultLocale;
self::$_defaultLocale = $locale;
return $oldLocale;
}
public static function getDefaultLocale()
{
return self::$_defaultLocale;
}
public static function getPreferredLocale($availableLocales = array())
{
if (empty($availableLocales)) {
return self::getDefaultLocale();
}
$userLocale = self::getSession('user')->getData('locale');
if ($userLocale !== null) {
return $userLocale;
}
$locales = array();
if (($accept = self::getRequest()->getServer('HTTP_ACCEPT_LANGUAGE')) !== null) {
// break up string into pieces (languages and q factors)
preg_match_all('/([a-z]{1,8}(?:-([a-z]{1,8}))?)\s*(?:;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $accept, $matches);
$length = count($matches[1]);
for ($i = 0; $i < $length; $i++) {
$locale = $lang_parse[1];
if (!empty($lang_parse[2])) {
$locale .= '_' . strtoupper($lang_parse[2]);
}
$locales[$locale] = !empty($lang_parse[3]) ? min(max(floatval($lang_parse[3]), 0), 1) : 1;
}
arsort($locales, SORT_NUMERIC);
}
if (empty($locales)) {
return self::getDefaultLocale();
}
$preferredLocale = key($locales);
$preferredPriority = current($locales);
foreach ($locales as $locale => $piority) {
if (!in_array($locale, $availableLocales)) {
continue;
}
if ($preferredPriority < $piority) {
$preferredPriority = $piority;
$preferredLocale = $locale;
}
}
self::getSession('user')->setData('locale', $preferredLocale);
return $preferredLocale;
}
public static function now()
{
if (self::$_now === null) {
self::$_now = time();
}
return self::$_now;
}
/**
* @return Wootook_Core_Controller_Request_Http
*/
public static function getRequest()
{
if (self::$_request === null) {
self::$_request = new Wootook_Core_Controller_Request_Http();
}
return self::$_request;
}
public static function setRequest($request)
{
self::$_request = $request;
}
/**
* @return Wootook_Core_Controller_Response_Http
*/
public static function getResponse()
{
if (self::$_response === null) {
self::$_response = new Wootook_Core_Controller_Response_Http();
}
return self::$_response;
}
public static function setResponse($response)
{
self::$_response = $response;
}
public static function loadConfig($filename = null)
{
self::$_websiteConfigs = array();
self::$_gameConfigs = array();
self::$_config = new Wootook_Core_Config_Adapter_Array();
try {
self::$_config->load(APPLICATION_PATH . 'config' . DIRECTORY_SEPARATOR . 'system.php');
if ($filename === null) {
$filename = APPLICATION_PATH . 'config' . DIRECTORY_SEPARATOR . 'local.php';
}
if (is_string($filename)) {
if (!self::$isInstalled) {
throw new Wootook_Core_Exception_DataAccessException();
}
$localConfig = new Wootook_Core_Config_Adapter_Array($filename);
self::$_config->merge($localConfig);
} else if (is_array($filename)) {
$localConfig = new Wootook_Core_Config_Node($filename);
self::$_config->merge($localConfig);
} else if ($filename instanceof Wootook_Core_Config_Node) {
self::$_config->merge($filename);
} else {
throw new Wootook_Core_Exception_DataAccessException();
}
} catch (Wootook_Core_Exception_DataAccessException $e) {
self::$_globalConfig = new Wootook_Core_Config_Node(array(), self::$_config);
self::$_ignoreDatabaseConfig = true;
return self::$_config;
}
self::$_globalConfig = clone self::$_config['default'];
if (isset(self::$_config['global'])) {
self::$_globalConfig->merge(self::$_config['global']);
}
self::_appendDatabaseConfig(self::$_globalConfig);
return self::$_config;
}
private static function _appendDatabaseConfig(Wootook_Core_Config_Node $config, $type = 'global', $model = null)
{
if (self::$_ignoreDatabaseConfig) {
return $config;
}
$collection = new Wootook_Core_Collection('core_config', 'Wootook_Core_Model_Config');
switch ($type) {
case 'website':
$collection->where('website_id = :website_id');
$collection->load(array('website_id' => $model->getId()));
break;
case 'game':
$collection->where('game_id = :game_id');
$collection->load(array('game_id' => $model->getId()));
break;
default:
$collection->where('website_id = 0');
$collection->where('game_id = 0');
$collection->load(array());
break;
}
foreach ($collection as $row) {
$config->setConfig($row->getData('config_path'), $row->getData('config_value'));
}
return $config;
}
public static function getWebsite($websiteId)
{
if (is_numeric($websiteId)) {
if (isset(self::$_websitesById[$websiteId])) {
return self::$_websitesById[$websiteId];
}
$website = new Wootook_Core_Model_Website();
try {
$website->load($websiteId);
$websiteCode = $website->getData('code');
self::$_websitesById[$websiteId] = $website;
self::$_websitesByCode[$websiteCode] = $website;
} catch (Wootook_Core_Exception_DataAccessException $e) {
throw new Wootook_Core_Exception_WebsiteError('Could not load website entity.', null, $e);
}
return $website;
} else {
if (isset(self::$_websitesByCode[$websiteId])) {
return self::$_websitesByCode[$websiteId];
}
$website = new Wootook_Core_Model_Website();
try {
$website->load($websiteId, 'code');
$websiteId = $website->getId();
$websiteCode = $website->getData('code');
self::$_websitesById[$websiteId] = $website;
self::$_websitesByCode[$websiteCode] = $website;
} catch (Wootook_Core_Exception_DataAccessException $e) {
throw new Wootook_Core_Exception_WebsiteError('Could not load website entity.', null, $e);
}
return $website;
}
}
public static function getGame($gameId)
{
if (is_numeric($gameId)) {
if (isset(self::$_gamesById[$gameId])) {
return self::$_gamesById[$gameId];
}
$game = new Wootook_Core_Model_Game();
try {
$game->load($gameId);
$gameCode = $game->getData('code');
self::$_gamesById[$gameId] = $game;
self::$_gamesByCode[$gameCode] = $game;
} catch (Wootook_Core_Exception_DataAccessException $e) {
throw new Wootook_Core_Exception_GameError('Could not load game entity.', null, $e);
}
return $game;
} else {
if (isset(self::$_gamesByCode[$gameId])) {
return self::$_gamesByCode[$gameId];
}
$game = new Wootook_Core_Model_Game();
try {
$game->load($gameId, 'code');
$gameId = $game->getId();
$gameCode = $game->getData('code');
self::$_gamesById[$gameId] = $game;
self::$_gamesByCode[$gameCode] = $game;
} catch (Wootook_Core_Exception_DataAccessException $e) {
throw new Wootook_Core_Exception_GameError('Could not load game entity.', null, $e);
}
return $game;
}
}
public static function addWebsite(Wootook_Core_Model_Website $website)
{
$websiteId = $website->getId();
$websiteKey = $website->getData('code');
self::$_websitesById[$websiteId] = $website;
self::$_websitesByCode[$websiteKey] = $website;
}
public static function addGame(Wootook_Core_Model_Game $game)
{
$gameId = $game->getId();
$gameKey = $game->getData('code');
self::$_gamesById[$gameId] = $game;
self::$_gamesByCode[$gameKey] = $game;
}
public static function setDefaultWebsite(Wootook_Core_Model_Website $website)
{
self::$_defaultWebsite = $website;
}
public static function getDefaultWebsite()
{
if (self::$_defaultWebsite === null) {
self::$_defaultWebsite = new Wootook_Core_Model_Website();
self::$_defaultWebsite->setId(1)->setData('code', Wootook_Core_Model_Website::DEFAULT_CODE);
}
return self::$_defaultWebsite;
}
public static function getDefaultGame()
{
if (self::$_defaultGame === null) {
self::$_defaultGame = new Wootook_Core_Model_Game();
self::$_defaultGame->setId(1)->setData('code', Wootook_Core_Model_Game::DEFAULT_CODE);
}
return self::$_defaultGame;
}
public static function setDefaultGame(Wootook_Core_Model_Game $game)
{
self::$_defaultGame = $game;
}
private static function _initWebsiteConfig($websiteId)
{
if (self::$_config === null) {
self::loadConfig();
}
if (!self::$isInstalled) {
if (isset(self::$_config['default'])) {
self::$_websiteConfigs[Wootook_Core_Model_Website::DEFAULT_CODE] = clone self::$_config['default'];
} else {
self::$_websiteConfigs[Wootook_Core_Model_Website::DEFAULT_CODE] = new Wootook_Core_Config_Node(array(), self::$_config);
}
if (isset(self::$_config['install'])) {
self::$_websiteConfigs[Wootook_Core_Model_Website::DEFAULT_CODE]->merge(self::$_config['install']);
}
return self::$_websiteConfigs[Wootook_Core_Model_Website::DEFAULT_CODE];
}
try {
$website = self::getWebsite($websiteId);
} catch (Wootook_Core_Exception_RuntimeException $e) {
Wootook_Core_ErrorProfiler::getSingleton()->exceptionManager($e);
return null;
}
$websiteKey = $website->getData('code');
$websiteId = $website->getId();
if (!isset(self::$_websiteConfigs[$websiteKey])) {
self::$_websiteConfigs[$websiteKey] = clone self::$_config['default'];
if ($websiteId != 0 && isset(self::$_config['frontend'])) {
self::$_websiteConfigs[$websiteKey]->merge(self::$_config['frontend']);
} else if ($websiteId == 0 && isset(self::$_config['backend'])) {
self::$_websiteConfigs[$websiteKey]->merge(self::$_config['backend']);
}
$websiteConfig = self::$_config->getConfig("website/{$websiteKey}");
if ($websiteConfig !== null) {
self::$_websiteConfigs[$websiteKey]->merge($websiteConfig);
}
self::_appendDatabaseConfig(self::$_websiteConfigs[$websiteKey], 'website', $website);
}
return self::$_websiteConfigs[$websiteKey];
}
private static function _initGameConfig($gameId)
{
if (self::$_config === null) {
self::loadConfig();
}
if (!self::$isInstalled) {
if (isset(self::$_config['default'])) {
self::$_gameConfigs[Wootook_Core_Model_Game::DEFAULT_CODE] = clone self::$_config['default'];
} else {
self::$_gameConfigs[Wootook_Core_Model_Game::DEFAULT_CODE] = new Wootook_Core_Config_Node(array(), self::$_config);
}
if (isset(self::$_config['install'])) {
self::$_gameConfigs[Wootook_Core_Model_Game::DEFAULT_CODE]->merge(self::$_config['install']);
}
return self::$_gameConfigs[Wootook_Core_Model_Game::DEFAULT_CODE];
}
try {
$game = self::getGame($gameId);
} catch (Wootook_Core_Exception_RuntimeException $e) {
Wootook_Core_ErrorProfiler::getSingleton()->exceptionManager($e);
return null;
}
$gameKey = $game->getData('code');
$gameId = $game->getId();
$websiteId = $game->getData('website_id');
if (!isset(self::$_gameConfigs[$gameKey])) {
$websiteConfig = self::_initWebsiteConfig($websiteId);
if ($websiteConfig === null) {
return null;
}
self::$_gameConfigs[$gameKey] = clone $websiteConfig;
$gameConfig = self::$_config->getConfig("game/{$gameKey}");
if ($gameConfig !== null) {
self::$_gameConfigs[$gameKey]->merge($gameConfig);
}
self::_appendDatabaseConfig(self::$_gameConfigs[$gameKey], 'game', $game);
}
return self::$_gameConfigs[$gameKey];
}
public static function getConfig($path = null)
{
if (self::$_config === null) {
self::loadConfig();
}
if ($path !== null) {
return self::$_globalConfig->getConfig($path);
}
return self::$_globalConfig;
}
public static function getWebsiteConfig($path = null, $websiteKey = null)
{
if (self::$_config === null) {
self::loadConfig();
}
if ($websiteKey === null) {
//$websiteKey = Wootook_Core_Model_Website::DEFAULT_CODE;
$websiteKey = self::getDefaultWebsite()->getData('code');
}
$config = self::_initWebsiteConfig($websiteKey);
if ($config === null) {
return null;
}
if ($path !== null) {
return $config->getConfig($path);
}
return $config;
}
public static function getGameConfig($path = null, $gameKey = null)
{
if (self::$_config === null) {
self::loadConfig();
}
if ($gameKey === null) {
//$gameKey = Wootook_Core_Model_Game::DEFAULT_CODE;
$gameKey = self::getDefaultGame()->getData('code');
}
$config = self::_initGameConfig($gameKey);
if ($config === null) {
return null;
}
if ($path !== null) {
return $config->getConfig($path);
}
return $config;
}
public static function setConfig($path, $value, $websiteId = null, $gameId = null)
{
if (self::$_config === null) {
self::loadConfig();
}
if (!self::$_ignoreDatabaseConfig) {
$updater = new Wootook_Core_Model_Config();
$updater->setPath($path)->setValue($value);
if ($websiteId !== null) {
$updater->setWebsiteId($websiteId);
if ($gameId !== null) {
$updater->setGameId($gameId);
self::$_gameConfigs[$gameId]->setConfig($path, $value);
} else {
self::$_websiteConfigs[$websiteId]->setConfig($path, $value);
}
} else {
self::$_globalConfig->setConfig($path, $value);
}
$updater->save();
} else if ($websiteId !== null) {
if ($gameId !== null) {
self::$_gameConfigs[$gameId]->setConfig($path, $value);
} else {
self::$_websiteConfigs[$websiteId]->setConfig($path, $value);
}
} else {
self::$_globalConfig->setConfig($path, $value);
}
return true;
}
public static function getBaseUrl($domain = 'base')
{
$urlConfig = self::getGameConfig('web/url');
if (!$urlConfig instanceof Wootook_Core_Config_Node) {
return null;
}
if (!is_string($domain) || !isset($urlConfig->$domain)) {
return $urlConfig->base;
}
return $urlConfig->$domain;
}
public static function getBasePath($domain = 'base')
{
$pathConfig = self::getGameConfig('system/path');
if (!$pathConfig instanceof Wootook_Core_Config_Node) {
return null;
}
if (!is_string($domain) || !isset($pathConfig->$domain)) {
return $pathConfig->base;
}
return $pathConfig->$domain;
}
public static function getUrl($uri, Array $params = array())
{
$baseUrl = self::getBaseUrl();
$serializedParams = array();
foreach ($params as $paramKey => $paramValue) {
if ($paramValue) {
$serializedParams[] = "{$paramKey}={$paramValue}";
}
}
if (count($serializedParams) > 0) {
return $baseUrl . $uri . '?' . implode('&', $serializedParams);
}
return $baseUrl . $uri;
}
public static function fileExists($path)
{
if ($path === null || empty($path)) {
return false;
}
Wootook_Core_ErrorProfiler::getSingleton()->sleep();
if (($fp = @fopen($path, 'r', true)) === false) {
Wootook_Core_ErrorProfiler::getSingleton()->wakeup();
return false;
}
fclose($fp);
Wootook_Core_ErrorProfiler::getSingleton()->wakeup();
return true;
}
}