Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Feb 25, 6:05 AM

in-portal

Index: branches/5.2.x/core/kernel/utility/http_query.php
===================================================================
--- branches/5.2.x/core/kernel/utility/http_query.php (revision 15706)
+++ branches/5.2.x/core/kernel/utility/http_query.php (revision 15707)
@@ -1,802 +1,802 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kHTTPQuery extends Params {
/**
* Cache of QueryString parameters
* from config, that are represented
* in environment variable
*
* @var Array
*/
protected $discoveredUnits = Array ();
/**
* $_POST vars
*
* @var Array
* @access private
*/
var $Post;
/**
* $_GET vars
*
* @var Array
* @access private
*/
var $Get;
/**
* $_COOKIE vars
*
* @var Array
* @access private
*/
var $Cookie;
/**
* $_SERVER vars
*
* @var Array
* @access private
*/
var $Server;
/**
* $_ENV vars
*
* @var Array
* @access private
*/
var $Env;
/**
* Order in what write
* all vars together in
* the same array
*
* @var string
*/
var $Order;
/**
* Uploaded files info
*
* @var Array
* @access private
*/
var $Files;
var $specialsToRemove = Array();
/**
* SessionID is given via "sid" variable in query string
*
* @var bool
*/
var $_sidInQueryString = false;
/**
* Trust information, provided by proxy
*
* @var bool
*/
protected $_trustProxy = false;
/**
* Loads info from $_POST, $_GET and
* related arrays into common place
*
* @param string $order
* @access public
*/
public function __construct($order = 'CGPF')
{
parent::__construct();
$this->Order = $order;
if ( isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
// when AJAX request is made from jQuery, then create ajax variable,
// so any logic based in it (like redirects) will not break down
$_GET['ajax'] = 'yes';
}
$vars = kUtil::getConfigVars();
$this->_trustProxy = isset($vars['TrustProxy']) ? (bool)$vars['TrustProxy'] : false;
}
/**
* Discovers unit form request and returns it's QueryString option on success
*
* @param string $prefix_special
*
* @return Array|bool
* @access public
*/
public function discoverUnit($prefix_special)
{
list($prefix) = explode('.', $prefix_special);
$query_string = $this->getQueryString($prefix);
if ($query_string) {
// only units with QueryString option can be discovered
$this->discoveredUnits[$prefix_special] = $query_string;
return $query_string;
}
unset( $this->discoveredUnits[$prefix] );
return false;
}
/**
* Returns units, passed in request
*
* @param bool $prefix_special_only
* @return Array
* @access protected
*/
public function getDiscoveredUnits($prefix_special_only = true)
{
return $prefix_special_only ? array_keys( $this->discoveredUnits ) : $this->discoveredUnits;
}
/**
* Returns QueryMap for requested unit config.
* In case if unit config is a clone, then get parent item's (from prefix) config to create clone
*
* @param string $prefix
* @return Array
* @access protected
*/
protected function getQueryString($prefix)
{
$ret = $this->Application->getUnitOption($prefix, 'QueryString', Array ());
if ( !$ret && preg_match('/(.*?)-(.*)/', $prefix, $regs) ) {
// "#prefix" (new format), "prefix" (old format)
return $this->_getQueryString('#' . $regs[2]);
}
return $ret;
}
/**
* Returns query string (with safety check against missing prefixes)
*
* @param string $prefix
* @return Array
*/
private function _getQueryString($prefix)
{
if ( $this->Application->prefixRegistred($prefix) ) {
return $this->Application->getUnitOption($prefix, 'QueryString');
}
return substr($prefix, 0, 1) == '#' ? $this->_getQueryString( substr($prefix, 1) ) : Array ();
}
/**
* Removes specials from request
*
* @param Array $array
* @return Array
* @access protected
*/
protected function _removeSpecials($array)
{
$ret = Array ();
$removed = false;
foreach ($this->specialsToRemove as $prefix_special => $flag) {
if ( $flag ) {
$removed = true;
list ($prefix, $special) = explode('.', $prefix_special, 2);
foreach ($array as $key => $val) {
$new_key = preg_match("/^" . $prefix . "[._]{1}" . $special . "(.*)/", $key, $regs) ? $prefix . $regs[1] : $key;
$ret[$new_key] = is_array($val) ? $this->_removeSpecials($val) : $val;
}
}
}
return $removed ? $ret : $array;
}
public function process()
{
$this->AddAllVars();
$this->removeSpecials();
ini_set('magic_quotes_gpc', 0);
$this->Application->UrlManager->LoadStructureTemplateMapping();
$this->AfterInit();
}
/**
* All all requested vars to
* common storage place
*
* @return void
* @access protected
*/
protected function AddAllVars()
{
for ($i = 0; $i < strlen($this->Order); $i++) {
switch ($this->Order[$i]) {
case 'G':
$this->Get = $this->AddVars($_GET);
if ( array_key_exists('sid', $_GET) ) {
$this->_sidInQueryString = true;
}
$vars = $this->Application->processQueryString($this->Get(ENV_VAR_NAME));
if ( array_key_exists('sid', $vars) ) {
// used by Session::GetPassedSIDValue
$this->Get['sid'] = $vars['sid'];
}
$this->AddParams($vars);
break;
case 'P':
$this->Post = $this->AddVars($_POST);
$this->convertPostEvents();
$this->_processPostEnvVariables();
break;
case 'C':
$this->Cookie = $this->AddVars($_COOKIE);
break;
/*case 'E';
$this->Env = $this->AddVars($_ENV, false); //do not strip slashes!
break;
case 'S';
$this->Server = $this->AddVars($_SERVER, false); //do not strip slashes!
break;*/
case 'F';
$this->convertFiles();
$this->Files = $this->MergeVars($_FILES); // , false); //do not strip slashes!
break;
}
}
}
/**
* Allow POST variables, that names were transformed by PHP ("." replaced with "_") to
* override variables, that were virtually created through environment variable parsing
*
*/
function _processPostEnvVariables()
{
$passed = $this->Get('passed');
if ( !$passed ) {
return;
}
$passed = explode(',', $passed);
foreach ($passed as $prefix_special) {
if ( strpos($prefix_special, '.') === false ) {
continue;
}
list ($prefix, $special) = explode('.', $prefix_special);
$query_map = $this->getQueryString($prefix);
$post_prefix_special = $prefix . '_' . $special;
foreach ($query_map as $var_name) {
if ( array_key_exists($post_prefix_special . '_' . $var_name, $this->Post) ) {
$this->Set($prefix_special . '_' . $var_name, $this->Post[$post_prefix_special . '_' . $var_name]);
}
}
}
}
/**
* Removes requested specials from all request variables
*
* @return void
* @access protected
*/
protected function removeSpecials()
{
$this->specialsToRemove = $this->Get('remove_specials');
if ( $this->specialsToRemove ) {
foreach ($this->specialsToRemove as $prefix_special => $flag) {
if ( $flag && strpos($prefix_special, '.') === false ) {
unset($this->specialsToRemove[$prefix_special]);
trigger_error('Incorrect usage of "<strong>remove_specials[' . $prefix_special . ']</strong>" field (no special found)', E_USER_NOTICE);
}
}
$this->_Params = $this->_removeSpecials($this->_Params);
}
}
/**
* Finishes initialization of kHTTPQuery class
*
* @return void
* @access protected
* @todo: only uses build-in rewrite listeners, when cache is build for the first time
*/
protected function AfterInit()
{
$rewrite_url = $this->Get('_mod_rw_url_');
if ( $this->Application->RewriteURLs() || $rewrite_url ) {
// maybe call onafterconfigread here
$this->Application->UrlManager->initRewrite();
if ( defined('DEBUG_MODE') && $this->Application->isDebugMode() ) {
$this->Application->Debugger->profileStart('url_parsing', 'Parsing <b>MOD_REWRITE</b> url');
$this->Application->UrlManager->rewrite->parseRewriteURL();
$description = 'Parsing <b>MOD_REWRITE</b> url (template: <b>' . $this->Get('t') . '</b>)';
$this->Application->Debugger->profileFinish('url_parsing', $description);
}
else {
$this->Application->UrlManager->rewrite->parseRewriteURL();
}
if ( !$rewrite_url && $this->rewriteRedirectRequired() ) {
// rewrite url is missing (e.g. not a script from tools folder)
$url_params = $this->getRedirectParams();
// no idea about how to check, that given template require category to be passed with it, so pass anyway
$url_params['pass_category'] = 1;
$url_params['response_code'] = 301; // Moved Permanently
trigger_error('Non mod-rewrite url "<strong>' . $_SERVER['REQUEST_URI'] . '</strong>" used', E_USER_NOTICE);
$this->Application->Redirect('', $url_params);
}
}
else {
$this->Application->VerifyThemeId();
$this->Application->VerifyLanguageId();
}
}
/**
* Checks, that non-rewrite url was visited and it's automatic rewrite is required
*
* @return bool
*/
function rewriteRedirectRequired()
{
$redirect_conditions = Array (
!$this->IsHTTPSRedirect(), // not https <-> http redirect
!$this->refererIsOurSite(), // referer doesn't match ssl path or non-ssl domain (same for site domains)
!defined('GW_NOTIFY'), // not in payment gateway notification script
preg_match('/[\/]{0,1}index.php[\/]{0,1}/', $_SERVER['PHP_SELF']), // "index.php" was visited
$this->Get('t') != 'index', // not on index page
);
$perform_redirect = true;
foreach ($redirect_conditions as $redirect_condition) {
$perform_redirect = $perform_redirect && $redirect_condition;
if (!$perform_redirect) {
return false;
}
}
return true;
}
/**
* This is redirect from https to http or via versa
*
* @return bool
*/
function IsHTTPSRedirect()
{
$http_referer = array_key_exists('HTTP_REFERER', $_SERVER) ? $_SERVER['HTTP_REFERER'] : false;
return (
( PROTOCOL == 'https://' && preg_match('#http:\/\/#', $http_referer) )
||
( PROTOCOL == 'http://' && preg_match('#https:\/\/#', $http_referer) )
);
}
/**
* Checks, that referer is out site
*
* @return bool
*/
function refererIsOurSite()
{
if ( !array_key_exists('HTTP_REFERER', $_SERVER) ) {
// no referer -> don't care what happens
return false;
}
$site_helper = $this->Application->recallObject('SiteHelper');
/* @var $site_helper SiteHelper */
$found = false;
$http_referer = $_SERVER['HTTP_REFERER'];
preg_match('/^(.*?):\/\/(.*?)(\/|$)/', $http_referer, $regs); // 1 - protocol, 2 - domain
if ($regs[1] == 'https') {
$found = $site_helper->getDomainByName('SSLUrl', $http_referer) > 0;
if (!$found) {
// check if referer starts with our ssl url
$ssl_url = $this->Application->ConfigValue('SSL_URL');
$found = $ssl_url && preg_match('/^' . preg_quote($ssl_url, '/') . '/', $http_referer);
}
}
else {
$found = $site_helper->getDomainByName('DomainName', $regs[2]) > 0;
if (!$found) {
$found = $regs[2] == DOMAIN;
}
}
return $found;
}
function convertFiles()
{
if ( !$_FILES ) {
return ;
}
$tmp = Array ();
$file_keys = Array ('error', 'name', 'size', 'tmp_name', 'type');
foreach ($_FILES as $file_name => $file_info) {
if ( is_array($file_info['error']) ) {
$tmp[$file_name] = $this->getArrayLevel($file_info['error'], $file_name);
}
else {
$normal_files[$file_name] = $file_info;
}
}
if ( !$tmp ) {
return ;
}
$files = $_FILES;
$_FILES = Array ();
foreach ($tmp as $prefix => $prefix_files) {
$anchor =& $_FILES;
foreach ($prefix_files['keys'] as $key) {
$anchor =& $anchor[$key];
}
foreach ($prefix_files['value'] as $field_name) {
unset($inner_anchor, $copy);
$work_copy = $prefix_files['keys'];
foreach ($file_keys as $file_key) {
$inner_anchor =& $files[$prefix][$file_key];
if ( isset($copy) ) {
$work_copy = $copy;
}
else {
$copy = $work_copy;
}
array_shift($work_copy);
foreach ($work_copy as $prefix_file_key) {
$inner_anchor =& $inner_anchor[$prefix_file_key];
}
$anchor[$field_name][$file_key] = $inner_anchor[$field_name];
}
}
}
// keys: img_temp, 0, values: LocalPath, ThumbPath
}
function getArrayLevel(&$level, $prefix='')
{
$ret['keys'] = $prefix ? Array($prefix) : Array();
$ret['value'] = Array();
foreach($level as $level_key => $level_value)
{
if( is_array($level_value) )
{
$ret['keys'][] = $level_key;
$tmp = $this->getArrayLevel($level_value);
$ret['keys'] = array_merge($ret['keys'], $tmp['keys']);
$ret['value'] = array_merge($ret['value'], $tmp['value']);
}
else
{
$ret['value'][] = $level_key;
}
}
return $ret;
}
/**
* Overwrites GET events with POST events in case if they are set and not empty
*
* @return void
* @access protected
*/
protected function convertPostEvents()
{
$events = $this->Get('events', Array ());
/* @var $events Array */
if ( is_array($events) ) {
$events = array_filter($events);
foreach ($events as $prefix_special => $event_name) {
$this->Set($prefix_special . '_event', $event_name);
}
}
}
function finalizeParsing($passed = Array())
{
if (!$passed) {
return;
}
foreach ($passed as $passed_prefix) {
$this->discoverUnit($passed_prefix); // from mod-rewrite url parsing
}
$this->Set('passed', implode(',', $this->getDiscoveredUnits()));
}
/**
* Saves variables from array specified
* into common variable storage place
*
* @param Array $array
* @param bool $strip_slashes
* @return Array
* @access private
*/
function AddVars($array, $strip_slashes = true)
{
if ( $strip_slashes ) {
$array = $this->StripSlashes($array);
}
foreach ($array as $key => $value) {
$this->Set($key, $value);
}
return $array;
}
function MergeVars($array, $strip_slashes = true)
{
if ( $strip_slashes ) {
$array = $this->StripSlashes($array);
}
foreach ($array as $key => $value_array) {
// $value_array is an array too
$this->_Params = kUtil::array_merge_recursive($this->_Params, Array ($key => $value_array));
}
return $array;
}
function StripSlashes($array)
{
static $magic_quotes = null;
if (!isset($magic_quotes)) {
$magic_quotes = get_magic_quotes_gpc();
}
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = $this->StripSlashes($value);
}
else {
if ($magic_quotes) {
$value = stripslashes($value);
}
if (!$this->Application->isAdmin) {
$value = htmlspecialchars($value, null, CHARSET);
}
$array[$key] = $value;
}
}
return $array;
}
/**
* Returns all $_GET array excluding system parameters, that are not allowed to be passed through generated urls
*
* @param bool $access_error Method is called during no_permission, require login, session expiration link preparation
* @return Array
*/
function getRedirectParams($access_error = false)
{
$vars = $this->Get;
$unset_vars = Array (ENV_VAR_NAME, 'rewrite', '_mod_rw_url_', 'Action');
if (!$this->_sidInQueryString) {
$unset_vars[] = 'sid';
}
// remove system variables
foreach ($unset_vars as $var_name) {
if (array_key_exists($var_name, $vars)) {
unset($vars[$var_name]);
}
}
if ($access_error) {
// place 1 of 2 (also in UsersEventHandler::OnSessionExpire)
$vars = $this->_removePassThroughVariables($vars);
}
// transform arrays
return $this->_transformArrays($vars);
}
/**
* Removes all pass_though variables from redirect params
*
* @param Array $url_params
* @return Array
*/
function _removePassThroughVariables($url_params)
{
$pass_through = array_key_exists('pass_through', $url_params) ? $url_params['pass_through'] : '';
if (!$pass_through) {
return $url_params;
}
$pass_through = explode(',', $pass_through . ',pass_through');
foreach ($pass_through as $pass_through_var) {
unset($url_params[$pass_through_var]);
}
$url_params['no_pass_through'] = 1; // this way kApplication::HREF won't add them again
return $url_params;
}
function _transformArrays($array, $level_prefix = '')
{
$ret = Array ();
foreach ($array as $var_name => $var_value) {
$new_var_name = $level_prefix ? $level_prefix . '[' . $var_name . ']' : $var_name;
if (is_array($var_value)) {
$ret = array_merge($ret, $this->_transformArrays($var_value, $new_var_name));
}
else {
$ret[$new_var_name] = $var_value;
}
}
return $ret;
}
function writeRequestLog($filename)
{
$log_file = (defined('RESTRICTED') ? RESTRICTED : FULL_PATH) . '/' . $filename;
if ( is_writable(dirname($log_file)) ) {
$fp = fopen($log_file, 'a');
if ( $fp ) {
$session = $this->Application->recallObject('Session');
/* @var $session Session */
$user_id = $session->GetField('PortalUserId');
$admin_mark = $this->Application->isAdmin ? 'ADMIN' : 'FRONT';
$data = '[' . date('D M d H:i:s Y') . '] ' . $admin_mark . '; ip: ' . $this->getClientIp() . '; user_id: ' . $user_id . '; sid: ' . $this->Application->GetSID() . '; request: ' . "\n";
if ( $this->Get ) {
$data .= "_GET:\n" . print_r($this->Get, true);
}
if ( $this->Post ) {
$data .= "_POST:\n" . print_r($this->Post, true);
}
if ( $this->Cookie ) {
$data .= "_COOKIE:\n" . print_r($this->Cookie, true);
}
$data .= str_repeat('=', 100) . "\n";
fwrite($fp, $data);
fclose($fp);
}
else {
trigger_error('Request Log directory not writable', E_USER_WARNING);
}
}
else {
trigger_error('Request Log directory not writable', E_USER_WARNING);
}
}
/**
* Checks, that url is empty
*
* @return bool
* @access public
*/
public function isEmptyUrl()
{
if ( $this->Application->RewriteURLs() ) {
return !$this->Get('_mod_rw_url_');
}
return !count($this->Get);
}
/**
* Returns the client IP address.
*
* @return string The client IP address
* @access public
*/
public function getClientIp()
{
if ( $this->_trustProxy ) {
if ( array_key_exists('HTTP_CLIENT_IP', $_SERVER) ) {
return $_SERVER['HTTP_CLIENT_IP'];
}
if ( array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) ) {
$client_ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($client_ip as $ip_address) {
$clean_ip_address = trim($ip_address);
if ( false !== filter_var($clean_ip_address, FILTER_VALIDATE_IP) ) {
return $clean_ip_address;
}
}
return '';
}
}
- return $_SERVER['REMOTE_ADDR'];
+ return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
}
}
\ No newline at end of file
Index: branches/5.2.x/core/kernel/utility/unit_config_reader.php
===================================================================
--- branches/5.2.x/core/kernel/utility/unit_config_reader.php (revision 15706)
+++ branches/5.2.x/core/kernel/utility/unit_config_reader.php (revision 15707)
@@ -1,1019 +1,1019 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kUnitConfigReader extends kBase implements kiCacheable {
/**
* Configs reader
*
* @var Array
* @access private
*/
var $configData = Array();
var $configFiles = Array();
var $CacheExpired = false;
var $prefixFiles = array();
var $ProcessAllConfigs = false;
var $FinalStage = false;
var $StoreCache = false;
var $AfterConfigProcessed = array();
/**
* Escaped directory separator for using in regular expressions
*
* @var string
*/
var $_directorySeparator = '';
/**
* Regular expression for detecting module folder
*
* @var string
*/
var $_moduleFolderRegExp = '';
/**
* Folders to skip during unit config search
*
* @var Array
*/
var $_skipFolders = Array ('CVS', '.svn', 'admin_templates', 'libchart');
/**
* Creates instance of unit config reader
*
*/
public function __construct()
{
parent::__construct();
$this->_directorySeparator = preg_quote(DIRECTORY_SEPARATOR);
$editor_path = explode('/', trim(EDITOR_PATH, '/'));
$this->_skipFolders[] = array_pop($editor_path); // last of cmseditor folders
$this->_moduleFolderRegExp = '#' . $this->_directorySeparator . '(core|modules' . $this->_directorySeparator . '.*?)' . $this->_directorySeparator . '#';
}
/**
* Sets data from cache to object
*
* @param Array $data
* @access public
*/
public function setFromCache(&$data)
{
$this->prefixFiles = $data['ConfigReader.prefixFiles'];
}
/**
* Gets object data for caching
*
* @access public
* @return Array
*/
public function getToCache()
{
return Array (
'ConfigReader.prefixFiles' => $this->prefixFiles,
);
}
function scanModules($folderPath, $cache = true)
{
if (defined('IS_INSTALL') && IS_INSTALL && !defined('FORCE_CONFIG_CACHE')) {
// disable config caching during installation
$cache = false;
}
if ($cache) {
$restored = $this->Application->cacheManager->LoadUnitCache();
if ($restored) {
if ( defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode() ) {
$this->Application->Debugger->appendHTML('UnitConfigReader: Restoring Cache');
}
return;
}
}
if ( defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode() ) {
$this->Application->Debugger->appendHTML('UnitConfigReader: Generating Cache');
}
$this->ProcessAllConfigs = true;
$this->includeConfigFiles($folderPath, $cache);
$this->ParseConfigs();
// tell AfterConfigRead to store cache if needed
// can't store it here because AfterConfigRead needs ability to change config data
$this->StoreCache = $cache;
if ( !$this->Application->InitDone ) {
// scanModules is called multiple times during installation process
$this->Application->InitManagers();
// get build-in rewrite listeners ONLY to be able to parse mod-rewrite url when unit config cache is missing
$this->retrieveCollections();
$this->_sortRewriteListeners();
}
$this->Application->cacheManager->applyDelayedUnitProcessing();
}
function findConfigFiles($folderPath, $level = 0)
{
// if FULL_PATH = "/" ensure, that all "/" in $folderPath are not deleted
$reg_exp = '/^' . preg_quote(FULL_PATH, '/') . '/';
$folderPath = preg_replace($reg_exp, '', $folderPath, 1); // this make sense, since $folderPath may NOT contain FULL_PATH
$base_folder = FULL_PATH . $folderPath . DIRECTORY_SEPARATOR;
$sub_folders = glob($base_folder . '*', GLOB_ONLYDIR);
if (!$sub_folders) {
return ;
}
if ($level == 0) {
// don't scan Front-End themes because of extensive directory structure
$sub_folders = array_diff($sub_folders, Array ($base_folder . 'themes', $base_folder . 'tools'));
}
foreach ($sub_folders as $full_path) {
$sub_folder = substr($full_path, strlen($base_folder));
if (in_array($sub_folder, $this->_skipFolders)) {
continue;
}
if (preg_match('/^\./', $sub_folder)) {
// don't scan ".folders"
continue;
}
$config_name = $this->getConfigName($folderPath . DIRECTORY_SEPARATOR . $sub_folder);
if (file_exists(FULL_PATH . $config_name)) {
$this->configFiles[] = $config_name;
}
$this->findConfigFiles($full_path, $level + 1);
}
}
function includeConfigFiles($folderPath, $cache = true)
{
$this->Application->refreshModuleInfo();
if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) {
$data = $this->Application->getCache('master:config_files', false, $cache ? CacheSettings::$unitCacheRebuildTime : 0);
}
else {
$data = $this->Application->getDBCache('config_files', $cache ? CacheSettings::$unitCacheRebuildTime : 0);
}
if ( $data ) {
$this->configFiles = unserialize($data);
- if ( !defined('DBG_VALIDATE_CONFIGS') && !DBG_VALIDATE_CONFIGS ) {
+ if ( !(defined('DBG_VALIDATE_CONFIGS') && DBG_VALIDATE_CONFIGS) ) {
shuffle($this->configFiles);
}
}
else {
$this->findConfigFiles(FULL_PATH . DIRECTORY_SEPARATOR . 'core'); // search from core directory
$this->findConfigFiles($folderPath); // search from modules directory
if ( $cache ) {
if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) {
$this->Application->setCache('master:config_files', serialize($this->configFiles));
}
else {
$this->Application->setDBCache('config_files', serialize($this->configFiles));
}
}
}
foreach ($this->configFiles as $filename) {
$prefix = $this->PreloadConfigFile($filename);
if (!$prefix) {
throw new Exception('Prefix not defined in config file <strong>' . $filename . '</strong>');
}
}
if ($cache) {
unset($this->configFiles);
}
}
/**
* Process all read config files - called ONLY when there is no cache!
*
*/
function ParseConfigs()
{
// 1. process normal configs
$prioritized_configs = array();
foreach ($this->configData as $prefix => $config) {
if (isset($config['ConfigPriority'])) {
$prioritized_configs[$prefix] = $config['ConfigPriority'];
continue;
}
$this->parseConfig($prefix);
}
foreach ($this->configData as $prefix => $config) {
$this->postProcessConfig($prefix, 'AggregateConfigs', 'sub_prefix');
$clones = $this->postProcessConfig($prefix, 'Clones', 'prefix');
}
// 2. process prioritized configs
asort($prioritized_configs);
foreach ($prioritized_configs as $prefix => $priority) {
$this->parseConfig($prefix);
}
}
function AfterConfigRead($store_cache = null)
{
// if (!$this->ProcessAllConfigs) return ;
$this->FinalStage = true;
foreach ($this->configData as $prefix => $config) {
$this->runAfterConfigRead($prefix);
}
if ( !isset($store_cache) ) {
// $store_cache not overridden -> use global setting
$store_cache = $this->StoreCache;
}
if ($store_cache || (defined('IS_INSTALL') && IS_INSTALL)) {
// cache is not stored during install, but dynamic clones should be processed in any case
$this->processDynamicClones();
$this->retrieveCollections();
}
if ($store_cache) {
$this->_sortRewriteListeners();
$this->Application->HandleEvent(new kEvent('adm:OnAfterCacheRebuild'));
$this->Application->cacheManager->UpdateUnitCache();
if (defined('DEBUG_MODE') && DEBUG_MODE && defined('DBG_VALIDATE_CONFIGS') && DBG_VALIDATE_CONFIGS) {
// validate configs here to have changes from OnAfterConfigRead hooks to prefixes
foreach ($this->configData as $prefix => $config) {
if (!isset($config['TableName'])) continue;
$this->ValidateConfig($prefix);
}
}
}
}
/**
* Sort rewrite listeners according to RewritePriority (non-prioritized listeners goes first)
*
*/
function _sortRewriteListeners()
{
$listeners = Array ();
$prioritized_listeners = Array ();
// process non-prioritized listeners
foreach ($this->Application->RewriteListeners as $prefix => $listener_data) {
if ($listener_data['priority'] === false) {
$listeners[$prefix] = $listener_data;
}
else {
$prioritized_listeners[$prefix] = $listener_data['priority'];
}
}
// process prioritized listeners
asort($prioritized_listeners, SORT_NUMERIC);
foreach ($prioritized_listeners as $prefix => $priority) {
$listeners[$prefix] = $this->Application->RewriteListeners[$prefix];
}
$this->Application->RewriteListeners = $listeners;
}
/**
* Re-reads all configs
*
*/
function ReReadConfigs()
{
// don't reset prefix file, since file scanning could slow down the process
$prefix_files_backup = $this->prefixFiles;
$this->Application->cacheManager->EmptyUnitCache();
$this->prefixFiles = $prefix_files_backup;
// parse all configs
$this->ProcessAllConfigs = true;
$this->AfterConfigProcessed = Array ();
$this->includeConfigFiles(MODULES_PATH, false);
$this->ParseConfigs();
$this->AfterConfigRead(false);
$this->processDynamicClones();
// don't call kUnitConfigReader::retrieveCollections since it
// will overwrite what we already have in kApplication class instance
}
/**
* Process clones, that were defined via OnAfterConfigRead event
*
*/
function processDynamicClones()
{
$new_clones = Array();
foreach ($this->configData as $prefix => $config) {
$clones = $this->postProcessConfig($prefix, 'Clones', 'prefix');
if ($clones) {
$new_clones = array_merge($new_clones, $clones);
}
}
// execute delayed methods for cloned unit configs
$this->Application->cacheManager->applyDelayedUnitProcessing();
// call OnAfterConfigRead for cloned configs
$new_clones = array_unique($new_clones);
foreach ($new_clones as $prefix) {
$this->runAfterConfigRead($prefix);
}
}
/**
* Process all collectible unit config options here to also catch ones, defined from OnAfterConfigRead events
*
*/
function retrieveCollections()
{
foreach ($this->configData as $prefix => $config) {
// collect replacement templates
if (array_key_exists('ReplacementTemplates', $config) && $config['ReplacementTemplates']) {
$this->Application->ReplacementTemplates = array_merge($this->Application->ReplacementTemplates, $config['ReplacementTemplates']);
}
// collect rewrite listeners
if (array_key_exists('RewriteListener', $config) && $config['RewriteListener']) {
$rewrite_listeners = $config['RewriteListener'];
if (!is_array($rewrite_listeners)) {
// when one method is used to build and parse url
$rewrite_listeners = Array ($rewrite_listeners, $rewrite_listeners);
}
foreach ($rewrite_listeners as $index => $rewrite_listener) {
if (strpos($rewrite_listener, ':') === false) {
$rewrite_listeners[$index] = $prefix . '_EventHandler:' . $rewrite_listener;
}
}
$rewrite_priority = array_key_exists('RewritePriority', $config) ? $config['RewritePriority'] : false;
$this->Application->RewriteListeners[$prefix] = Array ('listener' => $rewrite_listeners, 'priority' => $rewrite_priority);
}
}
}
/**
* Register nessasary classes
* This method should only process the data which is cached!
*
* @param string $prefix
* @access private
*/
function parseConfig($prefix)
{
$this->parseClasses($prefix);
$this->parseScheduledTasks($prefix);
$this->parseHooks($prefix);
$this->parseAggregatedTags($prefix);
}
protected function parseClasses($prefix)
{
$config =& $this->configData[$prefix];
$register_classes = $this->getClasses($prefix);
foreach ($register_classes as $class_info) {
$this->Application->registerClass(
$class_info['class'],
$config['BasePath'] . DIRECTORY_SEPARATOR . $class_info['file'],
$class_info['pseudo']
);
if ( isset($class_info['build_event']) && $class_info['build_event'] ) {
$this->Application->delayUnitProcessing('registerBuildEvent', Array ($class_info['pseudo'], $class_info['build_event']));
}
}
}
protected function parseScheduledTasks($prefix)
{
$config =& $this->configData[$prefix];
if ( !isset($config['ScheduledTasks']) || !$config['ScheduledTasks'] ) {
return ;
}
$scheduled_tasks = $config['ScheduledTasks'];
foreach ($scheduled_tasks as $short_name => $scheduled_task_info) {
$event_status = array_key_exists('Status', $scheduled_task_info) ? $scheduled_task_info['Status'] : STATUS_ACTIVE;
$this->Application->delayUnitProcessing('registerScheduledTask', Array ( $short_name, $config['Prefix'] . ':' . $scheduled_task_info['EventName'], $scheduled_task_info['RunSchedule'], $event_status ));
}
}
protected function parseHooks($prefix)
{
$config =& $this->configData[$prefix];
if ( !isset($config['Hooks']) || !$config['Hooks'] ) {
return ;
}
$hooks = $config['Hooks'];
foreach ($hooks as $hook) {
if ( isset($config['ParentPrefix']) && ($hook['HookToPrefix'] == $config['ParentPrefix']) ) {
trigger_error('Depricated Hook Usage [prefix: <strong>' . $config['Prefix'] . '</strong>; do_prefix: <strong>' . $hook['DoPrefix'] . '</strong>] use <strong>#PARENT#</strong> as <strong>HookToPrefix</strong> value, where HookToPrefix is same as ParentPrefix', defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_NOTICE);
}
if ($hook['HookToPrefix'] == '') {
// new: set hooktoprefix to current prefix if not set
$hook['HookToPrefix'] = $config['Prefix'];
}
if ( isset($config['ParentPrefix']) ) {
// new: allow to set hook to parent prefix what ever it is
if ($hook['HookToPrefix'] == '#PARENT#') {
$hook['HookToPrefix'] = $config['ParentPrefix'];
}
if ($hook['DoPrefix'] == '#PARENT#') {
$hook['DoPrefix'] = $config['ParentPrefix'];
}
}
elseif ($hook['HookToPrefix'] == '#PARENT#' || $hook['DoPrefix'] == '#PARENT#') {
// we need parent prefix but it's not set !
continue;
}
$hook_events = (array)$hook['HookToEvent'];
$do_prefix = $hook['DoPrefix'] == '' ? $config['Prefix'] : $hook['DoPrefix'];
foreach ($hook_events as $hook_event) {
$hook_event = $hook['HookToPrefix'] . '.' . $hook['HookToSpecial'] . ':' . $hook_event;
$do_event = $do_prefix . '.' . $hook['DoSpecial'] . ':' . $hook['DoEvent'];
$this->Application->delayUnitProcessing('registerHook', Array ($hook_event, $do_event, $hook['Mode'], $hook['Conditional']));
}
}
}
protected function parseAggregatedTags($prefix)
{
$config =& $this->configData[$prefix];
$aggregated_tags = isset($config['AggregateTags']) ? $config['AggregateTags'] : Array ();
foreach ($aggregated_tags as $aggregate_tag) {
if ( isset($config['ParentPrefix']) ) {
if ($aggregate_tag['AggregateTo'] == $config['ParentPrefix']) {
trigger_error('Depricated Aggregate Tag Usage [prefix: <b>'.$config['Prefix'].'</b>; AggregateTo: <b>'.$aggregate_tag['AggregateTo'].'</b>] use <b>#PARENT#</b> as <b>AggregateTo</b> value, where AggregateTo is same as ParentPrefix', defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_NOTICE);
}
if ($aggregate_tag['AggregateTo'] == '#PARENT#') {
$aggregate_tag['AggregateTo'] = $config['ParentPrefix'];
}
}
$aggregate_tag['LocalPrefix'] = $config['Prefix'];
$this->Application->delayUnitProcessing('registerAggregateTag', Array ($aggregate_tag));
}
}
function ValidateConfig($prefix)
{
global $debugger;
$config =& $this->configData[$prefix];
$tablename = $config['TableName'];
$float_types = Array ('float', 'double', 'numeric');
$table_found = $this->Conn->Query('SHOW TABLES LIKE "'.$tablename.'"');
if (!$table_found) {
// config present, but table missing, strange
kUtil::safeDefine('DBG_RAISE_ON_WARNINGS', 1);
$debugger->appendHTML("<b class='debug_error'>Config Warning: </b>Table <strong>$tablename</strong> missing, but prefix <b>".$config['Prefix']."</b> requires it!");
$debugger->WarningCount++;
return ;
}
$res = $this->Conn->Query('DESCRIBE '.$tablename);
$config_link = $debugger->getFileLink(FULL_PATH.$this->prefixFiles[$config['Prefix']], 1, $config['Prefix']);
$error_messages = Array (
'field_not_found' => 'Field <strong>%s</strong> exists in the database, but <strong>is not defined</strong> in config',
'default_missing' => 'Default value for field <strong>%s</strong> not set in config',
'not_null_error1' => 'Field <strong>%s</strong> is NOT NULL in the database, but is not configured as not_null', // or required',
'not_null_error2' => 'Field <strong>%s</strong> is described as NOT NULL in config, but <strong>does not have DEFAULT value</strong>',
'not_null_error3' => 'Field <strong>%s</strong> is described as <strong>NOT NULL in config</strong>, but is <strong>NULL in db</strong>',
'invalid_default' => '<strong>Default value</strong> for field %s<strong>%s</strong> not sync. to db (in config = %s, in db = %s)',
'date_column_not_null_error' => 'Field <strong>%s</strong> must be NULL in config and database, since it contains date',
'user_column_default_error' => 'Field <strong>%s</strong> must be have NULL as default value, since it holds user id',
'type_missing' => '<strong>Type definition</strong> for field <strong>%s</strong> missing in config',
'virtual_type_missing' => '<strong>Type definition</strong> for virtual field <strong>%s</strong> missing in config',
'virtual_default_missing' => 'Default value for virtual field <strong>%s</strong> not set in config',
'virtual_not_null_error' => 'Virtual field <strong>%s</strong> cannot be not null, since it doesn\'t exist in database',
'invalid_calculated_field' => 'Calculated field <strong>%s</strong> is missing corresponding virtual field',
);
$config_errors = Array ();
$tablename = preg_replace('/^'.preg_quote(TABLE_PREFIX, '/').'(.*)/', '\\1', $tablename); // remove table prefix
// validate unit config field declaration in relation to database table structure
foreach ($res as $field) {
$f_name = $field['Field'];
if (getArrayValue($config, 'Fields')) {
if (preg_match('/l[\d]+_[\w]/', $f_name)) {
// skip multilingual fields
continue;
}
if (!array_key_exists ($f_name, $config['Fields'])) {
$config_errors[] = sprintf($error_messages['field_not_found'], $f_name);
}
else {
$db_default = $field['Default'];
if (is_numeric($db_default)) {
$db_default = preg_match('/[\.,]/', $db_default) ? (float)$db_default : (int)$db_default;
}
$default_missing = false;
$options = $config['Fields'][$f_name];
$not_null = isset($options['not_null']) && $options['not_null'];
$formatter = array_key_exists('formatter', $options) ? $options['formatter'] : false;
if (!array_key_exists('default', $options)) {
$config_errors[] = sprintf($error_messages['default_missing'], $f_name);
$default_missing = true;
}
if ($field['Null'] != 'YES') {
// field is NOT NULL in database (MySQL5 for null returns "NO", but MySQL4 returns "")
if ( $f_name != $config['IDField'] && !isset($options['not_null']) /*&& !isset($options['required'])*/ ) {
$config_errors[] = sprintf($error_messages['not_null_error1'], $f_name);
}
if ($not_null && !isset($options['default']) ) {
$config_errors[] = sprintf($error_messages['not_null_error2'], $f_name);
}
}
elseif ($not_null) {
$config_errors[] = sprintf($error_messages['not_null_error3'], $f_name);
}
if (($formatter == 'kDateFormatter') && $not_null) {
$config_errors[] = sprintf($error_messages['date_column_not_null_error'], $f_name);
}
// columns, holding userid should have NULL as default value
if (array_key_exists('type', $options) && !$default_missing) {
// both type and default value set
if (preg_match('/ById$/', $f_name) && $options['default'] !== null) {
$config_errors[] = sprintf($error_messages['user_column_default_error'], $f_name);
}
}
if (!array_key_exists('type', $options)) {
$config_errors[] = sprintf($error_messages['type_missing'], $f_name);
}
if (!$default_missing && ($field['Type'] != 'text')) {
if ( is_null($db_default) && $not_null ) {
$db_default = $options['type'] == 'string' ? '' : 0;
}
if ($f_name == $config['IDField'] && $options['type'] != 'string' && $options['default'] !== 0) {
$config_errors[] = sprintf($error_messages['invalid_default'], '<span class="debug_error">IDField</span> ', $f_name, $this->varDump($options['default']), $this->varDump($field['Default']));
}
else if (((string)$options['default'] != '#NOW#') && ($db_default !== $options['default']) && !in_array($options['type'], $float_types)) {
$config_errors[] = sprintf($error_messages['invalid_default'], '', $f_name, $this->varDump($options['default']), $this->varDump($db_default));
}
}
}
}
}
// validate virtual fields
if ( array_key_exists('VirtualFields', $config) ) {
foreach ($config['VirtualFields'] as $f_name => $options) {
if (!array_key_exists('type', $options)) {
$config_errors[] = sprintf($error_messages['virtual_type_missing'], $f_name);
}
if (array_key_exists('not_null', $options)) {
$config_errors[] = sprintf($error_messages['virtual_not_null_error'], $f_name);
}
if (!array_key_exists('default', $options)) {
$config_errors[] = sprintf($error_messages['virtual_default_missing'], $f_name);
}
}
}
// validate calculated fields
if ( array_key_exists('CalculatedFields', $config) ) {
foreach ($config['CalculatedFields'] as $special => $calculated_fields) {
foreach ($calculated_fields as $calculated_field => $calculated_field_expr) {
if ( !isset($config['VirtualFields'][$calculated_field]) ) {
$config_errors[] = sprintf($error_messages['invalid_calculated_field'], $calculated_field);
}
}
}
$config_errors = array_unique($config_errors);
}
if ($config_errors) {
$error_prefix = '<strong class="debug_error">Config Error'.(count($config_errors) > 1 ? 's' : '').': </strong> for prefix <strong>'.$config_link.'</strong> ('.$tablename.') in unit config:<br />';
$config_errors = $error_prefix.'&nbsp;&nbsp;&nbsp;'.implode('<br />&nbsp;&nbsp;&nbsp;', $config_errors);
kUtil::safeDefine('DBG_RAISE_ON_WARNINGS', 1);
$debugger->appendHTML($config_errors);
$debugger->WarningCount++;
}
}
function varDump($value)
{
return '<strong>'.var_export($value, true).'</strong> of '.gettype($value);
}
function postProcessConfig($prefix, $config_key, $dst_prefix_var)
{
$main_config =& $this->configData[$prefix];
$sub_configs = isset($main_config[$config_key]) && $main_config[$config_key] ? $main_config[$config_key] : Array ();
if ( !$sub_configs ) {
return Array ();
}
unset($main_config[$config_key]);
$processed = array();
foreach ($sub_configs as $sub_prefix => $sub_config) {
if ($config_key == 'AggregateConfigs' && !isset($this->configData[$sub_prefix])) {
$this->loadConfig($sub_prefix);
}
$sub_config['Prefix'] = $sub_prefix;
$this->configData[$sub_prefix] = kUtil::array_merge_recursive($this->configData[$$dst_prefix_var], $sub_config);
// when merging empty array to non-empty results non-empty array, but empty is required
foreach ($sub_config as $sub_key => $sub_value) {
if (!$sub_value) {
unset($this->configData[$sub_prefix][$sub_key]);
}
}
if ($config_key == 'Clones') {
$this->prefixFiles[$sub_prefix] = $this->prefixFiles[$prefix];
}
$this->postProcessConfig($sub_prefix, $config_key, $dst_prefix_var);
if ($config_key == 'AggregateConfigs') {
$processed = array_merge($this->postProcessConfig($sub_prefix, 'Clones', 'prefix'), $processed);
}
elseif ($this->ProcessAllConfigs) {
$this->parseConfig($sub_prefix);
}
array_push($processed, $sub_prefix);
}
if (!$prefix) {
// configs, that used only for cloning & not used ifself
unset($this->configData[$prefix]);
}
return array_unique($processed);
}
function PreloadConfigFile($filename)
{
$config_found = file_exists(FULL_PATH . $filename) && $this->configAllowed($filename);
if (defined('DEBUG_MODE') && DEBUG_MODE && defined('DBG_PROFILE_INCLUDES') && DBG_PROFILE_INCLUDES) {
if ( in_array($filename, get_included_files()) ) {
return '';
}
global $debugger;
if ($config_found) {
$file = FULL_PATH . $filename;
$file_crc = crc32($file);
$debugger->ProfileStart('inc_' . $file_crc, $file);
include_once($file);
$debugger->ProfileFinish('inc_' . $file_crc);
$debugger->profilerAddTotal('includes', 'inc_' . $file_crc);
}
}
elseif ($config_found) {
include_once(FULL_PATH . $filename);
}
if ($config_found) {
if (isset($config) && $config) {
// config file is included for 1st time -> save it's content for future processing
$prefix = array_key_exists('Prefix', $config) ? $config['Prefix'] : '';
preg_match($this->_moduleFolderRegExp, $filename, $rets);
$config['ModuleFolder'] = str_replace(DIRECTORY_SEPARATOR, '/', $rets[1]);
$config['BasePath'] = dirname(FULL_PATH . $filename);
if (array_key_exists('AdminTemplatePath', $config)) {
// append template base folder for admin templates path of this prefix
$module_templates = $rets[1] == 'core' ? '' : substr($rets[1], 8) . '/';
$config['AdminTemplatePath'] = $module_templates . $config['AdminTemplatePath'];
}
if (array_key_exists($prefix, $this->prefixFiles) && ($this->prefixFiles[$prefix] != $filename)) {
trigger_error(
'Single unit config prefix "<strong>' . $prefix . '</strong>" ' .
'is used in multiple unit config files: ' .
'"<strong>' . $this->prefixFiles[$prefix] . '</strong>", "<strong>' . $filename . '</strong>"',
E_USER_WARNING
);
}
$this->configData[$prefix] = $config;
$this->prefixFiles[$prefix] = $filename;
return $prefix;
}
else {
$prefix = array_search($filename, $this->prefixFiles);
if ( $prefix ) {
// attempt is made to include config file twice or more, but include_once prevents that,
// but file exists on hdd, then it is already saved to all required arrays, just return it's prefix
return $prefix;
}
}
}
return 'dummy';
}
function loadConfig($prefix)
{
if ( !isset($this->prefixFiles[$prefix]) ) {
throw new Exception('Configuration file for prefix "<strong>' . $prefix . '</strong>" is unknown');
return ;
}
$file = $this->prefixFiles[$prefix];
$prefix = $this->PreloadConfigFile($file);
if ($this->FinalStage) {
// run prefix OnAfterConfigRead so all
// hooks to it can define their clonses
$this->runAfterConfigRead($prefix);
}
$clones = $this->postProcessConfig($prefix, 'AggregateConfigs', 'sub_prefix');
$clones = array_merge($this->postProcessConfig($prefix, 'Clones', 'prefix'), $clones);
if ($this->FinalStage) {
$clones = array_unique($clones);
foreach ($clones as $a_prefix) {
$this->runAfterConfigRead($a_prefix);
}
}
}
function runAfterConfigRead($prefix)
{
if (in_array($prefix, $this->AfterConfigProcessed)) {
return ;
}
$this->Application->HandleEvent( new kEvent($prefix . ':OnAfterConfigRead') );
if (!(defined('IS_INSTALL') && IS_INSTALL)) {
// allow to call OnAfterConfigRead multiple times during install
array_push($this->AfterConfigProcessed, $prefix);
}
}
/**
* Reads unit (specified by $prefix)
* option specified by $option
*
* @param string $prefix
* @param string $name
* @param mixed $default
* @return string
* @access public
*/
function getUnitOption($prefix, $name, $default = false)
{
if (preg_match('/(.*)\.(.*)/', $prefix, $rets)) {
if (!isset($this->configData[$rets[1]])) {
$this->loadConfig($rets[1]);
}
$ret = isset($this->configData[$rets[1]][$name][$rets[2]]) ? $this->configData[$rets[1]][$name][$rets[2]] : false;
// $ret = getArrayValue($this->configData, $rets[1], $name, $rets[2]);
}
else {
if (!isset($this->configData[$prefix])) {
$this->loadConfig($prefix);
}
$ret = isset($this->configData[$prefix][$name]) ? $this->configData[$prefix][$name] : false;
// $ret = getArrayValue($this->configData, $prefix, $name);
}
return $ret === false ? $default : $ret;
}
/**
* Read all unit with $prefix options
*
* @param string $prefix
* @return Array
* @access public
*/
function getUnitOptions($prefix)
{
if (!isset($this->configData[$prefix])) {
$this->loadConfig($prefix);
}
return $this->configData[$prefix];
}
/**
* Set's new unit option value
*
* @param string $prefix
* @param string $name
* @param string $value
* @access public
*/
function setUnitOption($prefix, $name, $value)
{
if ( preg_match('/(.*)\.(.*)/', $prefix, $rets) ) {
if ( !isset($this->configData[$rets[1]]) ) {
$this->loadConfig($rets[1]);
}
$this->configData[$rets[1]][$name][$rets[2]] = $value;
}
else {
if ( !isset($this->configData[$prefix]) ) {
$this->loadConfig($prefix);
}
$this->configData[$prefix][$name] = $value;
}
}
protected function getClasses($prefix)
{
$config =& $this->configData[$prefix];
$class_params = Array ('ItemClass', 'ListClass', 'EventHandlerClass', 'TagProcessorClass');
$register_classes = isset($config['RegisterClasses']) ? $config['RegisterClasses'] : Array ();
foreach ($class_params as $param_name) {
if ( !isset($config[$param_name]) ) {
continue;
}
$config[$param_name]['pseudo'] = $this->getPseudoByOptionName($param_name, $prefix);
$register_classes[] = $config[$param_name];
}
return $register_classes;
}
protected function getPseudoByOptionName($option_name, $prefix)
{
$pseudo_class_map = Array (
'ItemClass' => '%s',
'ListClass' => '%s_List',
'EventHandlerClass' => '%s_EventHandler',
'TagProcessorClass' => '%s_TagProcessor'
);
return sprintf($pseudo_class_map[$option_name], $prefix);
}
/**
* Get's config file name based
* on folder name supplied
*
* @param string $folderPath
* @return string
* @access private
*/
function getConfigName($folderPath)
{
return $folderPath . DIRECTORY_SEPARATOR . basename($folderPath) . '_config.php';
}
/**
* Checks if config file is allowed for includion (if module of config is installed)
*
* @param string $config_path relative path from in-portal directory
*/
function configAllowed($config_path)
{
static $module_paths = null;
if (defined('IS_INSTALL') && IS_INSTALL) {
// at installation start no modules in db and kernel configs could not be read
return true;
}
if (preg_match('#^' . $this->_directorySeparator . 'core#', $config_path)) {
// always allow to include configs from "core" module's folder
return true;
}
if (!$this->Application->ModuleInfo) {
return false;
}
if (!isset($module_paths)) {
$module_paths = Array ();
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
$module_paths[] = str_replace('/', DIRECTORY_SEPARATOR, rtrim($module_info['Path'], '/'));
}
$module_paths = array_unique($module_paths);
}
preg_match($this->_moduleFolderRegExp, $config_path, $rets);
// config file path starts with module folder path
return in_array($rets[1], $module_paths);
}
/**
* Returns true if config exists and is allowed for reading
*
* @param string $prefix
* @return bool
*/
function prefixRegistred($prefix)
{
return isset($this->prefixFiles[$prefix]) ? true : false;
}
/**
* Returns config file for given prefix
*
* @param string $prefix
* @return string
*/
function getPrefixFile($prefix)
{
return array_key_exists($prefix, $this->prefixFiles) ? $this->prefixFiles[$prefix] : false;
}
function iterateConfigs($callback_function, $params)
{
$this->includeConfigFiles(MODULES_PATH); //make sure to re-read all configs
$this->AfterConfigRead();
foreach ($this->configData as $prefix => $config_data) {
$callback_function[0]->$callback_function[1]($prefix, $config_data, $params);
}
}
}
\ No newline at end of file

Event Timeline