<?php
/**
* index.php
* Main entry point of Comelysome CMS.
* @copyright Copyright(c) 2002-2011 Björn Winberg
* @author Bjorn Winberg <cms@anomalye.net>
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License version 2
*/
date_default_timezone_set('Europe/London');
$context = new Context();
$context->startWrapper();
return;
/**
*
*/
class Module{
public static $MODULE_UID = false;
public $mContext = false;
protected $mConstants = array();
protected $mLocalSettings = array();
protected $mGlobalSettings = array();
/**
*
*/
public function __construct($aContext){
$this->mContext = $aContext;
}
/**
*
*/
public function generateView(){
return '';
}
/**
*
*/
public function loadSettings(){
$this->mLocalSettings = $this->mGlobalSettings = array();
$globalFile = $this->mContext->getGlobalIniFile(static::$MODULE_UID);
if(is_file($globalFile)){
$globalSettings = parse_ini_file($globalFile, true);
$localFile = $this->mContext->getLocalIniFile(static::$MODULE_UID);
if(is_file($localFile)){
foreach($globalSettings as $group => $data){
foreach($data as $key => $value){
$this->mGlobalSettings[$group][$key] = rawurldecode($value);
}
}
$localSettings = parse_ini_file($localFile, true);
foreach($localSettings as $group => $data){
foreach($data as $key => $value){
$this->mLocalSettings[$group][$key] = rawurldecode($value);
}
}
return true;
}
}
return false;
}
/**
*
*/
public function setConstant($aName, $aValue){
if(!isset($this->mConstants[$aName])){
$this->mConstants[$aName] = $aValue;
}
}
/**
*
*/
public function getConstant($aName){
if(isset($this->mConstants[$aName])){
return $this->mConstants[$aName];
}
return false;
}
/**
*
*/
public function getString($aKey){
if(isset($this->mLocalSettings['localized'][$aKey])){
return $this->mLocalSettings['localized'][$aKey];
}
return false;
}
/**
*
*/
public function getSetting($aKey){
if(isset($this->mGlobalSettings['settings'][$aKey])){
return $this->mGlobalSettings['settings'][$aKey];
}
return false;
}
}
/**
*
*/
class SystemModule extends Module{
public static $MODULE_UID = 'system';
/**
*
*/
public function __construct(Context $aContext){
parent::__construct($aContext);
$this->setConstant('BASEDIR', dirname(__FILE__));
$this->setConstant('LANGUAGE', 'eng');
$this->setConstant('DB_INTERFACE', 'sqlite');
$this->setConstant('DATA_FULLDIR', $this->getConstant('BASEDIR') . DIRECTORY_SEPARATOR . 'data');
$this->setConstant('PLUGIN_FULLDIR', $this->getConstant('BASEDIR') . DIRECTORY_SEPARATOR . 'modules');
$this->setConstant('SKIN_DIRNAME', 'skins');
$this->setConstant('SKIN_FULLDIR', $this->getConstant('BASEDIR') . DIRECTORY_SEPARATOR . $this->getConstant('SKIN_DIRNAME'));
$this->setConstant('TEMPLATE_FULLDIR', $this->getConstant('PLUGIN_FULLDIR') . DIRECTORY_SEPARATOR . 'templates');
$this->setConstant('INI_FULLDIR', $this->getConstant('PLUGIN_FULLDIR') . DIRECTORY_SEPARATOR . 'ini');
$this->setConstant('LOC_FULLDIR', $this->getConstant('PLUGIN_FULLDIR') . DIRECTORY_SEPARATOR . 'loc');
}
}
/**
*
*/
abstract class DatabaseConnection extends Module{
public static $MODULE_UID = false;
protected $mQueryCount = 0;
/**
*
*/
public function __construct(Context $aContext){
parent::__construct($aContext);
}
/**
*
*/
abstract public function dbOpen();
/**
*
*/
abstract public function dbClose();
/**
*
*/
abstract public function dbBeginTransaction();
/**
*
*/
abstract public function dbCommit();
/**
*
*/
abstract public function dbQuery($aQuery);
/**
*
*/
abstract public function dbExecute($aQuery);
/**
*
*/
abstract public function dbGetQueryCount();
}
/**
*
*/
class Context{
const PARAM_MAX_PAGE = 12;
private $mModules = array();
private $mFeedback = array('info' => array(), 'warn' => array());
private $mHtmlHeaders = array();
private $mScriptStart;
/**
*
*/
public function __construct(){
$this->mScriptStart = microtime(true);
}
/**
*
*/
public function startWrapper(){
$systemModule = new SystemModule($this);
$this->mModules[$systemModule::$MODULE_UID] = $systemModule;
$systemModule->loadSettings();
session_start();
if(!isset($_SESSION['systemInfo'])){
$_SESSION['systemInfo']['currentSkin'] = $this->getString('system', 'DEFAULT_SKIN');
}
$dbInterface = $this->loadModule($this->getConstant('system', 'DB_INTERFACE'));
if($dbInterface->dbOpen()){
$dbInterface->dbBeginTransaction();
$inputPage = $this->getParamEnc('p', 0, self::PARAM_MAX_PAGE);
$params['moduleContents'] = '';
if($inputPage !== false){
$module = $this->loadModule($inputPage);
if($module !== false){
$params['moduleContents'] = $module->generateView();
}
}
/*for($i = 0; $i < 4; $i++){
$dbInterface->dbExecute('CREATE TABLE IF NOT EXISTS test' . $i . ' (key TEXT PRIMARY KEY, value1 TEXT, value2 TEXT, value3 TEXT)');
$dbInterface->dbExecute("REPLACE INTO test" . $i . " (key, value1) VALUES ('" . $i . "','" . $i . "=>jkasdjk kasdhk asdas d asd asd asdjk as jkdjk asd asdasd sda jasd" . "')");
//$dbInterface->dbWrite('key' . $i, 'data' . $i);
//echo $dbInterface->dbRead('key' . $i);
}
for($i = 0; $i < 4; $i++){
$res = $dbInterface->dbQuery('SELECT * FROM test' . $i . " WHERE key = '" . $i . "'");
while($row = $res->fetchArray(SQLITE3_ASSOC)){
print_r($row);
}
//$dbInterface->dbWrite('key' . $i, 'data' . $i);
//echo $dbInterface->dbRead('key' . $i);
}*/
$params['scriptStart'] = $this->mScriptStart;
$params['queryCount'] = $dbInterface->dbGetQueryCount();
$dbInterface->dbCommit();
$dbInterface->dbClose();
echo $this->generateTemplate('system_wrapper.inc', $params);
}
}
/**
*
*/
public function feedbackWarn($aWarning){
$this->mFeedback['warn'][] = $aWarning;
}
/**
*
*/
public function feedbackInfo($aInfo){
$this->mFeedback['info'][] = $aInfo;
}
/**
*
*/
public function feedbackLog($aInfo){
echo "Log message: " . $aInfo . "<br>";
}
/**
*
*/
public function loadModule($aModuleName){
if(!isset($this->mModules[$aModuleName])){
$page = $this->getConstant('system', 'PLUGIN_FULLDIR') . DIRECTORY_SEPARATOR . $aModuleName . '.inc';
if(is_file($page)){
include($page);
$module = new $aModuleName($this);
assert($aModuleName === $module::$MODULE_UID);
$this->mModules[$module::$MODULE_UID] = $module;
return $module;
}
else{
$this->feedbackWarn($this->getString('system', 'ERROR_FILE_NOT_FOUND', array($aModuleName . '.inc')));
return false;
}
}
return $this->mModules[$aModuleName];
}
/**
*
*/
public function getParamSrc($aName, $aMin, $aMax, $aDefaultValue = false){
if(isset($_REQUEST[$aName])){
$length = $this->utf8StrLen($_REQUEST[$aName]);
if($length >= $aMin && $length <= $aMax){
return $_REQUEST[$aName];
}
return false;
}
return $aDefaultValue;
}
/**
*
*/
public function getParamEnc($aName, $aMin, $aMax, $aDefaultValue = false){
$param = $this->getParamSrc($aName, $aMin, $aMax, $aDefaultValue);
return rawurlencode($param);
}
/**
*
*/
public function utf8StrLen($aStr){
$pos = 0;
$count = 0;
$length = strlen($aStr);
while($pos < $length){
$chr = ord($aStr[$pos]);
$count++;
$pos++;
if($pos >= $length){
break;
}
if($chr & 0x80){
$chr <<= 1;
while($chr & 0x80){
$pos++;
$chr <<= 1;
}
}
}
return $count;
}
/**
*
*/
public function generateTemplate($aFilename, $aParams = array()){
ob_start();
require($this->getConstant('system', 'TEMPLATE_FULLDIR') . DIRECTORY_SEPARATOR . $aFilename);
$appliedTemplate = ob_get_contents();
ob_end_clean();
return $appliedTemplate;
}
/**
*
*/
public function getConstant($aModuleUId, $aConstantKey){
if(isset($this->mModules[$aModuleUId])){
return $this->mModules[$aModuleUId]->getConstant($aConstantKey);
}
return false;
}
/**
*
*/
public function getString($aModuleUId, $aStringKey, $aParams = false){
$ret = false;
if(isset($this->mModules[$aModuleUId])){
$ret = $this->mModules[$aModuleUId]->getString($aStringKey);
if($aParams !== false){
$ret = $this->insertVars($ret, $aParams, $this->getSetting('system', 'COMMAND_VARIABLE'));
}
}
return $ret;
}
/**
*
*/
public function getSetting($aModuleUId, $aKey){
if(isset($this->mModules[$aModuleUId])){
return $this->mModules[$aModuleUId]->getSetting($aKey);
}
return false;
}
/**
*
*/
public function insertVars($aStr, $aVars, $aDelim){
/*echo "String: $aStr<br>";
echo "Delim: $aDelim<br>";
print_r($aVars);*/
if($aVars !== false){
$ret = '';
$bits = explode($aDelim, $aStr);
foreach($bits as $str){
if($str != '' && isset($aVars[$str[0]])){
$ret = $ret . $aVars[$str[0]] . substr($str, 1);
}
else{
$ret = $ret . $str;
}
}
return $ret;
}
return $aStr;
}
/**
*
*/
public function getSkinUrl($aFile){
return $this->getConstant('system', 'SKIN_DIRNAME') . '/' . $_SESSION['systemInfo']['currentSkin'] . '/' . $aFile;
}
/**
*
*/
public function generateLink($aModule, $aTitle, $aParams = array()){
return '<a href="' . $this->generateUrl($aModule, $aParams) . '">' . $aTitle . '</a>';
}
/**
*
*/
public function generateUrl($aModule, $aParams = array()){
$url = 'index.php?p=' . $aModule;
foreach($aParams as $param => $value){
$url .= '&' . $param . '=' . $value;
}
return $url;
}
/**
*
*/
public function getSafeStr($aStr){
return htmlspecialchars(rawurldecode($aStr), ENT_COMPAT, 'UTF-8');
}
/**
*
*/
public function getLocalIniFile($aModule){
return $this->getConstant('system', 'LOC_FULLDIR') . DIRECTORY_SEPARATOR . $this->getConstant('system', 'LANGUAGE') . DIRECTORY_SEPARATOR . $aModule . '.ini';
}
/**
*
*/
public function getGlobalIniFile($aModule){
return $this->getConstant('system', 'INI_FULLDIR') . DIRECTORY_SEPARATOR . $aModule . '.ini';
}
}
$GLOBALS['_C']['dbKeys']['SYSTEM_LOG'] = array('system_log');
$GLOBALS['_C']['dbKeys']['SYSTEM_STATS'] = array('system_stats', '$0');
$GLOBALS['_C']['dbKeys']['SYSTEM_REFERERS'] = array('system_referers', '$0');
$GLOBALS['_C']['dbKeys']['SYSTEM_REFERERDETAILS'] = array('system_refererDetails', '$0');
system_loadModule($GLOBALS['_C']['SYSTEM_DB_INTERFACE']);
if(!system_dbOpen() || !system_dbBeginTransaction()){
die(system_loadStr('SYSTEM_DBFATAL_OPEN'));
}
if(!isset($_SESSION['modules']['auth']['userArray'])){
system_loadModule('auth');
auth_setLoggedSession(false);
}
system_readParamStr('p', 0, $GLOBALS['_S']['system']['LENGTH_S'], $GLOBALS['_S']['system']['DEFAULT_PAGE']);
system_readParamStr('a', 0, $GLOBALS['_S']['system']['LENGTH_S'], $GLOBALS['_S']['system']['DEFAULT_ACTION']);
system_readParamStr('o', 1, $GLOBALS['_S']['system']['LENGTH_S'], $GLOBALS['_C']['SYSTEM_OUTPUT_DEFAULT']);
system_initStats($GLOBALS['_S']['system']['GLOBAL_COUNTER']);
$GLOBALS['_T']['system']['outputType'] = $GLOBALS['_IN']['o']['enc'];
if($GLOBALS['_S']['system']['ENABLE_INSTALLER'] === 'true'){
system_loadModule('installer');
$GLOBALS['_T']['system']['moduleContents'] = installer_controller();
}
elseif(system_loadModule($GLOBALS['_IN']['p']['enc'])){
system_setCurrentItem();
$moduleExec = $GLOBALS['_IN']['p']['enc'] . '_controller';
$GLOBALS['_T']['system']['moduleContents'] = $moduleExec();
}
if(!system_dbCommit()){
die(system_loadStr('SYSTEM_DBFATAL_COMMIT'));
}
system_dbClose();
if($GLOBALS['_T']['system']['outputType'] === $GLOBALS['_C']['SYSTEM_OUTPUT_DEFAULT']){
header('Content-Type: text/html; charset=utf-8');
echo system_applyTemplate('system_wrapper.inc');
}
elseif($GLOBALS['_T']['system']['outputType'] === $GLOBALS['_C']['SYSTEM_OUTPUT_XML']){
header('Content-Type: text/xml; charset=utf-8');
echo $GLOBALS['_T']['system']['moduleContents'];
}
else{
echo $GLOBALS['_T']['system']['moduleContents'];
}
return true;
/**
* Set a current item in session from default value, user input or an old session.
*/
function system_setCurrentItem(){
$default = system_loadStr('SYSTEM_DEFAULT_ITEM');
if(isset($_SESSION['currentItem']) && isset($_REQUEST['p'])){
$default= rawurldecode($_SESSION['currentItem']);
}
system_readParamStr('item', 1, $GLOBALS['_S']['system']['LENGTH_M'], $default);
system_parseAsUId('item');
$_SESSION['currentItem'] = $GLOBALS['_IN']['item']['UId'];
}
/**
* Create a menu tree from serialized data.
* @param string $aIniKey The key identifying a serialized menu array in the hidden settings.
* @return array A menu array.
*/
function system_parseMenu($aIniKey){
$menu = array();
if(isset($GLOBALS['_S']['hidden'][$aIniKey]) && $GLOBALS['_S']['hidden'][$aIniKey] !== ''){
$menu = unserialize($GLOBALS['_S']['hidden'][$aIniKey]);
if($menu === false){
$menu = array();
}
}
return $menu;
}
/**
* Generate HTML code to display a menu array.
* @param string $aMenuName The key identifying a serialized menu array in the hidden settings.
* @param array $aParams Parameter data used by some menues.
* @param string $aCssClass CSS class.
* @param string|bool $aCssSelected CSS class for selected item, or false to disable.
* @return string The HTML code of the menu.
*/
function system_menuBuild($aMenuName, $aParams = array(), $aCssClass = '', $aCssSelected = false){
$menu = system_parseMenu($aMenuName);
$menuStr = '<div class="' . $aCssClass . '"><ul>' . "\n";
$URIBits = explode('/', $_SERVER['REQUEST_URI']);
$currentUrl = rawurlencode(array_pop($URIBits));
foreach($menu as $sectionKey=>$sectionData){
if(system_requireAuthorization(rawurldecode($sectionData['sectionAuth']))){
$sectionData['sectionName'] = system_insertVars($sectionData['sectionName'], $aParams);
$sectionData['url'] = system_insertVars($sectionData['url'], $aParams);
if(trim(rawurldecode($sectionData['sectionName'])) != ''){
if($aCssSelected !== false && $currentUrl === $sectionData['url']){
$menuStr .= '<li class="' . $aCssSelected . '">';
}
else{
$menuStr .= '<li>';
}
if($sectionData['url'] != ''){
$menuStr .= '<a href="';
$menuStr .= system_getSafeStr($sectionData['url']);
$menuStr .= '">' . system_getSafeStr($sectionData['sectionName']) . '</a>';
}
else{
$menuStr .= system_getSafeStr($sectionData['sectionName']);
}
$menuStr .= '</li>' . "\n";
}
foreach($sectionData['items'] as $itemKey=>$itemData){
if(system_requireAuthorization(rawurldecode($itemData['auth']))){
if($aCssSelected !== false && $currentUrl === $itemData['url']){
$menuStr .= '<li class="' . $aCssSelected . '">';
}
else{
$menuStr .= '<li>';
}
$itemData['title'] = system_insertVars($itemData['title'], $aParams);
if($itemData['url'] != ''){
$menuStr .= '<a href="';
$menuStr .= system_getSafeStr($itemData['url']);
$menuStr .= '">' . system_getSafeStr($itemData['title']) . '</a>';
}
else{
$menuStr .= system_getSafeStr($itemData['title']);
}
$menuStr .= '</li>' . "\n";
}
}
}
}
$menuStr .= '</ul></div>' . "\n";
return $menuStr;
}
/**
* Split a string into an array like str_split() in Php5.
* @param string $aString String to be exploded.
* @param int $aLength Length of each chunk.
* @return array Array containing the exploded string.
*/
function system_strSplit($aString, $aLength = 1){
$array = explode("\r\n", chunk_split($aString, $aLength));
array_pop($array);
return $array;
}
/**
* Slice an array and preserve keys similarly to array_slice() in Php5.
* @param array $aArray Source array.
* @param int $aOffset Index offset.
* @param int $aLen Number of items in the slice. A negative length will slice to end of array.
* @return array|bool The array slice or false on failure.
*/
function system_arraySlice($aArray, $aOffset, $aLen = -1){
if(!is_array($aArray)){
return false;
}
$return = array();
$length = $aLen > 0? $aLen: count($aArray);
$keys = array_slice(array_keys($aArray), $aOffset, $length);
foreach($keys as $key){
$return[$key] = $aArray[$key];
}
return $return;
}
/**
* Check if a user has permission to perform an action.
* @param string $aActionStr An action token.
* @return bool True if current user has permissions for the action.
*/
function system_requireAuthorization($aActionStr){
$aActionStr = strtolower(rawurlencode($aActionStr));
$actionVec = explode('_', $aActionStr);
$action = $actionVec[0];
$encodedWildcard = strtolower(rawurlencode('*'));
$params = array_splice($actionVec, 1);
if(isset($_SESSION['modules']['auth']['userArray']['authActions'][$action])){
if(isset($_SESSION['modules']['auth']['userArray']['authActions'][$action][$encodedWildcard])){
return true;
}
for($i = 0; $i < count($params); $i++){
if($params[$i] !== '' && !isset($_SESSION['modules']['auth']['userArray']['authActions'][$action][$params[$i]])){
return false;
}
}
return true;
}
return false;
}
/**
* Add an entry to the recent log.
* @param int $aTime Time stamp.
* @param string $aModule UId of sub section in the log.
* @param string $aText Unencoded and safe html text of log entry.
* @param bool True on success.
*/
function system_logEntry($aTime, $aModule, $aText){
if(!isset($GLOBALS['_T']['system']['modules'][$aModule]['name'])){
return false;
}
$moduleDisplayName = $GLOBALS['_T']['system']['modules'][$aModule]['name'];
$dbKey = system_dbKey('SYSTEM_LOG');
$systemLog = system_dbRead($dbKey);
$count = 0;
while(isset($systemLog[$aModule]['log'][$aTime . '_' . $count])){
$count++;
}
$logKey = $aTime . '_' . $count;
$systemLog[$aModule]['name'] = $moduleDisplayName;
$systemLog[$aModule]['log'][$logKey]['author'] = $_SESSION['modules']['auth']['userArray']['nameDisplay'];
$systemLog[$aModule]['log'][$logKey]['IP'] = $_SERVER['REMOTE_ADDR'];
$systemLog[$aModule]['log'][$logKey]['text'] = $aText;
system_timeFilter($systemLog[$aModule], $GLOBALS['_S']['system']['LOG_MAX_ITEMS'], $GLOBALS['_S']['system']['LOG_DELETE_THRESHOLD'] * 24 * 60 * 60);
system_dbWrite($dbKey, $systemLog);
return true;
}
/**
* Split an utf-8 string into an array of characters.
* @param string $aStr Utf-8 string.
* @return array Character array.
*/
function system_utf8Str2Array($aStr){
$pos = 0;
$count = -1;
$ret = array();
$length = strlen($aStr);
while($pos < $length){
$chr = ord($aStr[$pos]);
$count++;
$ret[$count] = $aStr[$pos];
$pos++;
if($pos >= $length){
break;
}
if($chr & 0x80){
$chr <<= 1;
while($chr & 0x80){
$ret[$count] .= $aStr[$pos];
$pos++;
$chr <<= 1;
}
}
}
return $ret;
}
/**
* Generate Javascript to display a timestamp.
* @param int $aTime Timestamp.
* @param string $aShowGMT The string 'true' if GMT offset should be shown.
* @param string $aFormat Time format. Empty string for default format.
* @param string $aPre An optional string to display before the time stamp.
* @param string $aPost An optional string to display after the time stamp.
*/
function system_generateTimeScript($aTime, $aShowGMT = 'false', $aFormat = '', $aPre = '', $aPost = ''){
if($aFormat == ''){
$aFormat = system_loadStr('SYSTEM_TIMESTAMP_FORMAT');
}
$gmtStr = '';
if($aShowGMT == 'true'){
$gmtStr = ' (' . system_loadStr('SYSTEM_UTC') . ': 0:00)';
}
$scriptPre = str_replace('"', '\"', $aPre);
$scriptPost = str_replace('"', '\"', $aPost);
return '<script type="text/javascript">' . "\n" . '<!-- ' . "\n" . 'document.write("' . $scriptPre . '" + getTime("' . $aTime . '", "' . $aFormat . '", "' . $aShowGMT . '", "' . system_loadStr('SYSTEM_UTC') .'") + "' . $scriptPost . '");' . "\n" . ' --></script>' .
'<noscript><div style="display: inline;">' . $aPre . gmdate($aFormat, $aTime) . $gmtStr . $aPost . '</div></noscript>';
}
/**
* Generate Javascript to display gmt offset.
* @param string $aPre An optional string to display before the time stamp.
* @param string $aPost An optional string to display after the time stamp.
*/
function system_getGmtScript($aPre = '', $aPost = ''){
$gmtStr = '0:00';
return '<script type="text/javascript">' . "\n" . '<!--' . "\n" . 'document.write("' . $aPre . '" + getGMTStr() + "' . $aPost . '");' . "\n" . '--></script>' .
'<noscript><div style="display: inline;">' . $aPre . $gmtStr . $aPost . '</div></noscript>';
}
/**
* Get the HTML code to display a user name with link to public user page.
* @param string $aDisplayName User name.
* @return string A linkified username, or plain text name for invalid UIds (e.g. guests).
*/
function system_generateUserLink($aEncodedName){
if($aEncodedName !== false){
return '<a href="index.php?p=auth&a=publicUser&name=' . $aEncodedName . '">' . system_getSafeStr($aEncodedName) . '</a>';
}
else{
return system_loadStr('SYSTEM_ANONYMOUS_USER');
}
}
/**
* Create a stat item and update the online user info.
* @param string $aCounterId A unique counter name.
*/
function system_initStats($aCounterId){
$currentTime = time();
$currentDate = @getdate($currentTime);
$counterDbKey = system_dbKey('SYSTEM_STATS', array($aCounterId));
$counterItem = system_dbRead($counterDbKey);
if($counterItem === false){
$counterItem['users'] = array();
$counterItem['domains'] = array();
$counterItem['referers'] = array();
$counterItem['counter'] = 0;
$counterItem['lastUpdate'] = $currentTime;
$counterItem['lastHourCount'] = array_fill(0, 24, 0);
$counterItem['lastDayCount'] = array_fill(0, 7, 0);
$counterItem['lastMonthCount'] = array_fill(0, 12, 0);
$counterItem['allHourCount'] = array_fill(0, 24, 0);
$counterItem['allDayCount'] = array_fill(0, 7, 0);
$counterItem['allMonthCount'] = array_fill(0, 12, 0);
}
if(!isset($counterItem['allYearCount'][$currentDate['year']])){
$counterItem['allYearCount'][$currentDate['year']] = 0;
}
if(!isset($_SESSION['modules']['stats']['sessionCounter'])){
$_SESSION['modules']['stats']['sessionCounter'] = 0;
}
$_SESSION['modules']['stats']['sessionCounter']++;
system_statUsers($counterItem, $currentTime);
system_dbWrite($counterDbKey, $counterItem);
}
/**
* Add current user to online statistics and clear old users.
* @param array &$aCounterItem Reference to a counter array.
* @param int $aCurrentTime Current time stamp.
* @access private
*/
function system_statUsers(&$aCounterItem, $aCurrentTime){
if(!isset($aCounterItem['users'][$_SERVER['REMOTE_ADDR']])){
$aCounterItem['users'][$_SERVER['REMOTE_ADDR']]['startTime'] = $aCurrentTime;
$aCounterItem['users'][$_SERVER['REMOTE_ADDR']]['validBeacon'] = false;
}
$aCounterItem['users'][$_SERVER['REMOTE_ADDR']]['time'] = $aCurrentTime;
$aCounterItem['users'][$_SERVER['REMOTE_ADDR']]['name'] = $_SESSION['modules']['auth']['userArray']['nameDisplay'];
$aCounterItem['users'][$_SERVER['REMOTE_ADDR']]['pageviews'] = $_SESSION['modules']['stats']['sessionCounter'];
foreach($aCounterItem['users'] as $ip => $data){
if($aCurrentTime - $aCounterItem['users'][$ip]['time'] > $GLOBALS['_S']['system']['ONLINE_TIME_MINUTE_LIMIT'] * 60){
unset($aCounterItem['users'][$ip]);
}
}
$GLOBALS['_T']['system']['onlineCount'] = count($aCounterItem['users']);
}
/**
* Main entry point for the parser. Find and handle all tags/commands in a parse item.
* Results are added to the parse item: 'parsedText', 'tags' and 'warnings'.
* The 'sourceText' might also be modified if one-time commands are used.
* @param array &$aSourceItem Parse item containing 'sourceText' and 'itemName'.
* @param string &$aAllowedHtml Comma separated list of allowed HTML tags.
* @param string &$aAllowedCommands Comma separated list of allowed modules|commands.
* @param array|bool $aParams An array of values to insert in the parsed article.
*/
function system_parseItem(&$aSourceItem, &$aAllowedHtml, &$aAllowedCommands, $aParams = false){
if($aSourceItem === false || !isset($aSourceItem['sourceText'])){
return false;
}
if($aParams !== false){
$aSourceItem['sourceText'] = system_insertVars($aSourceItem['sourceText'], $aParams);
}
if($GLOBALS['_S']['system']['PREPARSE_REPLACE'] !== ''){
system_preParse($aSourceItem, $GLOBALS['_S']['system']['PREPARSE_REPLACE']);
}
$commandBits = explode(',', $aAllowedCommands);
foreach($commandBits as $commandTag){
$bits = explode('|', $commandTag);
if(isset($bits[0]) && $bits[0] != '' && isset($bits[1]) && $bits[1] != ''){
$module = $bits[0];
$command = $bits[1];
$commandArray[$command] = $module;
}
}
$htmlBits = explode(',', $aAllowedHtml);
foreach($htmlBits as $htmlTag){
if($htmlTag != ''){
$htmlArray[$htmlTag] = 0;
}
}
$aSourceItem['parsedText'] = '';
$aSourceItem['info'] = array();
$aSourceItem['tags'] = array();
$aSourceItem['warnings'] = array();
system_parseExtractTags($aSourceItem, $commandArray, $htmlArray, false);
}
/**
* Perform a simple string replace before the main parsing starts.
* @param array &$aParseItem Parse item.
* @param string $aReplaceStr String containing replace rules in the format: "searchString,replaceString "
* @return string The modified source text.
*/
function system_preParse(&$aParseItem, $aReplaceStr){
$firstBits = explode(' ', $aReplaceStr);
foreach($firstBits as $replaceStr){
$replaceBits = explode(',', $replaceStr);
if(isset($replaceBits[1])){
$key = array_shift($replaceBits);
$replaceArray[$key] = implode(',', $replaceBits);
}
}
$shortcutToken = rawurlencode($GLOBALS['_S']['system']['COMMAND_SHORTCUT']);
$sourceBits = explode($shortcutToken, $aParseItem['sourceText']);
$i = 0;
$count = count($sourceBits);
do{
if(isset($sourceBits[$i-1]) && isset($sourceBits[$i+1]) && isset($replaceArray[$sourceBits[$i]])){
$sourceBits[$i+1] = $sourceBits[$i-1] . rawurlencode($replaceArray[$sourceBits[$i]]) . $sourceBits[$i+1];
unset($sourceBits[$i-1]);
unset($sourceBits[$i]);
$i++;
}
$i++;
}while($i < $count);
$newSource = implode($shortcutToken, $sourceBits);
$aParseItem['sourceText'] = $newSource;
return $newSource;
}
/**
* Separate command tags and HTML data and send it to the correct handler.
* @param array &$aParseItem Parse item that will hold the results.
* @param array &$aAllowedCommands Allowed command tags.
* @param array &$aAllowedHtml Allowed Html tags.
* @param bool $aAllowJavacript Allow Javascript.
* @access private
*/
function system_parseExtractTags(&$aParseItem, &$aAllowedCommands, &$aAllowedHtml, $aAllowJavacript = false){
$startTag = str_replace ('%', '\%', rawurlencode($GLOBALS['_S']['system']['COMMAND_TAG_START']));
$endTag = str_replace ('%', '\%', rawurlencode($GLOBALS['_S']['system']['COMMAND_TAG_END']));
$pattern = '/' . $startTag . '(.*)' . $endTag . '/iU';
$bits = preg_split($pattern, $aParseItem['sourceText'], -1, PREG_SPLIT_DELIM_CAPTURE);
$aParseItem['sourceText'] = '';
$i = 0;
while(isset($bits[$i])){
system_parseHtml($aParseItem, $bits[$i], $aAllowedHtml, $aAllowJavacript);
$aParseItem['sourceText'] .= $bits[$i];
if(isset($bits[$i+1])){
system_parseCommandTag($aParseItem, $bits[$i+1], $aAllowedCommands);
$aParseItem['sourceText'] .= rawurlencode($GLOBALS['_S']['system']['COMMAND_TAG_START']) . $bits[$i+1] . rawurlencode($GLOBALS['_S']['system']['COMMAND_TAG_END']);
}
$i += 2;
}
}
/**
* Check if a command tag is allowed and rout it to the correct module handler.
* @param array &$aParseItem Parse item that will hold the results.
* @param string &$aTag The full tag (command+params) being handled.
* @param array &$aAllowedCommands A list of allowed commands.
* @access private
*/
function system_parseCommandTag(&$aParseItem, &$aTag, &$aAllowedCommands){
$tagBits = explode(rawurlencode($GLOBALS['_S']['system']['COMMAND_PARAMETER_SEPARATOR']), $aTag);
if($tagBits[0] !== ''){
$command = 'link';
}
elseif(isset($tagBits[1]) && $tagBits[1] !== ''){
$command = $tagBits[1];
}
else{
$aParseItem['warnings'][] = system_loadStr('SYSTEM_PARSE_INVALID_TAG');
return;
}
if(strpos($command, rawurlencode($GLOBALS['_S']['system']['COMMAND_TAG_START'])) === 0){
$aParseItem['parsedText'] .= system_getSafeStr($aTag);
return;
}
if(isset($aAllowedCommands[$command])){
if(strpos($aTag, rawurlencode($GLOBALS['_S']['system']['COMMAND_VARIABLE'])) !== false){
$aParseItem['parsedText'] .= $GLOBALS['_S']['system']['COMMAND_TAG_START'] . system_getSafeStr($aTag) . $GLOBALS['_S']['system']['COMMAND_TAG_END'];
return;
}
$module = $aAllowedCommands[$command];
if(system_loadModule($module)){
$handlerFunction = $module . '_handleParseTag';
$handlerFunction($aParseItem, $aTag);
$aParseItem['tags'][$aTag] = $module;
}
}
else{
$aParseItem['warnings'][] = system_loadStr('SYSTEM_PARSE_INVALID_VARIABLE', array(system_getSafeStr($command)));
}
}
/**
* Parse a mixed body of Html and plain text.
* @param array &$aParseItem Parse item that will hold the results.
* @param array &$aHtmlData Html text to be parsed.
* @param array &$aAllowedHtml Allowed Html tags.
* @param bool $aAllowJavacript Allow Javascript.
* @access private
*/
function system_parseHtml(&$aParseItem, &$aHtmlData, &$aAllowedHtml, $aAllowJavacript = false){
$pattern = '/\%3C(.*?)\%3E/ie';
$bits = preg_split($pattern, $aHtmlData, -1, PREG_SPLIT_DELIM_CAPTURE);
$i = 0;
while(isset($bits[$i])){
system_parsePlainText($aParseItem, $bits[$i]);
if(isset($bits[$i+1])){
system_parseHtmlTag($aParseItem, $bits[$i+1], $aAllowedHtml, $aAllowJavacript);
}
$i += 2;
}
}
/**
* Parse what is left when html and commands have been parsed.
* @param array &$aParseItem Parse item that will hold the results.
* @param array $aText Text to be parsed.
* @access private
*/
function system_parsePlainText(&$aParseItem, $aText){
$aParseItem['parsedText'] .= system_getSafeStr($aText);
}
/**
* Check a html tag and make it safe before adding it to the parsed item.
* @param array &$aParseItem Parse item that will hold the results.
* @param array $aTag Html tag to be parsed.
* @param array &$aAllowedHtml Allowed Html tags.
* @param bool $aAllowJavacript Allow Javascript.
* @access private
*/
function system_parseHtmlTag(&$aParseItem, $aTag, &$aAllowedHtml, $aAllowJavacript = false){
$aTag = rawurldecode($aTag);
$bits = explode(' ', $aTag);
if(isset($bits[0][0])){
if($bits[0][0] == '/'){
$tagname = substr($bits[0], 1);
}
else{
$tagname = $bits[0];
}
}
$javaWarn = false;
if(!$aAllowJavacript && preg_match('/javascript|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup/i', $aTag)){
$javaWarn = true;
$aParseItem['warnings'][] = system_loadStr('SYSTEM_PARSE_JAVA_WARN');
}
if(isset($tagname) && isset($aAllowedHtml[$tagname]) && !$javaWarn){
$aParseItem['parsedText'] .= '<' . $aTag . '>';
}
else{
$aParseItem['parsedText'] .= '<' . htmlspecialchars($aTag, ENT_COMPAT, 'UTF-8') . '>';
}
}
/**
* Callback function that handles parser commands that belongs to this module.
* @param array &$aParseItem Parse item that will hold the results.
* @param string &$aTag The full tag (command+params) being handled.
* @see system_parseRootTag()
*/
function system_handleParseTag(&$aParseItem, &$aTag){
$tagBits = explode(rawurlencode($GLOBALS['_S']['system']['COMMAND_PARAMETER_SEPARATOR']), $aTag);
if($tagBits[1] == rawurlencode('time')){
if(isset($tagBits[2])){
$time = $tagBits[2];
if(!is_numeric($time) || $time < 0){
$time = 0;
}
}
else{
$time = time();
$aTag = rawurlencode($GLOBALS['_S']['system']['COMMAND_PARAMETER_SEPARATOR'] . 'time' . $GLOBALS['_S']['system']['COMMAND_PARAMETER_SEPARATOR'] . $time);
}
$aParseItem['parsedText'] .= system_generateTimeScript($time);
}
elseif($tagBits[1] == rawurlencode('user')){
if(isset($tagBits[2])){
$user = $tagBits[2];
}
else{
$user = $_SESSION['modules']['auth']['userArray']['nameDisplay'];
$aTag = rawurlencode($GLOBALS['_S']['system']['COMMAND_PARAMETER_SEPARATOR'] . 'user' . $GLOBALS['_S']['system']['COMMAND_PARAMETER_SEPARATOR']) . $user;
}
$aParseItem['parsedText'] .= system_generateUserLink($user);
}
elseif($tagBits[1] == rawurlencode('api')){
if(isset($tagBits[2]) && $tagBits[2] != ''){
$params = explode(rawurlencode('/'), $tagBits[2]);
$module = array_shift($params);
if(system_loadModule($module)){
$handlerFunction = $module . '_api';
$aParseItem['parsedText'] .= $handlerFunction($params);
}
}
}
else{
$aParseItem['warnings'][] = system_loadStr('SYSTEM_PARSE_INVALID_VARIABLE', array(system_getSafeStr($tagBits[1])));
}
}
/**
* General callback function.
* @param array &$aItem The orginator item of the action. The exact item type depends on the action.
* @param array &$aData Additional data. Exact type depends on the action.
* @param string $aAction The action that has been reported.
* @see system_parseDiffNotify()
*/
function system_handleEvent(&$aItem, &$aData, $aAction){
// Do nothing
}
/**
* Event generator that compares two versions of a parse item and notifies the tag owning modules
* when a tag is removed, added or retained. The params must already be parsed
* with system_parseItem().
* @param array &$aOldParseItem Old version.
* @param array &$aParseItem New version.
* @see system_parseItem()
*/
function system_parseDiffNotify(&$aOldParseItem, &$aParseItem){
$notifyAction = 'system_parseTagAdded';
if($aParseItem === false){
$aParseItem['tags'] = array();
}
if($aOldParseItem !== false){
$notifyAction = 'system_parseTagRetained';
$removedTags = array_diff_assoc($aOldParseItem['tags'], $aParseItem['tags']);
$addedTags = array_diff_assoc($aParseItem['tags'], $aOldParseItem['tags']);
foreach($removedTags as $tag => $module){
if(system_loadModule($module)){
$handlerFunction = $module . '_handleEvent';
$handlerFunction($aParseItem, $tag, 'system_parseTagRemoved');
}
}
foreach($addedTags as $tag => $module){
if(system_loadModule($module)){
$handlerFunction = $module . '_handleEvent';
$handlerFunction($aParseItem, $tag, 'system_parseTagAdded');
}
}
}
foreach($aParseItem['tags'] as $tag => $module){
if(!isset($removedTags[$tag]) && !isset($addedTags[$tag])){
if(system_loadModule($module)){
$handlerFunction = $module . '_handleEvent';
$handlerFunction($aParseItem, $tag, $notifyAction);
}
}
}
}
/**
* Generate Html meta headers.
* @return string Html meta headers ready for output.
*/
function system_generateMetaHeaders(){
$headers = '<meta name="Generator" content="' . $GLOBALS['_T']['system']['modules']['system']['name'] . ' ' . $GLOBALS['_T']['system']['modules']['system']['version'] . '" />' . "\n";
$contentItem = false;
if(isset($GLOBALS['_T']['article']['contentItem'])){
$contentItem = &$GLOBALS['_T']['article']['contentItem'];
}
$title = system_loadStr('SYSTEM_SITE_NAME');
if(isset($contentItem['info']['article']['title'])){
$title = $title . ' - ' . system_getSafeStr($contentItem['info']['article']['title']);
}
$desc = '';
if(isset($contentItem['info']['article']['description'])){
$desc = system_getSafeStr($contentItem['info']['article']['description']);
}
$keywords = '';
if(isset($contentItem['info']['article']['keywords'])){
$keywords = system_getSafeStr($contentItem['info']['article']['keywords']);
}
$headers .= '<title>' . $title . '</title>' . "\n";
$headers .= '<meta name="description" content="' . $desc . '" />' . "\n";
$headers .= '<meta name="keywords" content="' . $keywords . '" />' . "\n";
return $headers;
}
/**
* Generate feedback boxes inside a hidden div. Used to return feedback on ajax requests.
* @return string Html string with feedback boxes.
*/
function system_generateAjaxFeedback(){
$feedback = '<div style="display: none;" id="ajaxHiddenFeedback">';
foreach($GLOBALS['_T']['system']['feedback']['warn'] as $warning){
$feedback .= '<div class="errorBox">' . $warning . '</div>';
}
foreach($GLOBALS['_T']['system']['feedback']['info'] as $info){
$feedback .= '<div class="editBox">' . $info . '</div>';
}
$feedback .= '</div>';
return $feedback;
}
/**
* List all files in a directory.
* @param string $aDir Directory name.
* @return array A dir listing array.
*/
?>